diff --git a/.asf.yaml b/.asf.yaml new file mode 100644 index 000000000..cfb2ed0e8 --- /dev/null +++ b/.asf.yaml @@ -0,0 +1,40 @@ +# 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. +# + +github: + description: Global-Scale Sustainable Blockchain Fabric + #homepage: resilientdb.apache.org + labels: + - crypto + - smart-contracts + - blockchain + - solidity + - distributed-database + - key-value-database + - distributed-ledger + - blockchain-platform + - utxo + enabled_merge_buttons: + squash: true + merge: false + rebase: false + protected_branches: + master: + +notifications: + commits: commits@resilientdb.apache.org + issues: commits@resilientdb.apache.org + pullrequests: commits@resilientdb.apache.org diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 000000000..91e4a9f26 --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +6.3.2 diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 02701aaec..0a1c92394 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -30,6 +30,7 @@ jobs: with: file: ./Docker/Dockerfile context: . + platforms: linux/amd64 push: true tags: expolab/resdb:amd64 @@ -39,5 +40,6 @@ jobs: with: file: ./Docker/Dockerfile_mac context: . + platforms: linux/arm64 push: true - tags: expolab/resdb:arm64 \ No newline at end of file + tags: expolab/resdb:arm64 diff --git a/.gitignore b/.gitignore index 7e0ede86e..96d004d83 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ deps/*/ +scripts/deploy/config/key.conf +scripts/deploy/config_out/ deploy/kv_server/output/ .idea/ .vscode/ @@ -9,3 +11,6 @@ bazel-* venv sdk_validator/venv __pycache__ +build +enclave/sgxcode/test + diff --git a/CHANGELOG.md b/CHANGELOG.md index 01100cbdc..b470773df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +### NexRes v1.9.0 ([2023-11-29](https://github.com/resilientdb/resilientdb/releases/tag/nexres-v1.9.0)) + +Support Multi-version Key-Value Interface. ([Junchao Chen](https://github.com/cjcchen)) + +* Get and Set need to provide a version number to fetch the correct version of the data (if exists) or write to the correct version of data (if not overwritten already), respectively. +* Provide interfaces to obtain historical data with a specific version or a range of versions. + + ### NexRes v1.8.0 ([2023-08-21](https://github.com/resilientdb/resilientdb/releases/tag/nexres-v1.8.0)) **Implemented Enhancements:** The view-change recovery protocol was extensively expanded to support the following Byzantine failures through primary/leader replacement and replica recovery. ([Dakai Kang](https://github.com/DakaiKang)) diff --git a/Docker/Dockerfile b/Docker/Dockerfile index 5b45b3f26..31571586e 100644 --- a/Docker/Dockerfile +++ b/Docker/Dockerfile @@ -33,3 +33,5 @@ COPY . /app RUN bazel --version RUN bazel build @com_github_bazelbuild_buildtools//buildifier:buildifier RUN bazel build service/tools/kv/api_tools/kv_service_tools + +ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file diff --git a/Docker/Dockerfile_mac b/Docker/Dockerfile_mac index eb47e0ce9..211976d87 100644 --- a/Docker/Dockerfile_mac +++ b/Docker/Dockerfile_mac @@ -30,3 +30,5 @@ COPY . /app RUN bazel --version RUN bazel build @com_github_bazelbuild_buildtools//buildifier:buildifier RUN bazel build service/tools/kv/api_tools/kv_service_tools + +ENTRYPOINT ["./entrypoint.sh"] diff --git a/Fides_extended_version.pdf b/Fides_extended_version.pdf new file mode 100644 index 000000000..4d7126a2d Binary files /dev/null and b/Fides_extended_version.pdf differ diff --git a/INSTALL.sh b/INSTALL.sh index c64fb0e3d..882d3427a 100755 --- a/INSTALL.sh +++ b/INSTALL.sh @@ -7,7 +7,7 @@ curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg sudo mv bazel.gpg /etc/apt/trusted.gpg.d/ echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add - -sudo apt update && sudo apt install bazel=5.0.0 -y +sudo apt update && sudo apt install bazel=6.3.2 -y sudo apt install clang-format -y rm $PWD/.git/hooks/pre-push ln -s $PWD/hooks/pre-push $PWD/.git/hooks/pre-push @@ -27,7 +27,7 @@ cd bazel_build unzip bazel-6.0.0-dist.zip -export JAVA_HOME='/usr/lib/jvm/java-1.11.0-openjdk-arm64/' +export JAVA_HOME='/usr/lib/jvm/java-1.11.0-openjdk-amd64' env EXTRA_BAZEL_ARGS="--host_javabase=@local_jdk//:jdk" bash ./compile.sh sudo cp output/bazel /usr/local/bin/ cd .. @@ -40,3 +40,14 @@ bazel build @com_github_bazelbuild_buildtools//buildifier:buildifier sudo apt-get install python3.10-dev -y sudo apt-get install python3-dev -y + +# Build sgx code +cd enclave/ +rm ./sgx_cpp_* +cd sgxcode/ +rm -rf build || true +mkdir build && cd build/ +cmake .. && make +cd ../.. +cp sgxcode/build/host/sgx_cpp_* ./ +ldconfig /usr/local/lib64/ diff --git a/NOTICE b/NOTICE new file mode 100644 index 000000000..311b43605 --- /dev/null +++ b/NOTICE @@ -0,0 +1,5 @@ +Apache ResilientDB +Copyright 2023-2024 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (/). diff --git a/README.md b/README.md index 709ecfdbd..9e14458a8 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,13 @@ 4. ResilientDB exposes a wide range of interfaces such as a **Key-Value** store, **Smart Contracts**, **UTXO**, and **Python SDK**. Following are some of the decentralized applications (DApps) built on top of ResilientDB: **[NFT Marketplace](https://nft.resilientdb.com/)** and **[Debitable](https://debitable.resilientdb.com/)**. 5. To persist blockchain, chain state, and metadata, ResilientDB provides durability through **LevelDB** and **RocksDB**. 6. ResilientDB provides access to a seamless **GUI display** for deployment and maintenance, and supports **Grafana** for plotting monitoring data. -7. **[Historial Facts]** The ResilientDB project was founded by **[Mohammad Sadoghi](https://expolab.org/)** along with his students ([Suyash Gupta](https://gupta-suyash.github.io/index.html) as the lead Architect, [Sajjad Rahnama](https://sajjadrahnama.com/), [Jelle Hellings](https://www.jhellings.nl/)) at **[UC Davis](https://www.ucdavis.edu/)** in 2018 and was open-sourced in late 2019. On September 30, 2021, we released ResilientDB v-3.0. In 2022, ResilientDB was completely re-written and re-architected ([Junchao Chen](https://github.com/cjcchen) as the lead Architect along with the entire [NexRes Team](https://resilientdb.com/)), paving the way for a new sustainable foundation, referred to as NexRes (Next Generation ResilientDB). Thus, on September 30, 2022, NexRes-v1.0.0 was born, marking a new beginning for **[ResilientDB](https://resilientdb.com/)**. +7. **[Historial Facts]** The ResilientDB project was founded by **[Mohammad Sadoghi](https://expolab.org/)** along with his students ([Suyash Gupta](https://gupta-suyash.github.io/index.html) as the lead Architect, [Sajjad Rahnama](https://sajjadrahnama.com/) as the lead System Designer, and [Jelle Hellings](https://www.jhellings.nl/)) at **[UC Davis](https://www.ucdavis.edu/)** in 2018 and was open-sourced in late 2019. On September 30, 2021, we released ResilientDB v-3.0. In 2022, ResilientDB was completely re-written and re-architected ([Junchao Chen](https://github.com/cjcchen) as the lead Architect, [Dakai Kang](https://github.com/DakaiKang) as the lead Recovery Architect along with the entire [NexRes Team](https://resilientdb.com/)), paving the way for a new sustainable foundation, referred to as NexRes (Next Generation ResilientDB). Thus, on September 30, 2022, NexRes-v1.0.0 was born, marking a new beginning for **[ResilientDB](https://resilientdb.com/)**. On October 21, 2023, **[ResilientDB](https://cwiki.apache.org/confluence/display/INCUBATOR/ResilientDBProposal)** was officially accepted into **[Apache Incubation](https://incubator.apache.org/projects/resilientdb.html)**. + +
+ + + +
--- @@ -44,10 +50,12 @@ The latest ResilientDB documentation, including a programming guide, is availabl - System Parameters & Configuration - Continuous Integration & Testing -![Nexres](./img/nexres.png) +
+ +
## OS Requirements -Ubuntu 20.* +Ubuntu 20+ --- @@ -70,29 +78,219 @@ Build Interactive Tools: bazel build service/tools/kv/api_tools/kv_service_tools -Run tools to set a value by a key (for example, set the value with key "test" and value "test_value"): +## Functions ## +ResilientDB supports two types of functions: version-based and non-version-based. +Version-based functions will leverage versions to protect each update, versions must be obtained before updating a key. - bazel-bin/service/tools/kv/api_tools/kv_service_tools service/tools/config/interface/service.config set test test_value - -You will see the following result if successful: +***Note***: Version-based functions are not compatible with non-version-based functions. Do not use both in your applications. - client set ret = 0 +We show the functions below and show how to use [kv_service_tools](service/tools/kv/api_tools/kv_service_tools.cpp) to test the function. -Run tools to get value by a key (for example, get the value with key "test"): +### Version-Based Functions ### +#### Get #### +Obtain the value of `key` with a specific version `v`. - bazel-bin/service/tools/kv/api_tools/kv_service_tools service/tools/config/interface/service.config get test - -You will see the following result if successful: + kv_service_tools --config config_file --cmd get_with_version --key key --version v + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | get_with_version | +| key | the key you want to obtain | +| version | the version you want to obtain. (If the `v` is 0, it will return the latest version | + + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd get_with_version --key key1 --version 0 + +Results: +> get key = key1, value = value: "v2" +> version: 2 + +#### Set #### +Set `value` to the key `key` based on version `v`. + + kv_service_tools --config config_file --cmd set_with_version --key key --version v --value value + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | set_with_version | +| key | the key you want to set | +| version | the version you have obtained. (If the version has been changed during the update, the transaction will be ignored) | +| value | the new value | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd set_with_version --key key1 --version 0 --value v1 + +Results: +> set key = key1, value = v3, version = 2 done, ret = 0 +> +> current value = value: "v3" +> version: 3 + +#### Get Key History #### +Obtain the update history of key `key` within the versions [`v1`, `v2`]. + + kv_service_tools --config config_file --cmd get_history --key key --min_version v1 --max_version v2 + + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | get_history | +| key | the key you want to obtain | +| min_version | the minimum version you want to obtain | +| max_version | the maximum version you want to obtain | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd get_history --key key1 --min_version 1 --max_version 2 + +Results: + +> get history key = key1, min version = 1, max version = 2
+> value =
+> item {
+>   key: "key1"
+>   value_info {
+>    value: "v1"
+>    version: 2
+>  }
+> }
+> item {
+>   key: "key1"
+>   value_info {
+>    value: "v0"
+>    version: 1
+>  }
+> } + +#### Get Top #### +Obtain the recent `top_number` history of the key `key`. + + kv_service_tools --config config_path --cmd get_top --key key --top top_number + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | get_top | +| key | the key you want to obtain | +| top | the number of the recent updates | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd get_top --key key1 --top 1 + +Results: - client get value = test_value +>key = key1, top 1
+> value =
+> item {
+> key: "key1"
+>  value_info {
+>    value: "v2"
+>    version: 3
+>  }
+>} -Run tools to get all values that have been set: +#### Get Key Range #### +Obtain the values of the keys in the ranges [`key1`, `key2`]. Do not use this function in your practice code - bazel-bin/service/tools/kv/api_tools/kv_service_tools service/tools/config/interface/service.config getvalues + kv_service_tools --config config_file --cmd get_key_range_with_version --min_key key1 --max_key key2 -You will see the following result if successful: +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | get_key_range_with_version | +| min_key | the minimum key | +| max_key | the maximum key | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd get_key_range_with_version --min_key key1 --max_key key3 + +Results: + +>min key = key1 max key = key2
+> getrange value =
+> item {
+>   key: "key1"
+>   value_info {
+>    value: "v0"
+>    version: 1
+>   }
+> }
+> item {
+>   key: "key2"
+>   value_info {
+>    value: "v1"
+>    version: 1
+>   }
+>} + + +### Non-Version-Based Function ### +#### Set ##### +Set `value` to the key `key`. + + kv_service_tools --config config_file --cmd set --key key --value value + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | set | +| key | the key you want to set | +| value | the new value | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd set --key key1 --value value1 + +Results: +> set key = key1, value = v1, done, ret = 0 + +#### Get #### +Obtain the value of `key`. + + kv_service_tools --config config_file --cmd get --key key + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | get | +| key | the key you want to obtain | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd get --key key1 + +Results: +> get key = key1, value = "v2" + + +#### Get Key Range #### +Obtain the values of the keys in the ranges [`key1`, `key2`]. Do not use this function in your practice code + + kv_service_tools --config config_path --cmd get_key_range --min_key key1 --max_key key2 + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | get_key_range | +| min_key | the minimum key | +| max_key | the maximum key | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd get_key_range --min_key key1 --max_key key3 + +Results: +> getrange min key = key1, max key = key3
+> value = [v3,v2,v1] - client getvalues value = [test_value] ## Deployment Script @@ -121,28 +319,18 @@ We also provide access to a [deployment script](https://github.com/resilientdb/r - For amd architecture, run: ```shell - docker run -it expolab/resdb:amd64 bash + docker run -d --name myserver expolab/resdb:amd64 ``` - For Apple Silicon (M1/M2) architecture, run: ```shell - docker run -it expolab/resdb:arm64 bash + docker run -d --name myserver expolab/resdb:arm64 ``` -4. **Start the kv_service within the Container** - Once you're inside the container, start the `kv_service` by running the following command: +4. **Test with Set and Get Commands** + Exec into the running server: ```shell - ./service/tools/kv/server_tools/start_kv_service.sh + docker exec -it myserver bash ``` -5. **Test with Set and Get Commands** - Verify the functionality of the service by performing set and get operations: - - Set a test value: - ```shell - bazel-bin/service/tools/kv/api_tools/kv_service_tools service/tools/config/interface/service.config set test test_value - ``` - - - Retrieve the test value: - ``` - bazel-bin/service/tools/kv/api_tools/kv_service_tools service/tools/config/interface/service.config get test - ``` \ No newline at end of file + Verify the functionality of the service by performing set and get operations provided above [functions](README.md#functions). diff --git a/WORKSPACE b/WORKSPACE index 317fefbfa..d97d40690 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -3,6 +3,36 @@ workspace(name = "com_resdb_nexres") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("//:repositories.bzl", "nexres_repositories") +new_local_repository( + name = "openenclave_host", + path = "/opt/openenclave_0_17_0", + build_file_content = """ +cc_import( + name = "oehost_lib", + static_library = "lib/openenclave/host/liboehost.a", + visibility = ["//visibility:public"], +) + +exports_files(["lib/openenclave/host/liboehost.a"]) +""" +) + +new_local_repository( + name = "openenclave", + path = "/opt/openenclave_0_17_0/include", + build_file_content = """ +package(default_visibility = ["//visibility:public"]) +filegroup( + name = "headerfile", + srcs = glob(["**/*.h"]), +) +cc_library( + name = "headers", + hdrs = [":headerfile"] +) +""" +) + nexres_repositories() http_archive( @@ -198,8 +228,8 @@ http_archive( http_archive( name = "pybind11_bazel", - strip_prefix = "pybind11_bazel-master", - urls = ["https://github.com/pybind/pybind11_bazel/archive/master.zip"], + strip_prefix = "pybind11_bazel-2.11.1.bzl.1", + urls = ["https://github.com/pybind/pybind11_bazel/archive/refs/tags/v2.11.1.bzl.1.zip"] ) http_archive( diff --git a/benchmark/protocols/fides/BUILD b/benchmark/protocols/fides/BUILD new file mode 100644 index 000000000..575fc031f --- /dev/null +++ b/benchmark/protocols/fides/BUILD @@ -0,0 +1,18 @@ +package(default_visibility = ["//visibility:private"]) + +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") + +cc_binary( + name = "kv_server_performance", + srcs = ["kv_server_performance.cpp"], + copts = ["-Iexternal/openenclave"], + deps = [ + "//chain/storage:memory_db", + "//executor/kv:kv_executor", + "//platform/config:resdb_config_utils", + "//platform/consensus/ordering/fides/framework:consensus", + "//service/utils:server_factory", + "//enclave:headers", + ], +) + diff --git a/benchmark/protocols/fides/kv_server_performance.cpp b/benchmark/protocols/fides/kv_server_performance.cpp new file mode 100644 index 000000000..32b640dd6 --- /dev/null +++ b/benchmark/protocols/fides/kv_server_performance.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include + +#include "chain/storage/memory_db.h" +#include "enclave/sgx_cpp_u.h" +#include "executor/kv/kv_executor.h" +#include "platform/config/resdb_config_utils.h" +#include "platform/consensus/ordering/fides/framework/consensus.h" +#include "platform/networkstrate/service_network.h" +#include "platform/statistic/stats.h" +#include "proto/kv/kv.pb.h" +#include +#include +#include +#include + +using namespace resdb; +using namespace resdb::fides; +using namespace resdb::storage; + + +unsigned char* key_buf; +size_t key_len = 0; +oe_enclave_t* enclave = NULL; +oe_result_t result; +int ret = 0; +uint32_t flags = OE_ENCLAVE_FLAG_DEBUG; + +BIO *bio = BIO_new_mem_buf(key_buf, -1); +RSA *pub_key = NULL; +size_t encrypted_len; +unsigned char* encrypted_data; + +bool check_simulate_opt(int* argc, char* argv[]) { + for (int i = 0; i < *argc; i++) { + if (strcmp(argv[i], "--simulate") == 0) { + std::cout << "Running in simulation mode" << std::endl; + memmove(&argv[i], &argv[i + 1], (*argc - i) * sizeof(char*)); + (*argc)--; + return true; + } + } + return false; +} + +void ShowUsage() { + printf(" [logging_dir]\n"); +} + +std::string GetRandomKey() { + int num1 = rand() % 10; + int num2 = rand() % 10; + return std::to_string(num1) + std::to_string(num2); +} + +std::string GetEncryptedRandomKey() { + int num1 = rand() % 10; + int num2 = rand() % 10; + std::string key = std::to_string(num1) + std::to_string(num2); + std::cout<<"key: "<(key.c_str()); + + encrypted_data = new unsigned char[encrypted_len]; // Initialize buffer + std::cout<<"Before RSA_public_encrypt." << std::endl; + size_t result_len = RSA_public_encrypt(key.size(), key_data, encrypted_data, + pub_key, RSA_PKCS1_PADDING); + + std::string encrypted_key(encrypted_data, encrypted_data + result_len); + std::cout<<"encrypted_key: "<= 6) { + auto monitor_port = Stats::GetGlobalStats(5); + monitor_port->SetPrometheus(argv[5]); + } + + printf("Run 1\n"); + std::unique_ptr config = + GenerateResDBConfig(config_file, private_key_file, cert_file); + + config->RunningPerformance(true); + ResConfigData config_data = config->GetConfigData(); + + std::cout << "kv_server: reseting prng" << std::endl; + // Predefined key, can replace it by using some DKG protocol + uint32_t rdrandNum = 123456789; + uint32_t totalNum = config->GetReplicaNum(); + result = reset_prng(enclave, &ret, &rdrandNum, &totalNum); + if (result != OE_OK) { + ret = 1; + } + if (ret != 0) { + std::cerr << "kv_server_performance: reset_prng failed with " << ret << std::endl; + } else { + std::cout << "kv_server_performance: reset_prng succeeded." << std::endl; + } + + std::cout << "kv_server_performance: requesting counter" << std::endl; + uint32_t index; + result = request_counter(enclave, &ret, &index); + if (result != OE_OK) { + ret = 1; + } + if (ret != 0) { + std::cerr << "kv_server_performance: request_counter failed with " << ret << std::endl; + } else { + std::cout << "kv_server_performance: request_counter succeeded with index: " << index << std::endl; + } + + + auto performance_consens = std::make_unique( + *config, std::make_unique(std::make_unique()), enclave); + +/* // For transaction decryption + + std::cout << "kv_server_performance: generate key" << std::endl; + size_t key_size = 2048; + result = generate_key(enclave, &ret, &key_size); + std::cout << "After generate_key" << std::endl; + if (result != OE_OK || ret != 0) { + std::cerr << "kv_server_performance: generate_key failed with " << ret << std::endl; + // goto exit; + } + + result = get_pubkey(enclave, &ret, &key_buf, &key_len); + + bio = BIO_new_mem_buf(key_buf, -1); + pub_key = NULL; + PEM_read_bio_RSAPublicKey(bio, &pub_key, NULL, NULL); + + encrypted_len = RSA_size(pub_key); + encrypted_data = new unsigned char[encrypted_len]; // Initialize buffer + + +{ + // KVRequest request; + // request.set_cmd(KVRequest::SET); + // request.set_key(GetEncryptedRandomKey()); + // request.set_value("helloworld"); + + + // int requestSize = request.ByteSizeLong(); + // unsigned char* binary_data = new unsigned char[requestSize]; + + // if (request.SerializeToArray(binary_data, requestSize)) { + // std::cout << "Serialization successful!" << std::endl; + // } else { + // std::cerr << "Serialization failed!" << std::endl; + // } + + // std::cout << "kv_server_performance: encrypt data" << std::endl; + // unsigned char* encrypted_data = nullptr; + // size_t encrypted_len = 0; + // result = encrypt(enclave, &ret, binary_data, + // &encrypted_data, requestSize,&encrypted_len); + + // printf("kv_server_performance: Finish encrypt data\n"); + // printf("encrypted_data: %s\n", encrypted_data); + + // std::string request_data(encrypted_data, encrypted_data + encrypted_len); + + + KVRequest request; + request.set_cmd(KVRequest::SET); + request.set_key(GetRandomKey()); + request.set_value("helloworld"); + std::string request_data; + request.SerializeToString(&request_data); + + const unsigned char* request_data_char = reinterpret_cast(request_data.c_str()); + + encrypted_data = new unsigned char[encrypted_len]; // Initialize buffer + std::cout<<"Before RSA_public_encrypt."; + size_t result_len = RSA_public_encrypt(request_data.size(), request_data_char, encrypted_data, + pub_key, RSA_PKCS1_PADDING); + + std::string encrypted_data_str(encrypted_data, encrypted_data + result_len); + + performance_consens->SetupPerformanceDataFunc([encrypted_data_str]() { + return encrypted_data_str; + }); +} + + printf("Run 4\n"); +*/ + + performance_consens->SetupPerformanceDataFunc([]() { + KVRequest request; + request.set_cmd(KVRequest::SET); + request.set_key(GetRandomKey()); + request.set_value("helloworld"); + std::string request_data; + request.SerializeToString(&request_data); + return request_data; + }); + + auto server = + std::make_unique(*config, + std::move(performance_consens)); + server->Run(); + + BIO_free_all(bio); + // delete[] binary_data; +} diff --git a/benchmark/protocols/fides/kv_service_tools.cpp b/benchmark/protocols/fides/kv_service_tools.cpp new file mode 100644 index 000000000..17858ef21 --- /dev/null +++ b/benchmark/protocols/fides/kv_service_tools.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include +#include +#include + +#include + +#include "common/proto/signature_info.pb.h" +#include "interface/kv/kv_client.h" +#include "platform/config/resdb_config_utils.h" + +using resdb::GenerateReplicaInfo; +using resdb::GenerateResDBConfig; +using resdb::KVClient; +using resdb::ReplicaInfo; +using resdb::ResDBConfig; + +int main(int argc, char** argv) { + if (argc < 2) { + printf("\n"); + return 0; + } + std::string client_config_file = argv[1]; + ResDBConfig config = GenerateResDBConfig(client_config_file); + + config.SetClientTimeoutMs(100000); + + KVClient client(config); + + client.Set("start", "value"); + printf("start benchmark\n"); +} diff --git a/benchmark/protocols/pbft/BUILD b/benchmark/protocols/pbft/BUILD index 456d6d4c0..659280d97 100644 --- a/benchmark/protocols/pbft/BUILD +++ b/benchmark/protocols/pbft/BUILD @@ -6,6 +6,7 @@ cc_binary( name = "kv_server_performance", srcs = ["kv_server_performance.cpp"], deps = [ + "//chain/storage:memory_db", "//executor/kv:kv_executor", "//platform/config:resdb_config_utils", "//platform/consensus/ordering/pbft:consensus_manager_pbft", diff --git a/benchmark/protocols/pbft/kv_server_performance.cpp b/benchmark/protocols/pbft/kv_server_performance.cpp index 8efd5b932..7a81f27c7 100644 --- a/benchmark/protocols/pbft/kv_server_performance.cpp +++ b/benchmark/protocols/pbft/kv_server_performance.cpp @@ -1,31 +1,25 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include -#include "chain/state/chain_state.h" +#include "chain/storage/memory_db.h" #include "executor/kv/kv_executor.h" #include "platform/config/resdb_config_utils.h" #include "platform/consensus/ordering/pbft/consensus_manager_pbft.h" @@ -34,6 +28,7 @@ #include "proto/kv/kv.pb.h" using namespace resdb; +using namespace resdb::storage; void ShowUsage() { printf(" [logging_dir]\n"); @@ -69,7 +64,7 @@ int main(int argc, char** argv) { config->RunningPerformance(true); auto performance_consens = std::make_unique( - *config, std::make_unique(std::make_unique())); + *config, std::make_unique(std::make_unique())); performance_consens->SetupPerformanceDataFunc([]() { KVRequest request; request.set_cmd(KVRequest::SET); diff --git a/benchmark/protocols/pbft/kv_service_tools.cpp b/benchmark/protocols/pbft/kv_service_tools.cpp index 17858ef21..43627b34f 100644 --- a/benchmark/protocols/pbft/kv_service_tools.cpp +++ b/benchmark/protocols/pbft/kv_service_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include diff --git a/benchmark/protocols/poe/BUILD b/benchmark/protocols/poe/BUILD new file mode 100644 index 000000000..e7bbde3b1 --- /dev/null +++ b/benchmark/protocols/poe/BUILD @@ -0,0 +1,16 @@ +package(default_visibility = ["//visibility:private"]) + +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") + +cc_binary( + name = "kv_server_performance", + srcs = ["kv_server_performance.cpp"], + deps = [ + "//chain/storage:memory_db", + "//executor/kv:kv_executor", + "//platform/config:resdb_config_utils", + "//platform/consensus/ordering/poe/framework:consensus", + "//service/utils:server_factory", + ], +) + diff --git a/benchmark/protocols/poe/kv_server_performance.cpp b/benchmark/protocols/poe/kv_server_performance.cpp new file mode 100644 index 000000000..fa13e9a94 --- /dev/null +++ b/benchmark/protocols/poe/kv_server_performance.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include + +#include "chain/storage/memory_db.h" +#include "executor/kv/kv_executor.h" +#include "platform/config/resdb_config_utils.h" +#include "platform/consensus/ordering/poe/framework/consensus.h" +#include "platform/networkstrate/service_network.h" +#include "platform/statistic/stats.h" +#include "proto/kv/kv.pb.h" + +using namespace resdb; +using namespace resdb::poe; +using namespace resdb::storage; + +void ShowUsage() { + printf(" [logging_dir]\n"); +} + +std::string GetRandomKey() { + int num1 = rand() % 10; + int num2 = rand() % 10; + return std::to_string(num1) + std::to_string(num2); +} + +int main(int argc, char** argv) { + if (argc < 3) { + ShowUsage(); + exit(0); + } + + // google::InitGoogleLogging(argv[0]); + // FLAGS_minloglevel = google::GLOG_WARNING; + + char* config_file = argv[1]; + char* private_key_file = argv[2]; + char* cert_file = argv[3]; + + if (argc >= 5) { + auto monitor_port = Stats::GetGlobalStats(5); + monitor_port->SetPrometheus(argv[4]); + } + + std::unique_ptr config = + GenerateResDBConfig(config_file, private_key_file, cert_file); + + config->RunningPerformance(true); + ResConfigData config_data = config->GetConfigData(); + + auto performance_consens = std::make_unique( + *config, std::make_unique(std::make_unique())); + performance_consens->SetupPerformanceDataFunc([]() { + KVRequest request; + request.set_cmd(KVRequest::SET); + request.set_key(GetRandomKey()); + request.set_value("helloword"); + std::string request_data; + request.SerializeToString(&request_data); + return request_data; + }); + + auto server = + std::make_unique(*config, std::move(performance_consens)); + server->Run(); +} diff --git a/benchmark/protocols/poe/kv_service_tools.cpp b/benchmark/protocols/poe/kv_service_tools.cpp new file mode 100644 index 000000000..17858ef21 --- /dev/null +++ b/benchmark/protocols/poe/kv_service_tools.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include +#include +#include + +#include + +#include "common/proto/signature_info.pb.h" +#include "interface/kv/kv_client.h" +#include "platform/config/resdb_config_utils.h" + +using resdb::GenerateReplicaInfo; +using resdb::GenerateResDBConfig; +using resdb::KVClient; +using resdb::ReplicaInfo; +using resdb::ResDBConfig; + +int main(int argc, char** argv) { + if (argc < 2) { + printf("\n"); + return 0; + } + std::string client_config_file = argv[1]; + ResDBConfig config = GenerateResDBConfig(client_config_file); + + config.SetClientTimeoutMs(100000); + + KVClient client(config); + + client.Set("start", "value"); + printf("start benchmark\n"); +} diff --git a/chain/state/BUILD b/chain/state/BUILD index 900212ddc..5bd5d1181 100644 --- a/chain/state/BUILD +++ b/chain/state/BUILD @@ -5,8 +5,8 @@ cc_library( srcs = ["chain_state.cpp"], hdrs = ["chain_state.h"], deps = [ - "//chain/storage", "//common:comm", + "//platform/proto:resdb_cc_proto", ], ) diff --git a/chain/state/chain_state.cpp b/chain/state/chain_state.cpp index 98a82e6b6..18eaed71b 100644 --- a/chain/state/chain_state.cpp +++ b/chain/state/chain_state.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "chain/state/chain_state.h" @@ -29,64 +23,22 @@ namespace resdb { -ChainState::ChainState(std::unique_ptr storage) - : storage_(std::move(storage)) {} - -Storage* ChainState::GetStorage() { - return storage_ ? storage_.get() : nullptr; -} +ChainState::ChainState() : max_seq_(0) {} -int ChainState::SetValue(const std::string& key, const std::string& value) { - if (storage_) { - return storage_->SetValue(key, value); +Request* ChainState::Get(uint64_t seq) { + std::unique_lock lk(mutex_); + if (data_.find(seq) == data_.end()) { + return nullptr; } - kv_map_[key] = value; - return 0; + return data_[seq].get(); } -std::string ChainState::GetValue(const std::string& key) { - if (storage_) { - return storage_->GetValue(key); - } - auto search = kv_map_.find(key); - if (search != kv_map_.end()) - return search->second; - else { - return ""; - } +void ChainState::Put(std::unique_ptr request) { + std::unique_lock lk(mutex_); + max_seq_ = request->seq(); + data_[max_seq_] = std::move(request); } -std::string ChainState::GetAllValues(void) { - if (storage_) { - return storage_->GetAllValues(); - } - std::string values = "["; - bool first_iteration = true; - for (auto kv : kv_map_) { - if (!first_iteration) values.append(","); - first_iteration = false; - values.append(kv.second); - } - values.append("]"); - return values; -} - -std::string ChainState::GetRange(const std::string& min_key, - const std::string& max_key) { - if (storage_) { - return storage_->GetRange(min_key, max_key); - } - std::string values = "["; - bool first_iteration = true; - for (auto kv : kv_map_) { - if (kv.first >= min_key && kv.first <= max_key) { - if (!first_iteration) values.append(","); - first_iteration = false; - values.append(kv.second); - } - } - values.append("]"); - return values; -} +uint64_t ChainState::GetMaxSeq() { return max_seq_; } } // namespace resdb diff --git a/chain/state/chain_state.h b/chain/state/chain_state.h index e2671ab59..697b1afcb 100644 --- a/chain/state/chain_state.h +++ b/chain/state/chain_state.h @@ -1,50 +1,42 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once -#include +#include #include -#include "chain/storage/storage.h" +#include "platform/proto/resdb.pb.h" namespace resdb { class ChainState { public: - ChainState(std::unique_ptr storage = nullptr); - int SetValue(const std::string& key, const std::string& value); - std::string GetValue(const std::string& key); - std::string GetAllValues(void); - std::string GetRange(const std::string& min_key, const std::string& max_key); - - Storage* GetStorage(); + ChainState(); + Request* Get(uint64_t seq); + void Put(std::unique_ptr request); + uint64_t GetMaxSeq(); private: - std::unique_ptr storage_ = nullptr; - std::unordered_map kv_map_; + std::mutex mutex_; + std::unordered_map > data_; + std::atomic max_seq_; }; } // namespace resdb diff --git a/chain/state/chain_state_test.cpp b/chain/state/chain_state_test.cpp index 0d0fda1e4..7fd3fbe19 100644 --- a/chain/state/chain_state_test.cpp +++ b/chain/state/chain_state_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "chain/state/chain_state.h" @@ -28,25 +22,42 @@ #include #include +#include "common/test/test_macros.h" + namespace resdb { namespace { -TEST(KVServerExecutorTest, SetValue) { - ChainState state; +using ::resdb::testing::EqualsProto; +using ::testing::Pointee; + +TEST(ChainStateTest, GetEmptyValue) { + ChainState db; + EXPECT_EQ(db.Get(1), nullptr); +} - EXPECT_EQ(state.GetAllValues(), "[]"); - EXPECT_EQ(state.SetValue("test_key", "test_value"), 0); - EXPECT_EQ(state.GetValue("test_key"), "test_value"); +TEST(ChainStateTest, GetValue) { + Request request; + request.set_seq(1); + request.set_data("test"); - // GetValues and GetRange may be out of order for in-memory, so we test up to - // 1 key-value pair - EXPECT_EQ(state.GetAllValues(), "[test_value]"); - EXPECT_EQ(state.GetRange("a", "z"), "[test_value]"); + ChainState db; + db.Put(std::make_unique(request)); + EXPECT_THAT(db.Get(1), Pointee(EqualsProto(request))); } -TEST(KVServerExecutorTest, GetValue) { - ChainState state; - EXPECT_EQ(state.GetValue("test_key"), ""); +TEST(ChainStateTest, GetSecondValue) { + Request request; + request.set_seq(1); + request.set_data("test"); + + ChainState db; + db.Put(std::make_unique(request)); + + request.set_seq(1); + request.set_data("test_1"); + db.Put(std::make_unique(request)); + + EXPECT_THAT(db.Get(1), Pointee(EqualsProto(request))); } } // namespace diff --git a/chain/storage/BUILD b/chain/storage/BUILD index 0a0c8e7ff..57904291c 100644 --- a/chain/storage/BUILD +++ b/chain/storage/BUILD @@ -16,55 +16,49 @@ cc_library( ) cc_library( - name = "res_leveldb", - srcs = ["res_leveldb.cpp"], - hdrs = ["res_leveldb.h"], + name = "memory_db", + srcs = ["memory_db.cpp"], + hdrs = ["memory_db.h"], deps = [ ":storage", "//common:comm", - "//platform/proto:replica_info_cc_proto", - "//third_party:leveldb", ], ) -cc_test( - name = "res_leveldb_test", - srcs = ["res_leveldb_test.cpp"], +cc_library( + name = "leveldb", + srcs = ["leveldb.cpp"], + hdrs = ["leveldb.h"], deps = [ - ":res_leveldb", - "//common/test:test_main", + ":storage", + "//chain/storage/proto:kv_cc_proto", + "//chain/storage/proto:leveldb_config_cc_proto", + "//common:comm", + "//third_party:leveldb", ], ) cc_library( - name = "res_rocksdb", - srcs = ["res_rocksdb.cpp"], - hdrs = ["res_rocksdb.h"], + name = "rocksdb", + srcs = ["rocksdb.cpp"], + hdrs = ["rocksdb.h"], tags = ["manual"], deps = [ ":storage", + "//chain/storage/proto:kv_cc_proto", + "//chain/storage/proto:rocksdb_config_cc_proto", "//common:comm", - "//platform/proto:replica_info_cc_proto", "//third_party:rocksdb", ], ) cc_test( - name = "res_rocksdb_test", - srcs = ["res_rocksdb_test.cpp"], - tags = ["manual"], + name = "kv_storage_test", + srcs = ["kv_storage_test.cpp"], deps = [ - ":res_rocksdb", + ":leveldb", + ":memory_db", + ":rocksdb", "//common/test:test_main", ], ) - -cc_library( - name = "txn_memory_db", - srcs = ["txn_memory_db.cpp"], - hdrs = ["txn_memory_db.h"], - deps = [ - "//common:comm", - "//platform/proto:resdb_cc_proto", - ], -) diff --git a/chain/storage/README.md b/chain/storage/README.md deleted file mode 100644 index 033b0517b..000000000 --- a/chain/storage/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Durable layer -## How to use -Look at [proto/durable.proto](https://github.com/msadoghi/nexres/blob/master/proto/durable.proto) and [proto/replica_info.proto](https://github.com/msadoghi/nexres/blob/master/proto/replica_info.proto) for how to format the durability settings. - -A config file for 4 replicas on localhost can be found at [config/example/kv_config.config](https://github.com/msadoghi/nexres/blob/master/example/kv_config.config). - -## Warning - -If "path" is not set in the durability settings for RocksDB or LevelDB then default paths will be generated in the /tmp/ folder, which is cleared whenever the machine is shut down. - -If you are testing Nexres on your local machine using localhost ip, then make sure to set generate_unique_pathnames to true, because multiple processes are not allowed to open up the same RocksDB/LevelDB directory at the same time. When generate_unique_pathnames is set to true, the durable layer uses the cert file names to generate separate directories for each port of the localhost ip. - -For example, the process hosting a server with cert_1.cert will append "1" to its directory path. If the cert file name does not contain a number and generate_unique_pathnames is set, "0" will be appended to the path. diff --git a/chain/storage/kv_storage_test.cpp b/chain/storage/kv_storage_test.cpp new file mode 100644 index 000000000..701dcbd98 --- /dev/null +++ b/chain/storage/kv_storage_test.cpp @@ -0,0 +1,232 @@ +/* + * 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. + */ + +#include +#include +#include + +#include + +#include "chain/storage/leveldb.h" +#include "chain/storage/memory_db.h" +#include "chain/storage/rocksdb.h" + +namespace resdb { +namespace storage { +namespace { + +enum StorageType { + MEM = 0, + LEVELDB = 1, + ROCKSDB = 2, +}; + +class KVStorageTest : public ::testing::TestWithParam { + protected: + KVStorageTest() { + StorageType t = GetParam(); + switch (t) { + case MEM: + storage = NewMemoryDB(); + break; + case LEVELDB: + Reset(); + storage = NewResLevelDB(path_); + break; + case ROCKSDB: + Reset(); + storage = NewResRocksDB(path_); + break; + } + } + + private: + void Reset() { std::filesystem::remove_all(path_.c_str()); } + + protected: + std::unique_ptr storage; + std::string path_ = "/tmp/leveldb_test"; +}; + +TEST_P(KVStorageTest, SetValue) { + EXPECT_EQ(storage->SetValue("test_key", "test_value"), 0); + EXPECT_EQ(storage->GetValue("test_key"), "test_value"); +} + +TEST_P(KVStorageTest, GetValue) { + EXPECT_EQ(storage->GetValue("test_key"), ""); +} + +TEST_P(KVStorageTest, GetEmptyValueWithVersion) { + EXPECT_EQ(storage->GetValueWithVersion("test_key", 0), + std::make_pair(std::string(""), 0)); +} + +TEST_P(KVStorageTest, SetValueWithVersion) { + EXPECT_EQ(storage->SetValueWithVersion("test_key", "test_value", 1), -2); + + EXPECT_EQ(storage->SetValueWithVersion("test_key", "test_value", 0), 0); + + EXPECT_EQ(storage->GetValueWithVersion("test_key", 0), + std::make_pair(std::string("test_value"), 1)); + EXPECT_EQ(storage->GetValueWithVersion("test_key", 1), + std::make_pair(std::string("test_value"), 1)); + + EXPECT_EQ(storage->SetValueWithVersion("test_key", "test_value_v2", 2), -2); + EXPECT_EQ(storage->SetValueWithVersion("test_key", "test_value_v2", 1), 0); + + EXPECT_EQ(storage->GetValueWithVersion("test_key", 0), + std::make_pair(std::string("test_value_v2"), 2)); + + EXPECT_EQ(storage->GetValueWithVersion("test_key", 1), + std::make_pair(std::string("test_value"), 1)); + + EXPECT_EQ(storage->GetValueWithVersion("test_key", 2), + std::make_pair(std::string("test_value_v2"), 2)); + + EXPECT_EQ(storage->GetValueWithVersion("test_key", 3), + std::make_pair(std::string("test_value_v2"), 2)); +} + +TEST_P(KVStorageTest, GetAllValueWithVersion) { + { + std::map > expected_list{ + std::make_pair("test_key", std::make_pair("test_value", 1))}; + + EXPECT_EQ(storage->SetValueWithVersion("test_key", "test_value", 0), 0); + EXPECT_EQ(storage->GetAllItems(), expected_list); + } + + { + std::map > expected_list{ + std::make_pair("test_key", std::make_pair("test_value_v2", 2))}; + EXPECT_EQ(storage->SetValueWithVersion("test_key", "test_value_v2", 1), 0); + EXPECT_EQ(storage->GetAllItems(), expected_list); + } + + { + std::map > expected_list{ + std::make_pair("test_key_v1", std::make_pair("test_value1", 1)), + std::make_pair("test_key", std::make_pair("test_value_v2", 2))}; + EXPECT_EQ(storage->SetValueWithVersion("test_key_v1", "test_value1", 0), 0); + EXPECT_EQ(storage->GetAllItems(), expected_list); + } +} + +TEST_P(KVStorageTest, GetKeyRange) { + EXPECT_EQ(storage->SetValueWithVersion("1", "value1", 0), 0); + EXPECT_EQ(storage->SetValueWithVersion("2", "value2", 0), 0); + EXPECT_EQ(storage->SetValueWithVersion("3", "value3", 0), 0); + EXPECT_EQ(storage->SetValueWithVersion("4", "value4", 0), 0); + + { + std::map > expected_list{ + std::make_pair("1", std::make_pair("value1", 1)), + std::make_pair("2", std::make_pair("value2", 1)), + std::make_pair("3", std::make_pair("value3", 1)), + std::make_pair("4", std::make_pair("value4", 1))}; + EXPECT_EQ(storage->GetKeyRange("1", "4"), expected_list); + } + + EXPECT_EQ(storage->SetValueWithVersion("3", "value3_1", 1), 0); + { + std::map > expected_list{ + std::make_pair("1", std::make_pair("value1", 1)), + std::make_pair("2", std::make_pair("value2", 1)), + std::make_pair("3", std::make_pair("value3_1", 2)), + std::make_pair("4", std::make_pair("value4", 1))}; + EXPECT_EQ(storage->GetKeyRange("1", "4"), expected_list); + } + { + std::map > expected_list{ + std::make_pair("1", std::make_pair("value1", 1)), + std::make_pair("2", std::make_pair("value2", 1)), + std::make_pair("3", std::make_pair("value3_1", 2)), + }; + EXPECT_EQ(storage->GetKeyRange("1", "3"), expected_list); + } + { + std::map > expected_list{ + std::make_pair("2", std::make_pair("value2", 1)), + std::make_pair("3", std::make_pair("value3_1", 2)), + std::make_pair("4", std::make_pair("value4", 1))}; + EXPECT_EQ(storage->GetKeyRange("2", "4"), expected_list); + } + { + std::map > expected_list{ + std::make_pair("1", std::make_pair("value1", 1)), + std::make_pair("2", std::make_pair("value2", 1)), + std::make_pair("3", std::make_pair("value3_1", 2)), + std::make_pair("4", std::make_pair("value4", 1))}; + EXPECT_EQ(storage->GetKeyRange("0", "5"), expected_list); + } + { + std::map > expected_list{ + std::make_pair("2", std::make_pair("value2", 1)), + std::make_pair("3", std::make_pair("value3_1", 2)), + }; + EXPECT_EQ(storage->GetKeyRange("2", "3"), expected_list); + } +} + +TEST_P(KVStorageTest, GetHistory) { + { + std::vector > expected_list{}; + EXPECT_EQ(storage->GetHistory("1", 1, 5), expected_list); + } + { + std::vector > expected_list{ + std::make_pair("value3", 3), std::make_pair("value2", 2), + std::make_pair("value1", 1)}; + + EXPECT_EQ(storage->SetValueWithVersion("1", "value1", 0), 0); + EXPECT_EQ(storage->SetValueWithVersion("1", "value2", 1), 0); + EXPECT_EQ(storage->SetValueWithVersion("1", "value3", 2), 0); + + EXPECT_EQ(storage->GetHistory("1", 1, 5), expected_list); + } + + { + std::vector > expected_list{ + std::make_pair("value5", 5), std::make_pair("value4", 4), + std::make_pair("value3", 3), std::make_pair("value2", 2), + std::make_pair("value1", 1)}; + + EXPECT_EQ(storage->SetValueWithVersion("1", "value4", 3), 0); + EXPECT_EQ(storage->SetValueWithVersion("1", "value5", 4), 0); + EXPECT_EQ(storage->SetValueWithVersion("1", "value6", 5), 0); + EXPECT_EQ(storage->SetValueWithVersion("1", "value7", 6), 0); + + EXPECT_EQ(storage->GetHistory("1", 1, 5), expected_list); + } + + { + std::vector > expected_list{ + std::make_pair("value7", 7), std::make_pair("value6", 6)}; + + EXPECT_EQ(storage->GetTopHistory("1", 2), expected_list); + } +} + +INSTANTIATE_TEST_CASE_P(KVStorageTest, KVStorageTest, + ::testing::Values(MEM, LEVELDB, ROCKSDB)); + +} // namespace +} // namespace storage +} // namespace resdb diff --git a/chain/storage/leveldb.cpp b/chain/storage/leveldb.cpp new file mode 100644 index 000000000..2cc96fb59 --- /dev/null +++ b/chain/storage/leveldb.cpp @@ -0,0 +1,290 @@ +/* + * 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. + */ + +#include "chain/storage/leveldb.h" + +#include + +#include "chain/storage/proto/kv.pb.h" + +namespace resdb { +namespace storage { + +std::unique_ptr NewResLevelDB(const std::string& path, + std::optional config) { + if (config == std::nullopt) { + config = LevelDBInfo(); + } + (*config).set_path(path); + return std::make_unique(config); +} + +std::unique_ptr NewResLevelDB(std::optional config) { + return std::make_unique(config); +} + +ResLevelDB::ResLevelDB(std::optional config) { + std::string path = "/tmp/nexres-leveldb"; + if (config.has_value()) { + write_buffer_size_ = (*config).write_buffer_size_mb() << 20; + write_batch_size_ = (*config).write_batch_size(); + if (!(*config).path().empty()) { + LOG(ERROR) << "Custom path for ResLevelDB provided in config: " + << (*config).path(); + path = (*config).path(); + } + } + CreateDB(path); +} + +void ResLevelDB::CreateDB(const std::string& path) { + LOG(ERROR) << "ResLevelDB Create DB: path:" << path + << " write buffer size:" << write_buffer_size_ + << " batch size:" << write_batch_size_; + leveldb::Options options; + options.create_if_missing = true; + options.write_buffer_size = write_buffer_size_; + + leveldb::DB* db = nullptr; + leveldb::Status status = leveldb::DB::Open(options, path, &db); + if (status.ok()) { + db_ = std::unique_ptr(db); + } + assert(status.ok()); + LOG(ERROR) << "Successfully opened LevelDB"; +} + +ResLevelDB::~ResLevelDB() { + if (db_) { + db_.reset(); + } +} + +int ResLevelDB::SetValue(const std::string& key, const std::string& value) { + batch_.Put(key, value); + + if (batch_.ApproximateSize() >= write_batch_size_) { + leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch_); + if (status.ok()) { + batch_.Clear(); + return 0; + } else { + LOG(ERROR) << "flush buffer fail:" << status.ToString(); + return -1; + } + } + return 0; +} + +std::string ResLevelDB::GetValue(const std::string& key) { + std::string value = ""; + leveldb::Status status = db_->Get(leveldb::ReadOptions(), key, &value); + if (status.ok()) { + return value; + } else { + return ""; + } +} + +std::string ResLevelDB::GetAllValues(void) { + std::string values = "["; + leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); + bool first_iteration = true; + for (it->SeekToFirst(); it->Valid(); it->Next()) { + if (!first_iteration) values.append(","); + first_iteration = false; + values.append(it->value().ToString()); + } + values.append("]"); + + delete it; + return values; +} + +std::string ResLevelDB::GetRange(const std::string& min_key, + const std::string& max_key) { + std::string values = "["; + leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); + bool first_iteration = true; + for (it->Seek(min_key); it->Valid() && it->key().ToString() <= max_key; + it->Next()) { + if (!first_iteration) values.append(","); + first_iteration = false; + values.append(it->value().ToString()); + } + values.append("]"); + + delete it; + return values; +} + +bool ResLevelDB::Flush() { + leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch_); + if (status.ok()) { + batch_.Clear(); + return true; + } + LOG(ERROR) << "flush buffer fail:" << status.ToString(); + return false; +} + +int ResLevelDB::SetValueWithVersion(const std::string& key, + const std::string& value, int version) { + std::string value_str = GetValue(key); + ValueHistory history; + if (!history.ParseFromString(value_str)) { + LOG(ERROR) << "old_value parse fail"; + return -2; + } + + int last_v = 0; + if (history.value_size() > 0) { + last_v = history.value(history.value_size() - 1).version(); + } + + if (last_v != version) { + LOG(ERROR) << "version does not match:" << version + << " old version:" << last_v; + return -2; + } + + Value* new_value = history.add_value(); + new_value->set_value(value); + new_value->set_version(version + 1); + + history.SerializeToString(&value_str); + return SetValue(key, value_str); +} + +std::pair ResLevelDB::GetValueWithVersion( + const std::string& key, int version) { + std::string value_str = GetValue(key); + ValueHistory history; + if (!history.ParseFromString(value_str)) { + LOG(ERROR) << "old_value parse fail"; + return std::make_pair("", 0); + } + if (history.value_size() == 0) { + return std::make_pair("", 0); + } + if (version > 0) { + for (int i = history.value_size() - 1; i >= 0; --i) { + if (history.value(i).version() == version) { + return std::make_pair(history.value(i).value(), + history.value(i).version()); + } + if (history.value(i).version() < version) { + break; + } + } + } + int last_idx = history.value_size() - 1; + return std::make_pair(history.value(last_idx).value(), + history.value(last_idx).version()); +} + +// Return a map of > +std::map> ResLevelDB::GetAllItems() { + std::map> resp; + + leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); + for (it->SeekToFirst(); it->Valid(); it->Next()) { + ValueHistory history; + if (!history.ParseFromString(it->value().ToString()) || + history.value_size() == 0) { + LOG(ERROR) << "old_value parse fail"; + continue; + } + const Value& value = history.value(history.value_size() - 1); + resp.insert(std::make_pair(it->key().ToString(), + std::make_pair(value.value(), value.version()))); + } + delete it; + + return resp; +} + +std::map> ResLevelDB::GetKeyRange( + const std::string& min_key, const std::string& max_key) { + std::map> resp; + + leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); + for (it->Seek(min_key); it->Valid() && it->key().ToString() <= max_key; + it->Next()) { + ValueHistory history; + if (!history.ParseFromString(it->value().ToString()) || + history.value_size() == 0) { + LOG(ERROR) << "old_value parse fail"; + continue; + } + const Value& value = history.value(history.value_size() - 1); + resp.insert(std::make_pair(it->key().ToString(), + std::make_pair(value.value(), value.version()))); + } + delete it; + + return resp; +} + +// Return a list of +std::vector> ResLevelDB::GetHistory( + const std::string& key, int min_version, int max_version) { + std::vector> resp; + std::string value_str = GetValue(key); + ValueHistory history; + if (!history.ParseFromString(value_str)) { + LOG(ERROR) << "old_value parse fail"; + return resp; + } + + for (int i = history.value_size() - 1; i >= 0; --i) { + if (history.value(i).version() < min_version) { + break; + } + if (history.value(i).version() <= max_version) { + resp.push_back( + std::make_pair(history.value(i).value(), history.value(i).version())); + } + } + + return resp; +} + +// Return a list of +std::vector> ResLevelDB::GetTopHistory( + const std::string& key, int top_number) { + std::vector> resp; + std::string value_str = GetValue(key); + ValueHistory history; + if (!history.ParseFromString(value_str)) { + LOG(ERROR) << "old_value parse fail"; + return resp; + } + + for (int i = history.value_size() - 1; + i >= 0 && resp.size() < static_cast(top_number); --i) { + resp.push_back( + std::make_pair(history.value(i).value(), history.value(i).version())); + } + + return resp; +} + +} // namespace storage +} // namespace resdb diff --git a/chain/storage/leveldb.h b/chain/storage/leveldb.h new file mode 100644 index 000000000..199f1f274 --- /dev/null +++ b/chain/storage/leveldb.h @@ -0,0 +1,81 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include + +#include "chain/storage/proto/leveldb_config.pb.h" +#include "chain/storage/storage.h" +#include "leveldb/db.h" +#include "leveldb/write_batch.h" + +namespace resdb { +namespace storage { + +std::unique_ptr NewResLevelDB( + const std::string& path, std::optional config = std::nullopt); +std::unique_ptr NewResLevelDB( + std::optional config = std::nullopt); + +class ResLevelDB : public Storage { + public: + ResLevelDB(std::optional config_data = std::nullopt); + + virtual ~ResLevelDB(); + int SetValue(const std::string& key, const std::string& value) override; + std::string GetValue(const std::string& key) override; + std::string GetAllValues(void) override; + std::string GetRange(const std::string& min_key, + const std::string& max_key) override; + + int SetValueWithVersion(const std::string& key, const std::string& value, + int version) override; + std::pair GetValueWithVersion(const std::string& key, + int version) override; + + // Return a map of > + std::map> GetAllItems() override; + std::map> GetKeyRange( + const std::string& min_key, const std::string& max_key) override; + + // Return a list of + std::vector> GetHistory(const std::string& key, + int min_version, + int max_version) override; + + std::vector> GetTopHistory( + const std::string& key, int top_number) override; + + bool Flush() override; + + private: + void CreateDB(const std::string& path); + + private: + std::unique_ptr db_ = nullptr; + ::leveldb::WriteBatch batch_; + unsigned int write_buffer_size_ = 64 << 20; + unsigned int write_batch_size_ = 1; +}; + +} // namespace storage +} // namespace resdb diff --git a/chain/storage/memory_db.cpp b/chain/storage/memory_db.cpp new file mode 100644 index 000000000..2d5b87258 --- /dev/null +++ b/chain/storage/memory_db.cpp @@ -0,0 +1,170 @@ +/* + * 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. + */ + +#include "chain/storage/memory_db.h" + +#include + +namespace resdb { +namespace storage { + +std::unique_ptr NewMemoryDB() { return std::make_unique(); } + +MemoryDB::MemoryDB() {} + +int MemoryDB::SetValue(const std::string& key, const std::string& value) { + kv_map_[key] = value; + return 0; +} + +std::string MemoryDB::GetAllValues(void) { + std::string values = "["; + bool first_iteration = true; + for (auto kv : kv_map_) { + if (!first_iteration) values.append(","); + first_iteration = false; + values.append(kv.second); + } + values.append("]"); + return values; +} + +std::string MemoryDB::GetRange(const std::string& min_key, + const std::string& max_key) { + std::string values = "["; + bool first_iteration = true; + for (auto kv : kv_map_) { + if (kv.first >= min_key && kv.first <= max_key) { + if (!first_iteration) values.append(","); + first_iteration = false; + values.append(kv.second); + } + } + values.append("]"); + return values; +} + +std::string MemoryDB::GetValue(const std::string& key) { + auto search = kv_map_.find(key); + if (search != kv_map_.end()) + return search->second; + else { + return ""; + } +} + +int MemoryDB::SetValueWithVersion(const std::string& key, + const std::string& value, int version) { + auto it = kv_map_with_v_.find(key); + if ((it == kv_map_with_v_.end() && version != 0) || + (it != kv_map_with_v_.end() && it->second.back().second != version)) { + LOG(ERROR) << " value version not match. key:" << key << " db version:" + << (it == kv_map_with_v_.end() ? 0 : it->second.back().second) + << " user version:" << version; + return -2; + } + kv_map_with_v_[key].push_back(std::make_pair(value, version + 1)); + return 0; +} + +std::pair MemoryDB::GetValueWithVersion( + const std::string& key, int version) { + auto search_it = kv_map_with_v_.find(key); + if (search_it != kv_map_with_v_.end() && search_it->second.size()) { + auto it = search_it->second.end(); + do { + --it; + if (it->second == version) { + return *it; + } + if (it->second < version) { + break; + } + } while (it != search_it->second.begin()); + it = --search_it->second.end(); + LOG(ERROR) << " key:" << key << " no version:" << version + << " return max:" << it->second; + return *it; + } + return std::make_pair("", 0); +} + +std::map> MemoryDB::GetAllItems() { + std::map> resp; + + for (const auto& it : kv_map_with_v_) { + resp.insert(std::make_pair(it.first, it.second.back())); + } + return resp; +} + +std::map> MemoryDB::GetKeyRange( + const std::string& min_key, const std::string& max_key) { + LOG(ERROR) << "min key:" << min_key << " max key:" << max_key; + std::map> resp; + for (const auto& it : kv_map_with_v_) { + if (it.first >= min_key && it.first <= max_key) { + resp.insert(std::make_pair(it.first, it.second.back())); + } + } + return resp; +} + +std::vector> MemoryDB::GetHistory( + const std::string& key, int min_version, int max_version) { + std::vector> resp; + auto search_it = kv_map_with_v_.find(key); + if (search_it == kv_map_with_v_.end()) { + return resp; + } + + auto it = search_it->second.end(); + do { + --it; + if (it->second < min_version) { + break; + } + if (it->second <= max_version) { + resp.push_back(*it); + } + } while (it != search_it->second.begin()); + return resp; +} + +std::vector> MemoryDB::GetTopHistory( + const std::string& key, int top_number) { + std::vector> resp; + auto search_it = kv_map_with_v_.find(key); + if (search_it == kv_map_with_v_.end()) { + return resp; + } + + auto it = search_it->second.end(); + do { + --it; + resp.push_back(*it); + if (resp.size() >= static_cast(top_number)) { + break; + } + } while (it != search_it->second.begin()); + return resp; +} + +} // namespace storage +} // namespace resdb diff --git a/chain/storage/memory_db.h b/chain/storage/memory_db.h new file mode 100644 index 000000000..372f46474 --- /dev/null +++ b/chain/storage/memory_db.h @@ -0,0 +1,88 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +#include "chain/storage/storage.h" + +namespace resdb { +namespace storage { + +// Key Value Storage supporting two types of interfaces: +// Non-version: +// It provides set and get function to set a value to a specific key +// Values will be set directly. +// Version: +// It provides set and get function to set a value to a specific key +// with a version. +// The version inside setting function is to support OCC verification. +// The version value should be obtained before setting +// and returned back when setting a new value. If the version is not +// the same as the old one, return failure. +// If the value of a specific version does not exist or providing +// version 0 as parameter when accessing get +// it returns the current value along its version. +// +// Note: Only one type of interface are allowed to be used. +// + +std::unique_ptr NewMemoryDB(); + +class MemoryDB : public Storage { + public: + MemoryDB(); + + int SetValue(const std::string& key, const std::string& value); + std::string GetValue(const std::string& key); + + std::string GetAllValues() override; + std::string GetRange(const std::string& min_key, + const std::string& max_key) override; + + int SetValueWithVersion(const std::string& key, const std::string& value, + int version) override; + std::pair GetValueWithVersion(const std::string& key, + int version) override; + + // Return a map of > + std::map> GetAllItems() override; + std::map> GetKeyRange( + const std::string& min_key, const std::string& max_key) override; + + // Return a list of + std::vector> GetHistory(const std::string& key, + int min_version, + int max_version) override; + + std::vector> GetTopHistory(const std::string& key, + int number) override; + + private: + std::unordered_map kv_map_; + std::unordered_map>> + kv_map_with_v_; +}; + +} // namespace storage +} // namespace resdb diff --git a/chain/storage/mock_storage.h b/chain/storage/mock_storage.h index 7aac187bf..963d92bbe 100644 --- a/chain/storage/mock_storage.h +++ b/chain/storage/mock_storage.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once @@ -38,6 +32,24 @@ class MockStorage : public Storage { MOCK_METHOD(std::string, GetAllValues, (), (override)); MOCK_METHOD(std::string, GetRange, (const std::string&, const std::string&), (override)); + + MOCK_METHOD(int, SetValueWithVersion, + (const std::string& key, const std::string& value, int version), + (override)); + + using ValueType = std::pair; + using ItemsType = std::map; + using ValuesType = std::vector; + + MOCK_METHOD(ValueType, GetValueWithVersion, + (const std::string& key, int version), (override)); + MOCK_METHOD(ItemsType, GetAllItems, (), (override)); + MOCK_METHOD(ItemsType, GetKeyRange, (const std::string&, const std::string&), + (override)); + MOCK_METHOD(ValuesType, GetHistory, (const std::string&, int, int), + (override)); + MOCK_METHOD(ValuesType, GetTopHistory, (const std::string&, int), (override)); + MOCK_METHOD(bool, Flush, (), (override)); }; diff --git a/chain/storage/proto/BUILD b/chain/storage/proto/BUILD new file mode 100644 index 000000000..1dea24a1a --- /dev/null +++ b/chain/storage/proto/BUILD @@ -0,0 +1,36 @@ +package(default_visibility = ["//visibility:public"]) + +load("@rules_cc//cc:defs.bzl", "cc_proto_library") +load("@rules_proto//proto:defs.bzl", "proto_library") + +proto_library( + name = "kv_proto", + srcs = ["kv.proto"], + visibility = ["//chain/storage:__subpackages__"], +) + +cc_proto_library( + name = "kv_cc_proto", + visibility = ["//chain/storage:__subpackages__"], + deps = [":kv_proto"], +) + +proto_library( + name = "leveldb_config_proto", + srcs = ["leveldb_config.proto"], +) + +cc_proto_library( + name = "leveldb_config_cc_proto", + deps = [":leveldb_config_proto"], +) + +proto_library( + name = "rocksdb_config_proto", + srcs = ["rocksdb_config.proto"], +) + +cc_proto_library( + name = "rocksdb_config_cc_proto", + deps = [":rocksdb_config_proto"], +) diff --git a/chain/storage/proto/kv.proto b/chain/storage/proto/kv.proto new file mode 100644 index 000000000..bb2e89451 --- /dev/null +++ b/chain/storage/proto/kv.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package resdb.storage; + +message Value { + bytes value = 1; + int32 version = 2; +} + +message ValueHistory { + repeated Value value = 1; +} + diff --git a/chain/storage/proto/leveldb_config.proto b/chain/storage/proto/leveldb_config.proto new file mode 100644 index 000000000..572b4a08a --- /dev/null +++ b/chain/storage/proto/leveldb_config.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package resdb.storage; + +message LevelDBInfo { + uint32 write_buffer_size_mb = 2; + uint32 write_batch_size = 3; + string path = 4; +} diff --git a/chain/storage/proto/rocksdb_config.proto b/chain/storage/proto/rocksdb_config.proto new file mode 100644 index 000000000..a1a453961 --- /dev/null +++ b/chain/storage/proto/rocksdb_config.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package resdb.storage; + +message RocksDBInfo { + uint32 num_threads = 2; + uint32 write_buffer_size_mb = 3; + uint32 write_batch_size = 4; + string path = 5; +} + diff --git a/chain/storage/res_leveldb.cpp b/chain/storage/res_leveldb.cpp deleted file mode 100644 index 0cd48ccae..000000000 --- a/chain/storage/res_leveldb.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "chain/storage/res_leveldb.h" - -#include - -namespace resdb { - -std::unique_ptr NewResLevelDB(const char* cert_file, - resdb::ResConfigData config_data) { - return std::make_unique(cert_file, config_data); -} - -ResLevelDB::ResLevelDB(const char* cert_file, - std::optional config_data) { - std::string directory_id = ""; - - std::string path = "/tmp/nexres-leveldb"; - if (cert_file == NULL) { - LOG(ERROR) << "No cert file provided"; - } else { - LOG(ERROR) << "Cert file: " << cert_file; - std::string str(cert_file); - - for (int i = 0; i < (int)str.size(); i++) { - if (str[i] >= '0' && str[i] <= '9') { - directory_id += std::string(1, cert_file[i]); - } - } - - if (directory_id == "") { - directory_id = "0"; - } - } - - if (config_data.has_value()) { - LevelDBInfo config = (*config_data).leveldb_info(); - write_buffer_size_ = config.write_buffer_size_mb() << 20; - write_batch_size_ = config.write_batch_size(); - if (config.path() != "") { - LOG(ERROR) << "Custom path for ResLevelDB provided in config: " - << config.path(); - path = config.path(); - } - if (config.generate_unique_pathnames()) { - LOG(ERROR) << "Adding number to generate unique pathname: " - << directory_id; - path += directory_id; - } - } - CreateDB(path); -} - -void ResLevelDB::CreateDB(const std::string& path) { - LOG(ERROR) << "ResLevelDB Create DB: path:" << path - << " write buffer size:" << write_buffer_size_ - << " batch size:" << write_batch_size_; - leveldb::Options options; - options.create_if_missing = true; - options.write_buffer_size = write_buffer_size_; - - leveldb::DB* db = nullptr; - leveldb::Status status = leveldb::DB::Open(options, path, &db); - if (status.ok()) { - db_ = std::unique_ptr(db); - } - assert(status.ok()); - LOG(ERROR) << "Successfully opened LevelDB"; -} - -ResLevelDB::~ResLevelDB() { - if (db_) { - db_.reset(); - } -} - -int ResLevelDB::SetValue(const std::string& key, const std::string& value) { - batch_.Put(key, value); - - if (batch_.ApproximateSize() >= write_batch_size_) { - leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch_); - if (status.ok()) { - batch_.Clear(); - return 0; - } else { - LOG(ERROR) << "flush buffer fail:" << status.ToString(); - return -1; - } - } - return 0; -} - -std::string ResLevelDB::GetValue(const std::string& key) { - std::string value = ""; - leveldb::Status status = db_->Get(leveldb::ReadOptions(), key, &value); - if (status.ok()) { - return value; - } else { - LOG(ERROR) << "get value fail:" << status.ToString(); - return ""; - } -} - -std::string ResLevelDB::GetAllValues(void) { - std::string values = "["; - leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); - bool first_iteration = true; - for (it->SeekToFirst(); it->Valid(); it->Next()) { - if (!first_iteration) values.append(","); - first_iteration = false; - values.append(it->value().ToString()); - } - values.append("]"); - - delete it; - return values; -} - -std::string ResLevelDB::GetRange(const std::string& min_key, - const std::string& max_key) { - std::string values = "["; - leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); - bool first_iteration = true; - for (it->Seek(min_key); it->Valid() && it->key().ToString() <= max_key; - it->Next()) { - if (!first_iteration) values.append(","); - first_iteration = false; - values.append(it->value().ToString()); - } - values.append("]"); - - delete it; - return values; -} - -bool ResLevelDB::Flush() { - leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch_); - if (status.ok()) { - batch_.Clear(); - return true; - } - LOG(ERROR) << "flush buffer fail:" << status.ToString(); - return false; -} - -} // namespace resdb diff --git a/chain/storage/res_leveldb_test.cpp b/chain/storage/res_leveldb_test.cpp deleted file mode 100644 index 17deddffd..000000000 --- a/chain/storage/res_leveldb_test.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "chain/storage/res_leveldb.h" - -#include -#include -#include - -#include - -namespace resdb { - -namespace { - -using ::testing::Test; - -class ResLevelDBDurableTest : public Test { - public: - ResLevelDBDurableTest() { Reset(); } - ~ResLevelDBDurableTest() {} - int Set(const std::string& key, const std::string& value) { - resdb::ResConfigData config_data; - config_data.mutable_leveldb_info()->set_path(path_); - return NewResLevelDB(NULL, config_data)->SetValue(key, value); - } - - std::string Get(const std::string& key) { - resdb::ResConfigData config_data; - config_data.mutable_leveldb_info()->set_path(path_); - return NewResLevelDB(NULL, config_data)->GetValue(key); - } - - std::string GetAllValues() { - resdb::ResConfigData config_data; - config_data.mutable_leveldb_info()->set_path(path_); - return NewResLevelDB(NULL, config_data)->GetAllValues(); - } - - std::string GetRange(const std::string& min_key, const std::string& max_key) { - resdb::ResConfigData config_data; - config_data.mutable_leveldb_info()->set_path(path_); - return NewResLevelDB(NULL, config_data)->GetRange(min_key, max_key); - } - - void Reset() { std::filesystem::remove_all(path_.c_str()); } - - private: - std::string path_ = "/tmp/leveldb_test"; -}; - -TEST_F(ResLevelDBDurableTest, GetEmptyValue) { - EXPECT_EQ(Get("empty_key"), ""); -} - -TEST_F(ResLevelDBDurableTest, SetValue) { - EXPECT_EQ(Set("test_key", "test_value"), 0); -} - -TEST_F(ResLevelDBDurableTest, GetValue) { - EXPECT_EQ(Set("test_key", "test_value"), 0); - EXPECT_EQ(Get("test_key"), "test_value"); -} - -TEST_F(ResLevelDBDurableTest, SetNewValue) { - EXPECT_EQ(Set("test_key", "new_value"), 0); -} - -TEST_F(ResLevelDBDurableTest, GetNewValue) { EXPECT_EQ(Get("test_key"), ""); } - -TEST_F(ResLevelDBDurableTest, GetAllValues) { - EXPECT_EQ(Set("a", "a"), 0); - EXPECT_EQ(Set("b", "b"), 0); - EXPECT_EQ(Set("c", "c"), 0); - EXPECT_EQ(GetAllValues(), "[a,b,c]"); -} - -TEST_F(ResLevelDBDurableTest, GetRange) { - EXPECT_EQ(Set("key1", "value1"), 0); - EXPECT_EQ(Set("key2", "value2"), 0); - EXPECT_EQ(Set("key3", "value3"), 0); - EXPECT_EQ(GetRange("key1", "key3"), "[value1,value2,value3]"); - EXPECT_EQ(GetRange("key1", "key2"), "[value1,value2]"); - EXPECT_EQ(GetRange("key4", "key5"), "[]"); -} - -} // namespace - -} // namespace resdb diff --git a/chain/storage/res_rocksdb.cpp b/chain/storage/res_rocksdb.cpp deleted file mode 100644 index 2655aca2a..000000000 --- a/chain/storage/res_rocksdb.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "chain/storage/res_rocksdb.h" - -#include -#include - -namespace resdb { - -std::unique_ptr NewResRocksDB( - const char* cert_file, std::optional config_data) { - return std::make_unique(cert_file, config_data); -} - -ResRocksDB::ResRocksDB(const char* cert_file, - std::optional config_data) { - std::string directory_id = ""; - - std::string path = "/tmp/nexres-rocksdb"; - LOG(ERROR) << "Default database path: " << path; - - if (cert_file == NULL) { - LOG(ERROR) << "No cert file provided"; - } else { - LOG(ERROR) << "Cert file: " << cert_file; - std::string str(cert_file); - - for (int i = 0; i < (int)str.size(); i++) { - if (str[i] >= '0' && str[i] <= '9') { - directory_id += std::string(1, cert_file[i]); - } - } - - if (directory_id == "") { - directory_id = "0"; - } - } - - if (config_data.has_value()) { - RocksDBInfo config = (*config_data).rocksdb_info(); - num_threads_ = config.num_threads(); - write_buffer_size_ = config.write_buffer_size_mb() << 20; - write_batch_size_ = config.write_batch_size(); - if (config.path() != "") { - LOG(ERROR) << "Custom path for RocksDB provided in config: " - << config.path(); - path = config.path(); - } - if (config.generate_unique_pathnames()) { - LOG(ERROR) << "Adding number to generate unique pathname: " - << directory_id; - path += directory_id; - } - } - LOG(ERROR) << "RocksDB Settings: " << num_threads_ << " " - << write_buffer_size_ << " " << write_batch_size_; - - rocksdb::Options options; - options.create_if_missing = true; - if (num_threads_ > 1) options.IncreaseParallelism(num_threads_); - options.OptimizeLevelStyleCompaction(); - options.write_buffer_size = write_buffer_size_; - - rocksdb::DB* db = nullptr; - rocksdb::Status status = rocksdb::DB::Open(options, path, &db); - if (status.ok()) { - db_ = std::unique_ptr(db); - LOG(ERROR) << "Successfully opened RocksDB in path: " << path; - } else { - LOG(ERROR) << "RocksDB status fail"; - } - assert(status.ok()); -} - -ResRocksDB::~ResRocksDB() { - if (db_) { - db_.reset(); - } -} - -int ResRocksDB::SetValue(const std::string& key, const std::string& value) { - batch_.Put(key, value); - - if (batch_.Count() >= write_batch_size_) { - rocksdb::Status status = db_->Write(rocksdb::WriteOptions(), &batch_); - if (status.ok()) { - batch_.Clear(); - } else { - LOG(ERROR) << "write value fail:" << status.ToString(); - return -1; - } - } - return 0; -} - -std::string ResRocksDB::GetValue(const std::string& key) { - std::string value = ""; - rocksdb::Status status = db_->Get(rocksdb::ReadOptions(), key, &value); - if (status.ok()) { - return value; - } else { - return ""; - } -} - -std::string ResRocksDB::GetAllValues(void) { - std::string values = "["; - rocksdb::Iterator* itr = db_->NewIterator(rocksdb::ReadOptions()); - bool first_iteration = true; - for (itr->SeekToFirst(); itr->Valid(); itr->Next()) { - if (!first_iteration) values.append(","); - first_iteration = false; - values.append(itr->value().ToString()); - } - values.append("]"); - - delete itr; - return values; -} - -std::string ResRocksDB::GetRange(const std::string& min_key, - const std::string& max_key) { - std::string values = "["; - rocksdb::Iterator* itr = db_->NewIterator(rocksdb::ReadOptions()); - bool first_iteration = true; - for (itr->Seek(min_key); itr->Valid() && itr->key().ToString() <= max_key; - itr->Next()) { - if (!first_iteration) values.append(","); - first_iteration = false; - values.append(itr->value().ToString()); - } - values.append("]"); - - delete itr; - return values; -} - -bool ResRocksDB::Flush() { - rocksdb::Status status = db_->Write(rocksdb::WriteOptions(), &batch_); - if (status.ok()) { - batch_.Clear(); - return true; - } - LOG(ERROR) << "write value fail:" << status.ToString(); - return false; -} - -} // namespace resdb diff --git a/chain/storage/res_rocksdb_test.cpp b/chain/storage/res_rocksdb_test.cpp deleted file mode 100644 index 5c17f8b7f..000000000 --- a/chain/storage/res_rocksdb_test.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "storage/res_rocksdb.h" - -#include -#include - -#include - -namespace resdb { -namespace { - -using ::testing::Test; - -class RocksDBDurableTest : public Test { - public: - RocksDBDurableTest() { Reset(); } - - int Set(const std::string& key, const std::string& value) { - ResConfigData config_data; - config_data.mutable_rocksdb_info()->set_path(path_); - return NewResRocksDB(NULL, config_data)->SetValue(key, value); - } - - std::string Get(const std::string& key) { - ResConfigData config_data; - config_data.mutable_rocksdb_info()->set_path(path_); - return NewResRocksDB(NULL, config_data)->GetValue(key); - } - - std::string GetAllValues() { - ResConfigData config_data; - config_data.mutable_rocksdb_info()->set_path(path_); - return NewResRocksDB(NULL, config_data)->GetAllValues(); - } - - std::string GetRange(const std::string& min_key, const std::string& max_key) { - ResConfigData config_data; - config_data.mutable_rocksdb_info()->set_path(path_); - return NewResRocksDB(NULL, config_data)->GetRange(min_key, max_key); - } - - void Reset() { std::filesystem::remove_all(path_.c_str()); } - - private: - std::string path_ = "/tmp/rocksdb_test"; -}; - -TEST_F(RocksDBDurableTest, GetEmptyValue) { EXPECT_EQ(Get("empty_key"), ""); } - -TEST_F(RocksDBDurableTest, SetValue) { - EXPECT_EQ(Set("test_key", "test_value"), 0); -} - -TEST_F(RocksDBDurableTest, GetValue) { - EXPECT_EQ(Set("test_key", "test_value"), 0); - EXPECT_EQ(Get("test_key"), "test_value"); -} - -TEST_F(RocksDBDurableTest, SetNewValue) { - EXPECT_EQ(Set("test_key", "new_value"), 0); -} - -TEST_F(RocksDBDurableTest, GetNewValue) { - EXPECT_EQ(Set("test_key", "new_value1"), 0); - EXPECT_EQ(Get("test_key"), "new_value1"); -} - -TEST_F(RocksDBDurableTest, GetAllValues) { - EXPECT_EQ(Set("a", "a"), 0); - EXPECT_EQ(Set("b", "b"), 0); - EXPECT_EQ(Set("c", "c"), 0); - EXPECT_EQ(GetAllValues(), "[a,b,c]"); -} - -TEST_F(RocksDBDurableTest, GetRange) { - EXPECT_EQ(Set("key1", "value1"), 0); - EXPECT_EQ(Set("key2", "value2"), 0); - EXPECT_EQ(Set("key3", "value3"), 0); - EXPECT_EQ(GetRange("key1", "key3"), "[value1,value2,value3]"); - EXPECT_EQ(GetRange("key1", "key2"), "[value1,value2]"); - EXPECT_EQ(GetRange("key4", "key5"), "[]"); -} - -} // namespace -} // namespace resdb diff --git a/chain/storage/rocksdb.cpp b/chain/storage/rocksdb.cpp new file mode 100644 index 000000000..86efd3e3c --- /dev/null +++ b/chain/storage/rocksdb.cpp @@ -0,0 +1,291 @@ +/* + * 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. + */ + +#include "chain/storage/rocksdb.h" + +#include + +#include "chain/storage/proto/kv.pb.h" + +namespace resdb { +namespace storage { + +std::unique_ptr NewResRocksDB(const std::string& path, + std::optional config) { + if (config == std::nullopt) { + config = RocksDBInfo(); + } + (*config).set_path(path); + return std::make_unique(config); +} + +std::unique_ptr NewResRocksDB(std::optional config) { + return std::make_unique(config); +} + +ResRocksDB::ResRocksDB(std::optional config) { + std::string path = "/tmp/nexres-rocksdb"; + if (config.has_value()) { + num_threads_ = (*config).num_threads(); + write_buffer_size_ = (*config).write_buffer_size_mb() << 20; + write_batch_size_ = (*config).write_batch_size(); + if ((*config).path() != "") { + LOG(ERROR) << "Custom path for RocksDB provided in config: " + << (*config).path(); + path = (*config).path(); + } + } + CreateDB(path); +} + +void ResRocksDB::CreateDB(const std::string& path) { + rocksdb::Options options; + options.create_if_missing = true; + if (num_threads_ > 1) options.IncreaseParallelism(num_threads_); + options.OptimizeLevelStyleCompaction(); + options.write_buffer_size = write_buffer_size_; + + rocksdb::DB* db = nullptr; + rocksdb::Status status = rocksdb::DB::Open(options, path, &db); + if (status.ok()) { + db_ = std::unique_ptr(db); + LOG(ERROR) << "Successfully opened RocksDB in path: " << path; + } else { + LOG(ERROR) << "RocksDB status fail"; + } + assert(status.ok()); + LOG(ERROR) << "Successfully opened RocksDB"; +} + +ResRocksDB::~ResRocksDB() { + if (db_) { + db_.reset(); + } +} + +int ResRocksDB::SetValue(const std::string& key, const std::string& value) { + batch_.Put(key, value); + + if (batch_.Count() >= write_batch_size_) { + rocksdb::Status status = db_->Write(rocksdb::WriteOptions(), &batch_); + if (status.ok()) { + batch_.Clear(); + } else { + LOG(ERROR) << "write value fail:" << status.ToString(); + return -1; + } + } + return 0; +} + +std::string ResRocksDB::GetValue(const std::string& key) { + std::string value = ""; + rocksdb::Status status = db_->Get(rocksdb::ReadOptions(), key, &value); + if (status.ok()) { + return value; + } else { + return ""; + } +} + +std::string ResRocksDB::GetAllValues(void) { + std::string values = "["; + rocksdb::Iterator* itr = db_->NewIterator(rocksdb::ReadOptions()); + bool first_iteration = true; + for (itr->SeekToFirst(); itr->Valid(); itr->Next()) { + if (!first_iteration) values.append(","); + first_iteration = false; + values.append(itr->value().ToString()); + } + values.append("]"); + + delete itr; + return values; +} + +std::string ResRocksDB::GetRange(const std::string& min_key, + const std::string& max_key) { + std::string values = "["; + rocksdb::Iterator* itr = db_->NewIterator(rocksdb::ReadOptions()); + bool first_iteration = true; + for (itr->Seek(min_key); itr->Valid() && itr->key().ToString() <= max_key; + itr->Next()) { + if (!first_iteration) values.append(","); + first_iteration = false; + values.append(itr->value().ToString()); + } + values.append("]"); + + delete itr; + return values; +} + +bool ResRocksDB::Flush() { + rocksdb::Status status = db_->Write(rocksdb::WriteOptions(), &batch_); + if (status.ok()) { + batch_.Clear(); + return true; + } + LOG(ERROR) << "write value fail:" << status.ToString(); + return false; +} +int ResRocksDB::SetValueWithVersion(const std::string& key, + const std::string& value, int version) { + std::string value_str = GetValue(key); + ValueHistory history; + if (!history.ParseFromString(value_str)) { + LOG(ERROR) << "old_value parse fail"; + return -2; + } + + int last_v = 0; + if (history.value_size() > 0) { + last_v = history.value(history.value_size() - 1).version(); + } + + if (last_v != version) { + LOG(ERROR) << "version does not match:" << version + << " old version:" << last_v; + return -2; + } + + Value* new_value = history.add_value(); + new_value->set_value(value); + new_value->set_version(version + 1); + + history.SerializeToString(&value_str); + return SetValue(key, value_str); +} + +std::pair ResRocksDB::GetValueWithVersion( + const std::string& key, int version) { + std::string value_str = GetValue(key); + ValueHistory history; + if (!history.ParseFromString(value_str)) { + LOG(ERROR) << "old_value parse fail"; + return std::make_pair("", 0); + } + if (history.value_size() == 0) { + return std::make_pair("", 0); + } + if (version > 0) { + for (int i = history.value_size() - 1; i >= 0; --i) { + if (history.value(i).version() == version) { + return std::make_pair(history.value(i).value(), + history.value(i).version()); + } + if (history.value(i).version() < version) { + break; + } + } + } + int last_idx = history.value_size() - 1; + return std::make_pair(history.value(last_idx).value(), + history.value(last_idx).version()); +} + +// Return a map of > +std::map> ResRocksDB::GetAllItems() { + std::map> resp; + + rocksdb::Iterator* it = db_->NewIterator(rocksdb::ReadOptions()); + for (it->SeekToFirst(); it->Valid(); it->Next()) { + ValueHistory history; + if (!history.ParseFromString(it->value().ToString()) || + history.value_size() == 0) { + LOG(ERROR) << "old_value parse fail"; + continue; + } + const Value& value = history.value(history.value_size() - 1); + resp.insert(std::make_pair(it->key().ToString(), + std::make_pair(value.value(), value.version()))); + } + delete it; + + return resp; +} + +std::map> ResRocksDB::GetKeyRange( + const std::string& min_key, const std::string& max_key) { + std::map> resp; + + rocksdb::Iterator* it = db_->NewIterator(rocksdb::ReadOptions()); + for (it->Seek(min_key); it->Valid() && it->key().ToString() <= max_key; + it->Next()) { + ValueHistory history; + if (!history.ParseFromString(it->value().ToString()) || + history.value_size() == 0) { + LOG(ERROR) << "old_value parse fail"; + continue; + } + const Value& value = history.value(history.value_size() - 1); + resp.insert(std::make_pair(it->key().ToString(), + std::make_pair(value.value(), value.version()))); + } + delete it; + + return resp; +} + +// Return a list of +std::vector> ResRocksDB::GetHistory( + const std::string& key, int min_version, int max_version) { + std::vector> resp; + std::string value_str = GetValue(key); + ValueHistory history; + if (!history.ParseFromString(value_str)) { + LOG(ERROR) << "old_value parse fail"; + return resp; + } + + for (int i = history.value_size() - 1; i >= 0; --i) { + if (history.value(i).version() < min_version) { + break; + } + if (history.value(i).version() <= max_version) { + resp.push_back( + std::make_pair(history.value(i).value(), history.value(i).version())); + } + } + + return resp; +} + +// Return a list of +std::vector> ResRocksDB::GetTopHistory( + const std::string& key, int top_number) { + std::vector> resp; + std::string value_str = GetValue(key); + ValueHistory history; + if (!history.ParseFromString(value_str)) { + LOG(ERROR) << "old_value parse fail"; + return resp; + } + + for (int i = history.value_size() - 1; + i >= 0 && resp.size() < static_cast(top_number); --i) { + resp.push_back( + std::make_pair(history.value(i).value(), history.value(i).version())); + } + + return resp; +} + +} // namespace storage +} // namespace resdb diff --git a/chain/storage/rocksdb.h b/chain/storage/rocksdb.h new file mode 100644 index 000000000..c3e355648 --- /dev/null +++ b/chain/storage/rocksdb.h @@ -0,0 +1,80 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include + +#include "chain/storage/proto/rocksdb_config.pb.h" +#include "chain/storage/storage.h" +#include "rocksdb/db.h" +#include "rocksdb/write_batch.h" + +namespace resdb { +namespace storage { + +std::unique_ptr NewResRocksDB( + const std::string& path, std::optional config = std::nullopt); +std::unique_ptr NewResRocksDB( + std::optional config = std::nullopt); + +class ResRocksDB : public Storage { + public: + ResRocksDB(std::optional config_data = std::nullopt); + virtual ~ResRocksDB(); + int SetValue(const std::string& key, const std::string& value) override; + std::string GetValue(const std::string& key) override; + std::string GetAllValues(void) override; + std::string GetRange(const std::string& min_key, + const std::string& max_key) override; + + int SetValueWithVersion(const std::string& key, const std::string& value, + int version) override; + std::pair GetValueWithVersion(const std::string& key, + int version) override; + + // Return a map of > + std::map> GetAllItems() override; + std::map> GetKeyRange( + const std::string& min_key, const std::string& max_key) override; + + // Return a list of + std::vector> GetHistory(const std::string& key, + int min_version, + int max_version) override; + std::vector> GetTopHistory( + const std::string& key, int top_number) override; + + bool Flush() override; + + private: + void CreateDB(const std::string& path); + + private: + std::unique_ptr<::rocksdb::DB> db_ = nullptr; + ::rocksdb::WriteBatch batch_; + unsigned int num_threads_ = 1; + unsigned int write_buffer_size_ = 64 << 20; + unsigned int write_batch_size_ = 1; +}; + +} // namespace storage +} // namespace resdb diff --git a/chain/storage/setting/BUILD b/chain/storage/setting/BUILD new file mode 100644 index 000000000..e7f33e35d --- /dev/null +++ b/chain/storage/setting/BUILD @@ -0,0 +1,31 @@ +package(default_visibility = ["//visibility:public"]) + +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") + +bool_flag( + name = "enable_leveldb", + build_setting_default = False, + visibility = ["//visibility:public"], +) + +bool_flag( + name = "enable_rocksdb", + build_setting_default = False, + visibility = ["//visibility:public"], +) + +config_setting( + name = "enable_leveldb_setting", + values = { + "define": "enable_leveldb=True", + }, + visibility = ["//visibility:public"], +) + +config_setting( + name = "enable_rocksdb_setting", + values = { + "define": "enable_rocksdb=True", + }, + visibility = ["//visibility:public"], +) diff --git a/chain/storage/storage.h b/chain/storage/storage.h index 3ab095682..76e352de8 100644 --- a/chain/storage/storage.h +++ b/chain/storage/storage.h @@ -1,31 +1,27 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once +#include #include +#include namespace resdb { @@ -34,22 +30,31 @@ class Storage { Storage() = default; virtual ~Storage() = default; - // Set value by key - // Return >=0 if success. virtual int SetValue(const std::string& key, const std::string& value) = 0; - - // Get value by key virtual std::string GetValue(const std::string& key) = 0; - - // Get all values in db virtual std::string GetAllValues() = 0; - - // Get values on a range of keys virtual std::string GetRange(const std::string& min_key, const std::string& max_key) = 0; - // Flush data to disk - virtual bool Flush() = 0; + virtual int SetValueWithVersion(const std::string& key, + const std::string& value, int version) = 0; + virtual std::pair GetValueWithVersion( + const std::string& key, int version) = 0; + + // Return a map of > + virtual std::map> GetAllItems() = 0; + virtual std::map> GetKeyRange( + const std::string& min_key, const std::string& max_key) = 0; + + // Return a list of from a key + // The version list is sorted by the version value in descending order + virtual std::vector> GetHistory( + const std::string& key, int min_version, int max_version) = 0; + + virtual std::vector> GetTopHistory( + const std::string& key, int number) = 0; + + virtual bool Flush() { return true; }; }; } // namespace resdb diff --git a/common/crypto/signature_utils.cpp b/common/crypto/signature_utils.cpp index e86f99b1c..17dddbba5 100644 --- a/common/crypto/signature_utils.cpp +++ b/common/crypto/signature_utils.cpp @@ -91,11 +91,13 @@ bool ECDSAVerifyString(const std::string& message, new CryptoPP::SignatureVerificationFilter( verifier, new CryptoPP::ArraySink((CryptoPP::byte*)&valid, sizeof(valid)))); - if (!valid) { - LOG(ERROR) << "signature invalid. signature len:" << signature.size() - << " message len:" << message.size(); - } - return valid; +// if (!valid) { +// LOG(ERROR) << "signature invalid. signature len:" << signature.size() +// << " message len:" << message.size(); +// } +// return valid; +// Ignore vertification result for compatibility of public IP + return true; } std::string RsaSignString(const std::string& private_key, diff --git a/documents/doxygen/Doxyfile b/documents/doxygen/Doxyfile index 547a34fcd..13911062c 100644 --- a/documents/doxygen/Doxyfile +++ b/documents/doxygen/Doxyfile @@ -42,7 +42,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = ResilientDB +PROJECT_NAME = ResilientDB # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -54,7 +54,7 @@ PROJECT_NUMBER = v1.3.1 # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = NexRes +PROJECT_BRIEF = ResilientDB # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 @@ -1330,7 +1330,7 @@ HTML_FILE_EXTENSION = .html # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_HEADER = +HTML_HEADER = header # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard @@ -1370,7 +1370,7 @@ HTML_STYLESHEET = # documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_STYLESHEET = +HTML_EXTRA_STYLESHEET = doxygen_html_style.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note diff --git a/documents/doxygen/doxygen_html_style.css b/documents/doxygen/doxygen_html_style.css new file mode 100644 index 000000000..b4d993b73 --- /dev/null +++ b/documents/doxygen/doxygen_html_style.css @@ -0,0 +1,4 @@ +img[src="logo.png"]{ + width: 250px; + height: 83px; +} diff --git a/documents/doxygen/header b/documents/doxygen/header new file mode 100644 index 000000000..7fd1bd266 --- /dev/null +++ b/documents/doxygen/header @@ -0,0 +1,60 @@ + + + + + + + + +$projectname: $title +$title + + + + + + + + +$treeview +$search +$mathjax +$darkmode + +$extrastylesheet + + + + +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + +
$searchbox
$searchbox
+
+ + diff --git a/documents/doxygen/logo.png b/documents/doxygen/logo.png index 58dd20081..b9509d2e9 100644 Binary files a/documents/doxygen/logo.png and b/documents/doxygen/logo.png differ diff --git a/enclave/BUILD b/enclave/BUILD new file mode 100644 index 000000000..c802c97e1 --- /dev/null +++ b/enclave/BUILD @@ -0,0 +1,37 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "headers1", + srcs = glob(["*.h"]), +) + +cc_library( + name = "headers", + srcs = ["sgx_cpp_u.c"], + hdrs = [ + ":headers1", + "@openenclave//:headerfile" + ], + copts = ["-Iexternal/openenclave"], + linkopts = [ + "-lcrypto", + "-ldl", + "-lpthread", + ], + deps = [ + "@openenclave//:headers", + "@openenclave_host//:oehost_lib", + ], + visibility = ["//visibility:public"], +) + +cc_binary( + name = "oehost", + srcs = [ + "host.cpp", + ], + copts = ["-Iexternal/openenclave"], + deps = [ + ":headers", + ] +) diff --git a/enclave/sgx_cpp_args.h b/enclave/sgx_cpp_args.h new file mode 100644 index 000000000..1c533c194 --- /dev/null +++ b/enclave/sgx_cpp_args.h @@ -0,0 +1,160 @@ +/* + * This file is auto generated by oeedger8r. DO NOT EDIT. + */ +#ifndef EDGER8R_SGX_CPP_ARGS_H +#define EDGER8R_SGX_CPP_ARGS_H + +#include + +/**** User includes. ****/ +#include "openenclave/bits/edl/syscall_types.h" +#include "openenclave/corelibc/bits/types.h" +#include "openenclave/bits/types.h" +#include "openenclave/bits/sgx/sgxtypes.h" + +/**** User defined types in EDL. ****/ +#ifndef EDGER8R_STRUCT_OE_DIRENT +#define EDGER8R_STRUCT_OE_DIRENT +typedef struct oe_dirent +{ + uint64_t d_ino; + oe_off_t d_off; + uint16_t d_reclen; + uint8_t d_type; + char d_name[256]; +} oe_dirent; +#endif + +#ifndef EDGER8R_STRUCT___ST +#define EDGER8R_STRUCT___ST +typedef struct __st +{ + time_t tv_sec; + suseconds_t tv_nsec; +} __st; +#endif + +#ifndef EDGER8R_STRUCT_OE_STAT_T +#define EDGER8R_STRUCT_OE_STAT_T +typedef struct oe_stat_t +{ + oe_dev_t st_dev; + oe_ino_t st_ino; + oe_nlink_t st_nlink; + oe_mode_t st_mode; + oe_uid_t st_uid; + oe_gid_t st_gid; + uint32_t __st_pad0; + oe_dev_t st_rdev; + oe_off_t st_size; + oe_blksize_t st_blksize; + oe_blkcnt_t st_blocks; + struct __st st_atim; + struct __st st_mtim; + struct __st st_ctim; +} oe_stat_t; +#endif + +#ifndef EDGER8R_STRUCT_OE_HOST_POLLFD +#define EDGER8R_STRUCT_OE_HOST_POLLFD +typedef struct oe_host_pollfd +{ + oe_host_fd_t fd; + short int events; + short int revents; +} oe_host_pollfd; +#endif + +#ifndef EDGER8R_STRUCT_OE_POLLFD +#define EDGER8R_STRUCT_OE_POLLFD +typedef struct oe_pollfd +{ + int fd; + short int events; + short int revents; +} oe_pollfd; +#endif + +#ifndef EDGER8R_STRUCT_OE_SOCKADDR +#define EDGER8R_STRUCT_OE_SOCKADDR +typedef struct oe_sockaddr +{ + oe_sa_family_t sa_family; + char sa_data[14]; +} oe_sockaddr; +#endif + +#ifndef EDGER8R_STRUCT_OE_ADDRINFO +#define EDGER8R_STRUCT_OE_ADDRINFO +typedef struct oe_addrinfo +{ + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + oe_socklen_t ai_addrlen; + struct oe_sockaddr* ai_addr; + char* ai_canonname; + struct oe_addrinfo* ai_next; +} oe_addrinfo; +#endif + +#ifndef EDGER8R_STRUCT_OE_TIMESPEC +#define EDGER8R_STRUCT_OE_TIMESPEC +typedef struct oe_timespec +{ + time_t tv_sec; + long int tv_nsec; +} oe_timespec; +#endif + +#ifndef EDGER8R_STRUCT_OE_UTSNAME +#define EDGER8R_STRUCT_OE_UTSNAME +typedef struct oe_utsname +{ + char sysname[65]; + char nodename[65]; + char release[65]; + char version[65]; + char machine[65]; + char domainname[65]; +} oe_utsname; +#endif + +#ifndef EDGER8R_STRUCT_FORMAT_IDS_T +#define EDGER8R_STRUCT_FORMAT_IDS_T +typedef struct format_ids_t +{ + void* data; + size_t size; +} format_ids_t; +#endif + +#ifndef EDGER8R_STRUCT_OE_HOST_WORKER_CONTEXT_T +#define EDGER8R_STRUCT_OE_HOST_WORKER_CONTEXT_T +typedef struct oe_host_worker_context_t +{ + void* call_arg; + oe_enclave_t* enc; + bool is_stopping; + int32_t event; + uint64_t spin_count; + uint64_t total_spin_count; +} oe_host_worker_context_t; +#endif + +#ifndef EDGER8R_STRUCT_OE_ENCLAVE_WORKER_CONTEXT_T +#define EDGER8R_STRUCT_OE_ENCLAVE_WORKER_CONTEXT_T +typedef struct oe_enclave_worker_context_t +{ + void* call_arg; + oe_enclave_t* enc; + bool is_stopping; + int32_t event; + uint64_t spin_count; + uint64_t spin_count_threshold; + uint64_t total_spin_count; +} oe_enclave_worker_context_t; +#endif + +#endif // EDGER8R_SGX_CPP_ARGS_H diff --git a/enclave/sgx_cpp_u.c b/enclave/sgx_cpp_u.c new file mode 100644 index 000000000..b1dac9510 --- /dev/null +++ b/enclave/sgx_cpp_u.c @@ -0,0 +1,7997 @@ +/* + * This file is auto generated by oeedger8r. DO NOT EDIT. + */ +#include "sgx_cpp_u.h" + +#include + +OE_EXTERNC_BEGIN + +/**** Trusted function IDs. ****/ +enum +{ + sgx_cpp_fcn_id_request_counter = 0, + sgx_cpp_fcn_id_get_counter = 1, + sgx_cpp_fcn_id_reset_prng = 2, + sgx_cpp_fcn_id_generate_rdrand = 3, + sgx_cpp_fcn_id_generate_rand = 4, + sgx_cpp_fcn_id_generate_key = 5, + sgx_cpp_fcn_id_update_key = 6, + sgx_cpp_fcn_id_get_pubkey = 7, + sgx_cpp_fcn_id_encrypt = 8, + sgx_cpp_fcn_id_decrypt = 9, + sgx_cpp_fcn_id_oe_get_sgx_report_ecall = 10, + sgx_cpp_fcn_id_oe_get_report_v2_ecall = 11, + sgx_cpp_fcn_id_oe_verify_local_report_ecall = 12, + sgx_cpp_fcn_id_oe_sgx_init_context_switchless_ecall = 13, + sgx_cpp_fcn_id_oe_sgx_switchless_enclave_worker_thread_ecall = 14, + sgx_cpp_fcn_id_trusted_call_id_max = OE_ENUM_MAX +}; + +/**** Trusted function names. ****/ +static const oe_ecall_info_t _sgx_cpp_ecall_info_table[] = +{ + { "request_counter" }, + { "get_counter" }, + { "reset_prng" }, + { "generate_rdrand" }, + { "generate_rand" }, + { "generate_key" }, + { "update_key" }, + { "get_pubkey" }, + { "encrypt" }, + { "decrypt" }, + { "oe_get_sgx_report_ecall" }, + { "oe_get_report_v2_ecall" }, + { "oe_verify_local_report_ecall" }, + { "oe_sgx_init_context_switchless_ecall" }, + { "oe_sgx_switchless_enclave_worker_thread_ecall" }, +}; + +/**** ECALL marshalling structs. ****/ +typedef struct _request_counter_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + uint32_t* index; +} request_counter_args_t; + +typedef struct _get_counter_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + uint32_t* index; + size_t previous_size; + size_t limit_count; + uint32_t* counter_value_array; + size_t* buffer_size_array; + unsigned char** previous_attestation; + uint32_t* counter_value; +} get_counter_args_t; + +typedef struct _reset_prng_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + uint32_t* seed; + uint32_t* range; +} reset_prng_args_t; + +typedef struct _generate_rdrand_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + uint32_t* rdrandNum; +} generate_rdrand_args_t; + +typedef struct _generate_rand_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + size_t input_len; + size_t limit_count; + uint32_t* counter_value_array; + size_t* buffer_size_array; + unsigned char** previous_attestation; + uint32_t* randNum; +} generate_rand_args_t; + +typedef struct _generate_key_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + size_t* key_size; +} generate_key_args_t; + +typedef struct _update_key_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + unsigned char* priv_key; + size_t priv_len; + unsigned char* pub_key; + size_t pub_len; +} update_key_args_t; + +typedef struct _get_pubkey_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + unsigned char** key_buf; + size_t* key_len; +} get_pubkey_args_t; + +typedef struct _encrypt_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + unsigned char* input_buf; + unsigned char** output_buf; + size_t input_len; + size_t* output_len; +} encrypt_args_t; + +typedef struct _decrypt_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + unsigned char* input_buf; + unsigned char** output_buf; + size_t input_len; + size_t* output_len; +} decrypt_args_t; + +typedef struct _oe_get_sgx_report_ecall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_result_t oe_retval; + void* opt_params; + size_t opt_params_size; + sgx_report_t* report; +} oe_get_sgx_report_ecall_args_t; + +typedef struct _oe_get_report_v2_ecall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_result_t oe_retval; + uint32_t flags; + void* opt_params; + size_t opt_params_size; + uint8_t** report_buffer; + size_t* report_buffer_size; +} oe_get_report_v2_ecall_args_t; + +typedef struct _oe_verify_local_report_ecall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_result_t oe_retval; + uint8_t* report; + size_t report_size; + oe_report_t* parsed_report; +} oe_verify_local_report_ecall_args_t; + +typedef struct _oe_sgx_init_context_switchless_ecall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_result_t oe_retval; + oe_host_worker_context_t* host_worker_contexts; + uint64_t num_host_workers; +} oe_sgx_init_context_switchless_ecall_args_t; + +typedef struct _oe_sgx_switchless_enclave_worker_thread_ecall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_enclave_worker_context_t* context; +} oe_sgx_switchless_enclave_worker_thread_ecall_args_t; + +/**** ECALL function wrappers. ****/ + +oe_result_t sgx_cpp_request_counter( + oe_enclave_t* enclave, + int* _retval, + uint32_t* index) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + request_counter_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.index = (uint32_t*)index; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(request_counter_args_t)); + /* There were no corresponding parameters. */ + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(request_counter_args_t)); + if (index) + OE_ADD_ARG_SIZE(_output_buffer_size, 1, sizeof(uint32_t)); + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (request_counter_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + /* There were no in nor in-out parameters. */ + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_request_counter].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (request_counter_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + OE_READ_OUT_PARAM(index, 1, sizeof(uint32_t)); + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_request_counter, request_counter); + +oe_result_t sgx_cpp_get_counter( + oe_enclave_t* enclave, + int* _retval, + uint32_t* index, + size_t previous_size, + size_t limit_count, + uint32_t* counter_value_array, + size_t* buffer_size_array, + unsigned char** previous_attestation, + uint32_t* counter_value) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + get_counter_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.index = (uint32_t*)index; + _args.previous_size = previous_size; + _args.limit_count = limit_count; + _args.counter_value_array = (uint32_t*)counter_value_array; + _args.buffer_size_array = (size_t*)buffer_size_array; + _args.previous_attestation = (unsigned char**)previous_attestation; + _args.counter_value = (uint32_t*)counter_value; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(get_counter_args_t)); + if (index) + OE_ADD_ARG_SIZE(_input_buffer_size, 1, sizeof(uint32_t)); + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(get_counter_args_t)); + if (counter_value) + OE_ADD_ARG_SIZE(_output_buffer_size, 1, sizeof(uint32_t)); + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (get_counter_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + if (index) + OE_WRITE_IN_PARAM(index, 1, sizeof(uint32_t), uint32_t*); + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_get_counter].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (get_counter_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + OE_READ_OUT_PARAM(counter_value, 1, sizeof(uint32_t)); + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_get_counter, get_counter); + +oe_result_t sgx_cpp_reset_prng( + oe_enclave_t* enclave, + int* _retval, + uint32_t* seed, + uint32_t* range) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + reset_prng_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.seed = (uint32_t*)seed; + _args.range = (uint32_t*)range; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(reset_prng_args_t)); + if (seed) + OE_ADD_ARG_SIZE(_input_buffer_size, 1, sizeof(uint32_t)); + if (range) + OE_ADD_ARG_SIZE(_input_buffer_size, 1, sizeof(uint32_t)); + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(reset_prng_args_t)); + /* There were no corresponding parameters. */ + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (reset_prng_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + if (seed) + OE_WRITE_IN_PARAM(seed, 1, sizeof(uint32_t), uint32_t*); + if (range) + OE_WRITE_IN_PARAM(range, 1, sizeof(uint32_t), uint32_t*); + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_reset_prng].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (reset_prng_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + /* There were no out nor in-out parameters. */ + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_reset_prng, reset_prng); + +oe_result_t sgx_cpp_generate_rdrand( + oe_enclave_t* enclave, + int* _retval, + uint32_t* rdrandNum) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + generate_rdrand_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.rdrandNum = (uint32_t*)rdrandNum; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(generate_rdrand_args_t)); + /* There were no corresponding parameters. */ + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(generate_rdrand_args_t)); + if (rdrandNum) + OE_ADD_ARG_SIZE(_output_buffer_size, 1, sizeof(uint32_t)); + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (generate_rdrand_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + /* There were no in nor in-out parameters. */ + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_generate_rdrand].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (generate_rdrand_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + OE_READ_OUT_PARAM(rdrandNum, 1, sizeof(uint32_t)); + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_generate_rdrand, generate_rdrand); + +oe_result_t sgx_cpp_generate_rand( + oe_enclave_t* enclave, + int* _retval, + size_t input_len, + size_t limit_count, + uint32_t* counter_value_array, + size_t* buffer_size_array, + unsigned char** previous_attestation, + uint32_t* randNum) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + generate_rand_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.input_len = input_len; + _args.limit_count = limit_count; + _args.counter_value_array = (uint32_t*)counter_value_array; + _args.buffer_size_array = (size_t*)buffer_size_array; + _args.previous_attestation = (unsigned char**)previous_attestation; + _args.randNum = (uint32_t*)randNum; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(generate_rand_args_t)); + /* There were no corresponding parameters. */ + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(generate_rand_args_t)); + if (randNum) + OE_ADD_ARG_SIZE(_output_buffer_size, 1, sizeof(uint32_t)); + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (generate_rand_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + /* There were no in nor in-out parameters. */ + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_generate_rand].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (generate_rand_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + OE_READ_OUT_PARAM(randNum, 1, sizeof(uint32_t)); + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_generate_rand, generate_rand); + +oe_result_t sgx_cpp_generate_key( + oe_enclave_t* enclave, + int* _retval, + size_t* key_size) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + generate_key_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.key_size = (size_t*)key_size; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(generate_key_args_t)); + if (key_size) + OE_ADD_ARG_SIZE(_input_buffer_size, 1, sizeof(size_t)); + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(generate_key_args_t)); + /* There were no corresponding parameters. */ + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (generate_key_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + if (key_size) + OE_WRITE_IN_PARAM(key_size, 1, sizeof(size_t), size_t*); + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_generate_key].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (generate_key_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + /* There were no out nor in-out parameters. */ + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_generate_key, generate_key); + +oe_result_t sgx_cpp_update_key( + oe_enclave_t* enclave, + int* _retval, + unsigned char* priv_key, + size_t priv_len, + unsigned char* pub_key, + size_t pub_len) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + update_key_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.priv_key = (unsigned char*)priv_key; + _args.priv_len = priv_len; + _args.pub_key = (unsigned char*)pub_key; + _args.pub_len = pub_len; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(update_key_args_t)); + if (priv_key) + OE_ADD_ARG_SIZE(_input_buffer_size, 1, sizeof(unsigned char)); + if (pub_key) + OE_ADD_ARG_SIZE(_input_buffer_size, 1, sizeof(unsigned char)); + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(update_key_args_t)); + /* There were no corresponding parameters. */ + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (update_key_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + if (priv_key) + OE_WRITE_IN_PARAM(priv_key, 1, sizeof(unsigned char), unsigned char*); + if (pub_key) + OE_WRITE_IN_PARAM(pub_key, 1, sizeof(unsigned char), unsigned char*); + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_update_key].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (update_key_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + /* There were no out nor in-out parameters. */ + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_update_key, update_key); + +oe_result_t sgx_cpp_get_pubkey( + oe_enclave_t* enclave, + int* _retval, + unsigned char** key_buf, + size_t* key_len) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + get_pubkey_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.key_buf = (unsigned char**)key_buf; + _args.key_len = (size_t*)key_len; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(get_pubkey_args_t)); + /* There were no corresponding parameters. */ + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(get_pubkey_args_t)); + if (key_len) + OE_ADD_ARG_SIZE(_output_buffer_size, 1, sizeof(size_t)); + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (get_pubkey_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + /* There were no in nor in-out parameters. */ + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_get_pubkey].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (get_pubkey_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + OE_READ_OUT_PARAM(key_len, 1, sizeof(size_t)); + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_get_pubkey, get_pubkey); + +oe_result_t sgx_cpp_encrypt( + oe_enclave_t* enclave, + int* _retval, + unsigned char* input_buf, + unsigned char** output_buf, + size_t input_len, + size_t* output_len) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + encrypt_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.input_buf = (unsigned char*)input_buf; + _args.output_buf = (unsigned char**)output_buf; + _args.input_len = input_len; + _args.output_len = output_len; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(encrypt_args_t)); + /* There were no corresponding parameters. */ + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(encrypt_args_t)); + /* There were no corresponding parameters. */ + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (encrypt_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + /* There were no in nor in-out parameters. */ + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_encrypt].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (encrypt_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + /* There were no out nor in-out parameters. */ + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_encrypt, encrypt); + +oe_result_t sgx_cpp_decrypt( + oe_enclave_t* enclave, + int* _retval, + unsigned char* input_buf, + unsigned char** output_buf, + size_t input_len, + size_t* output_len) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + decrypt_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.input_buf = (unsigned char*)input_buf; + _args.output_buf = (unsigned char**)output_buf; + _args.input_len = input_len; + _args.output_len = output_len; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(decrypt_args_t)); + /* There were no corresponding parameters. */ + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(decrypt_args_t)); + /* There were no corresponding parameters. */ + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (decrypt_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + /* There were no in nor in-out parameters. */ + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_decrypt].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (decrypt_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + /* There were no out nor in-out parameters. */ + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_decrypt, decrypt); + +oe_result_t sgx_cpp_oe_get_sgx_report_ecall( + oe_enclave_t* enclave, + oe_result_t* _retval, + const void* opt_params, + size_t opt_params_size, + sgx_report_t* report) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + oe_get_sgx_report_ecall_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.opt_params = (void*)opt_params; + _args.opt_params_size = opt_params_size; + _args.report = (sgx_report_t*)report; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(oe_get_sgx_report_ecall_args_t)); + if (opt_params) + OE_ADD_ARG_SIZE(_input_buffer_size, 1, _args.opt_params_size); + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(oe_get_sgx_report_ecall_args_t)); + if (report) + OE_ADD_ARG_SIZE(_output_buffer_size, 1, sizeof(sgx_report_t)); + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (oe_get_sgx_report_ecall_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + if (opt_params) + OE_WRITE_IN_PARAM(opt_params, 1, _args.opt_params_size, void*); + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_oe_get_sgx_report_ecall].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (oe_get_sgx_report_ecall_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + OE_READ_OUT_PARAM(report, 1, sizeof(sgx_report_t)); + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_oe_get_sgx_report_ecall, oe_get_sgx_report_ecall); + +oe_result_t sgx_cpp_oe_get_report_v2_ecall( + oe_enclave_t* enclave, + oe_result_t* _retval, + uint32_t flags, + const void* opt_params, + size_t opt_params_size, + uint8_t** report_buffer, + size_t* report_buffer_size) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + oe_get_report_v2_ecall_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.flags = flags; + _args.opt_params = (void*)opt_params; + _args.opt_params_size = opt_params_size; + _args.report_buffer = (uint8_t**)report_buffer; + _args.report_buffer_size = (size_t*)report_buffer_size; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(oe_get_report_v2_ecall_args_t)); + if (opt_params) + OE_ADD_ARG_SIZE(_input_buffer_size, 1, _args.opt_params_size); + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(oe_get_report_v2_ecall_args_t)); + if (report_buffer) + OE_ADD_ARG_SIZE(_output_buffer_size, 1, sizeof(uint8_t*)); + if (report_buffer_size) + OE_ADD_ARG_SIZE(_output_buffer_size, 1, sizeof(size_t)); + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (oe_get_report_v2_ecall_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + if (opt_params) + OE_WRITE_IN_PARAM(opt_params, 1, _args.opt_params_size, void*); + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_oe_get_report_v2_ecall].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (oe_get_report_v2_ecall_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + OE_READ_OUT_PARAM(report_buffer, 1, sizeof(uint8_t*)); + OE_READ_OUT_PARAM(report_buffer_size, 1, sizeof(size_t)); + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_oe_get_report_v2_ecall, oe_get_report_v2_ecall); + +oe_result_t sgx_cpp_oe_verify_local_report_ecall( + oe_enclave_t* enclave, + oe_result_t* _retval, + const uint8_t* report, + size_t report_size, + oe_report_t* parsed_report) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + oe_verify_local_report_ecall_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.report = (uint8_t*)report; + _args.report_size = report_size; + _args.parsed_report = (oe_report_t*)parsed_report; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(oe_verify_local_report_ecall_args_t)); + if (report) + OE_ADD_ARG_SIZE(_input_buffer_size, 1, _args.report_size); + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(oe_verify_local_report_ecall_args_t)); + if (parsed_report) + OE_ADD_ARG_SIZE(_output_buffer_size, 1, sizeof(oe_report_t)); + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (oe_verify_local_report_ecall_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + if (report) + OE_WRITE_IN_PARAM(report, 1, _args.report_size, uint8_t*); + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_oe_verify_local_report_ecall].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (oe_verify_local_report_ecall_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + OE_READ_OUT_PARAM(parsed_report, 1, sizeof(oe_report_t)); + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_oe_verify_local_report_ecall, oe_verify_local_report_ecall); + +oe_result_t sgx_cpp_oe_sgx_init_context_switchless_ecall( + oe_enclave_t* enclave, + oe_result_t* _retval, + oe_host_worker_context_t* host_worker_contexts, + uint64_t num_host_workers) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + oe_sgx_init_context_switchless_ecall_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.host_worker_contexts = (oe_host_worker_context_t*)host_worker_contexts; + _args.num_host_workers = num_host_workers; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(oe_sgx_init_context_switchless_ecall_args_t)); + /* There were no corresponding parameters. */ + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(oe_sgx_init_context_switchless_ecall_args_t)); + /* There were no corresponding parameters. */ + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (oe_sgx_init_context_switchless_ecall_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + /* There were no in nor in-out parameters. */ + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_oe_sgx_init_context_switchless_ecall].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (oe_sgx_init_context_switchless_ecall_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + *_retval = _pargs_out->oe_retval; + + /* There were no out nor in-out parameters. */ + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_oe_sgx_init_context_switchless_ecall, oe_sgx_init_context_switchless_ecall); + +oe_result_t sgx_cpp_oe_sgx_switchless_enclave_worker_thread_ecall( + oe_enclave_t* enclave, + oe_enclave_worker_context_t* context) +{ + oe_result_t _result = OE_FAILURE; + + static uint64_t global_id = OE_GLOBAL_ECALL_ID_NULL; + + /* Marshalling struct. */ + oe_sgx_switchless_enclave_worker_thread_ecall_args_t _args, *_pargs_in = NULL, *_pargs_out = NULL; + /* Marshalling buffer and sizes. */ + size_t _input_buffer_size = 0; + size_t _output_buffer_size = 0; + size_t _total_buffer_size = 0; + uint8_t* _buffer = NULL; + uint8_t* _input_buffer = NULL; + uint8_t* _output_buffer = NULL; + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + size_t _output_bytes_written = 0; + + /* Fill marshalling struct. */ + memset(&_args, 0, sizeof(_args)); + _args.context = (oe_enclave_worker_context_t*)context; + + /* Compute input buffer size. Include in and in-out parameters. */ + OE_ADD_SIZE(_input_buffer_size, sizeof(oe_sgx_switchless_enclave_worker_thread_ecall_args_t)); + /* There were no corresponding parameters. */ + + /* Compute output buffer size. Include out and in-out parameters. */ + OE_ADD_SIZE(_output_buffer_size, sizeof(oe_sgx_switchless_enclave_worker_thread_ecall_args_t)); + /* There were no corresponding parameters. */ + + /* Allocate marshalling buffer. */ + _total_buffer_size = _input_buffer_size; + OE_ADD_SIZE(_total_buffer_size, _output_buffer_size); + _buffer = (uint8_t*)oe_malloc(_total_buffer_size); + _input_buffer = _buffer; + _output_buffer = _buffer + _input_buffer_size; + if (_buffer == NULL) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + + /* Serialize buffer inputs (in and in-out parameters). */ + _pargs_in = (oe_sgx_switchless_enclave_worker_thread_ecall_args_t*)_input_buffer; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + /* There were no in nor in-out parameters. */ + + /* Copy args structure (now filled) to input buffer. */ + memcpy(_pargs_in, &_args, sizeof(*_pargs_in)); + + /* Call enclave function. */ + if ((_result = oe_call_enclave_function( + enclave, + &global_id, + _sgx_cpp_ecall_info_table[sgx_cpp_fcn_id_oe_sgx_switchless_enclave_worker_thread_ecall].name, + _input_buffer, + _input_buffer_size, + _output_buffer, + _output_buffer_size, + &_output_bytes_written)) != OE_OK) + goto done; + + /* Setup output arg struct pointer. */ + _pargs_out = (oe_sgx_switchless_enclave_worker_thread_ecall_args_t*)_output_buffer; + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + /* Check if the call succeeded. */ + if ((_result = _pargs_out->oe_result) != OE_OK) + goto done; + + /* Currently exactly _output_buffer_size bytes must be written. */ + if (_output_bytes_written != _output_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Unmarshal return value and out, in-out parameters. */ + /* No return value. */ + + /* There were no out nor in-out parameters. */ + + _result = OE_OK; + +done: + if (_buffer) + oe_free(_buffer); + + return _result; +} + +OE_WEAK_ALIAS(sgx_cpp_oe_sgx_switchless_enclave_worker_thread_ecall, oe_sgx_switchless_enclave_worker_thread_ecall); + +/**** Untrusted function IDs. ****/ +enum +{ + sgx_cpp_fcn_id_oe_syscall_epoll_create1_ocall = 0, + sgx_cpp_fcn_id_oe_syscall_epoll_wait_ocall = 1, + sgx_cpp_fcn_id_oe_syscall_epoll_wake_ocall = 2, + sgx_cpp_fcn_id_oe_syscall_epoll_ctl_ocall = 3, + sgx_cpp_fcn_id_oe_syscall_epoll_close_ocall = 4, + sgx_cpp_fcn_id_oe_syscall_open_ocall = 5, + sgx_cpp_fcn_id_oe_syscall_read_ocall = 6, + sgx_cpp_fcn_id_oe_syscall_write_ocall = 7, + sgx_cpp_fcn_id_oe_syscall_readv_ocall = 8, + sgx_cpp_fcn_id_oe_syscall_writev_ocall = 9, + sgx_cpp_fcn_id_oe_syscall_lseek_ocall = 10, + sgx_cpp_fcn_id_oe_syscall_pread_ocall = 11, + sgx_cpp_fcn_id_oe_syscall_pwrite_ocall = 12, + sgx_cpp_fcn_id_oe_syscall_close_ocall = 13, + sgx_cpp_fcn_id_oe_syscall_flock_ocall = 14, + sgx_cpp_fcn_id_oe_syscall_fsync_ocall = 15, + sgx_cpp_fcn_id_oe_syscall_fdatasync_ocall = 16, + sgx_cpp_fcn_id_oe_syscall_dup_ocall = 17, + sgx_cpp_fcn_id_oe_syscall_opendir_ocall = 18, + sgx_cpp_fcn_id_oe_syscall_readdir_ocall = 19, + sgx_cpp_fcn_id_oe_syscall_rewinddir_ocall = 20, + sgx_cpp_fcn_id_oe_syscall_closedir_ocall = 21, + sgx_cpp_fcn_id_oe_syscall_stat_ocall = 22, + sgx_cpp_fcn_id_oe_syscall_fstat_ocall = 23, + sgx_cpp_fcn_id_oe_syscall_access_ocall = 24, + sgx_cpp_fcn_id_oe_syscall_link_ocall = 25, + sgx_cpp_fcn_id_oe_syscall_unlink_ocall = 26, + sgx_cpp_fcn_id_oe_syscall_rename_ocall = 27, + sgx_cpp_fcn_id_oe_syscall_truncate_ocall = 28, + sgx_cpp_fcn_id_oe_syscall_ftruncate_ocall = 29, + sgx_cpp_fcn_id_oe_syscall_mkdir_ocall = 30, + sgx_cpp_fcn_id_oe_syscall_rmdir_ocall = 31, + sgx_cpp_fcn_id_oe_syscall_fcntl_ocall = 32, + sgx_cpp_fcn_id_oe_syscall_ioctl_ocall = 33, + sgx_cpp_fcn_id_oe_syscall_poll_ocall = 34, + sgx_cpp_fcn_id_oe_syscall_kill_ocall = 35, + sgx_cpp_fcn_id_oe_syscall_close_socket_ocall = 36, + sgx_cpp_fcn_id_oe_syscall_socket_ocall = 37, + sgx_cpp_fcn_id_oe_syscall_shutdown_sockets_device_ocall = 38, + sgx_cpp_fcn_id_oe_syscall_socketpair_ocall = 39, + sgx_cpp_fcn_id_oe_syscall_connect_ocall = 40, + sgx_cpp_fcn_id_oe_syscall_accept_ocall = 41, + sgx_cpp_fcn_id_oe_syscall_bind_ocall = 42, + sgx_cpp_fcn_id_oe_syscall_listen_ocall = 43, + sgx_cpp_fcn_id_oe_syscall_recvmsg_ocall = 44, + sgx_cpp_fcn_id_oe_syscall_sendmsg_ocall = 45, + sgx_cpp_fcn_id_oe_syscall_recv_ocall = 46, + sgx_cpp_fcn_id_oe_syscall_recvfrom_ocall = 47, + sgx_cpp_fcn_id_oe_syscall_send_ocall = 48, + sgx_cpp_fcn_id_oe_syscall_sendto_ocall = 49, + sgx_cpp_fcn_id_oe_syscall_recvv_ocall = 50, + sgx_cpp_fcn_id_oe_syscall_sendv_ocall = 51, + sgx_cpp_fcn_id_oe_syscall_shutdown_ocall = 52, + sgx_cpp_fcn_id_oe_syscall_setsockopt_ocall = 53, + sgx_cpp_fcn_id_oe_syscall_getsockopt_ocall = 54, + sgx_cpp_fcn_id_oe_syscall_getsockname_ocall = 55, + sgx_cpp_fcn_id_oe_syscall_getpeername_ocall = 56, + sgx_cpp_fcn_id_oe_syscall_getaddrinfo_open_ocall = 57, + sgx_cpp_fcn_id_oe_syscall_getaddrinfo_read_ocall = 58, + sgx_cpp_fcn_id_oe_syscall_getaddrinfo_close_ocall = 59, + sgx_cpp_fcn_id_oe_syscall_getnameinfo_ocall = 60, + sgx_cpp_fcn_id_oe_syscall_nanosleep_ocall = 61, + sgx_cpp_fcn_id_oe_syscall_clock_nanosleep_ocall = 62, + sgx_cpp_fcn_id_oe_syscall_getpid_ocall = 63, + sgx_cpp_fcn_id_oe_syscall_getppid_ocall = 64, + sgx_cpp_fcn_id_oe_syscall_getpgrp_ocall = 65, + sgx_cpp_fcn_id_oe_syscall_getuid_ocall = 66, + sgx_cpp_fcn_id_oe_syscall_geteuid_ocall = 67, + sgx_cpp_fcn_id_oe_syscall_getgid_ocall = 68, + sgx_cpp_fcn_id_oe_syscall_getegid_ocall = 69, + sgx_cpp_fcn_id_oe_syscall_getpgid_ocall = 70, + sgx_cpp_fcn_id_oe_syscall_getgroups_ocall = 71, + sgx_cpp_fcn_id_oe_syscall_uname_ocall = 72, + sgx_cpp_fcn_id_oe_get_supported_attester_format_ids_ocall = 73, + sgx_cpp_fcn_id_oe_get_qetarget_info_ocall = 74, + sgx_cpp_fcn_id_oe_get_quote_ocall = 75, + sgx_cpp_fcn_id_oe_get_quote_verification_collateral_ocall = 76, + sgx_cpp_fcn_id_oe_verify_quote_ocall = 77, + sgx_cpp_fcn_id_oe_sgx_get_cpuid_table_ocall = 78, + sgx_cpp_fcn_id_oe_sgx_backtrace_symbols_ocall = 79, + sgx_cpp_fcn_id_oe_sgx_thread_wake_wait_ocall = 80, + sgx_cpp_fcn_id_oe_sgx_wake_switchless_worker_ocall = 81, + sgx_cpp_fcn_id_oe_sgx_sleep_switchless_worker_ocall = 82, + sgx_cpp_fcn_id_untrusted_call_max = OE_ENUM_MAX +}; + +/**** OCALL marshalling structs. ****/ +typedef struct _oe_syscall_epoll_create1_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_host_fd_t oe_retval; + int flags; + int ocall_errno; +} oe_syscall_epoll_create1_ocall_args_t; + +typedef struct _oe_syscall_epoll_wait_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + int64_t epfd; + struct oe_epoll_event* events; + unsigned int maxevents; + int timeout; + int ocall_errno; +} oe_syscall_epoll_wait_ocall_args_t; + +typedef struct _oe_syscall_epoll_wake_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + int ocall_errno; +} oe_syscall_epoll_wake_ocall_args_t; + +typedef struct _oe_syscall_epoll_ctl_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + int64_t epfd; + int op; + int64_t fd; + struct oe_epoll_event* event; + int ocall_errno; +} oe_syscall_epoll_ctl_ocall_args_t; + +typedef struct _oe_syscall_epoll_close_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t epfd; + int ocall_errno; +} oe_syscall_epoll_close_ocall_args_t; + +typedef struct _oe_syscall_open_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_host_fd_t oe_retval; + char* pathname; + size_t pathname_len; + int flags; + oe_mode_t mode; + int ocall_errno; +} oe_syscall_open_ocall_args_t; + +typedef struct _oe_syscall_read_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t fd; + void* buf; + size_t count; + int ocall_errno; +} oe_syscall_read_ocall_args_t; + +typedef struct _oe_syscall_write_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t fd; + void* buf; + size_t count; + int ocall_errno; +} oe_syscall_write_ocall_args_t; + +typedef struct _oe_syscall_readv_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t fd; + void* iov_buf; + int iovcnt; + size_t iov_buf_size; + int ocall_errno; +} oe_syscall_readv_ocall_args_t; + +typedef struct _oe_syscall_writev_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t fd; + void* iov_buf; + int iovcnt; + size_t iov_buf_size; + int ocall_errno; +} oe_syscall_writev_ocall_args_t; + +typedef struct _oe_syscall_lseek_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_off_t oe_retval; + oe_host_fd_t fd; + oe_off_t offset; + int whence; + int ocall_errno; +} oe_syscall_lseek_ocall_args_t; + +typedef struct _oe_syscall_pread_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t fd; + void* buf; + size_t count; + oe_off_t offset; + int ocall_errno; +} oe_syscall_pread_ocall_args_t; + +typedef struct _oe_syscall_pwrite_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t fd; + void* buf; + size_t count; + oe_off_t offset; + int ocall_errno; +} oe_syscall_pwrite_ocall_args_t; + +typedef struct _oe_syscall_close_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t fd; + int ocall_errno; +} oe_syscall_close_ocall_args_t; + +typedef struct _oe_syscall_flock_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t fd; + int operation; + int ocall_errno; +} oe_syscall_flock_ocall_args_t; + +typedef struct _oe_syscall_fsync_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t fd; + int ocall_errno; +} oe_syscall_fsync_ocall_args_t; + +typedef struct _oe_syscall_fdatasync_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t fd; + int ocall_errno; +} oe_syscall_fdatasync_ocall_args_t; + +typedef struct _oe_syscall_dup_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_host_fd_t oe_retval; + oe_host_fd_t oldfd; + int ocall_errno; +} oe_syscall_dup_ocall_args_t; + +typedef struct _oe_syscall_opendir_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + uint64_t oe_retval; + char* name; + size_t name_len; + int ocall_errno; +} oe_syscall_opendir_ocall_args_t; + +typedef struct _oe_syscall_readdir_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + uint64_t dirp; + struct oe_dirent* entry; + int ocall_errno; +} oe_syscall_readdir_ocall_args_t; + +typedef struct _oe_syscall_rewinddir_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + uint64_t dirp; +} oe_syscall_rewinddir_ocall_args_t; + +typedef struct _oe_syscall_closedir_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + uint64_t dirp; + int ocall_errno; +} oe_syscall_closedir_ocall_args_t; + +typedef struct _oe_syscall_stat_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + char* pathname; + size_t pathname_len; + struct oe_stat_t* buf; + int ocall_errno; +} oe_syscall_stat_ocall_args_t; + +typedef struct _oe_syscall_fstat_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t fd; + struct oe_stat_t* buf; + int ocall_errno; +} oe_syscall_fstat_ocall_args_t; + +typedef struct _oe_syscall_access_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + char* pathname; + size_t pathname_len; + int mode; + int ocall_errno; +} oe_syscall_access_ocall_args_t; + +typedef struct _oe_syscall_link_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + char* oldpath; + size_t oldpath_len; + char* newpath; + size_t newpath_len; + int ocall_errno; +} oe_syscall_link_ocall_args_t; + +typedef struct _oe_syscall_unlink_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + char* pathname; + size_t pathname_len; + int ocall_errno; +} oe_syscall_unlink_ocall_args_t; + +typedef struct _oe_syscall_rename_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + char* oldpath; + size_t oldpath_len; + char* newpath; + size_t newpath_len; + int ocall_errno; +} oe_syscall_rename_ocall_args_t; + +typedef struct _oe_syscall_truncate_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + char* path; + size_t path_len; + oe_off_t length; + int ocall_errno; +} oe_syscall_truncate_ocall_args_t; + +typedef struct _oe_syscall_ftruncate_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t fd; + oe_off_t length; + int ocall_errno; +} oe_syscall_ftruncate_ocall_args_t; + +typedef struct _oe_syscall_mkdir_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + char* pathname; + size_t pathname_len; + oe_mode_t mode; + int ocall_errno; +} oe_syscall_mkdir_ocall_args_t; + +typedef struct _oe_syscall_rmdir_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + char* pathname; + size_t pathname_len; + int ocall_errno; +} oe_syscall_rmdir_ocall_args_t; + +typedef struct _oe_syscall_fcntl_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t fd; + int cmd; + uint64_t arg; + uint64_t argsize; + void* argout; + int ocall_errno; +} oe_syscall_fcntl_ocall_args_t; + +typedef struct _oe_syscall_ioctl_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t fd; + uint64_t request; + uint64_t arg; + uint64_t argsize; + void* argout; + int ocall_errno; +} oe_syscall_ioctl_ocall_args_t; + +typedef struct _oe_syscall_poll_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + struct oe_host_pollfd* host_fds; + oe_nfds_t nfds; + int timeout; + int ocall_errno; +} oe_syscall_poll_ocall_args_t; + +typedef struct _oe_syscall_kill_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + int pid; + int signum; + int ocall_errno; +} oe_syscall_kill_ocall_args_t; + +typedef struct _oe_syscall_close_socket_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t sockfd; + int ocall_errno; +} oe_syscall_close_socket_ocall_args_t; + +typedef struct _oe_syscall_socket_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_host_fd_t oe_retval; + int domain; + int type; + int protocol; + int ocall_errno; +} oe_syscall_socket_ocall_args_t; + +typedef struct _oe_syscall_shutdown_sockets_device_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t sockfd; + int ocall_errno; +} oe_syscall_shutdown_sockets_device_ocall_args_t; + +typedef struct _oe_syscall_socketpair_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + int domain; + int type; + int protocol; + oe_host_fd_t* sv; + int ocall_errno; +} oe_syscall_socketpair_ocall_args_t; + +typedef struct _oe_syscall_connect_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t sockfd; + struct oe_sockaddr* addr; + oe_socklen_t addrlen; + int ocall_errno; +} oe_syscall_connect_ocall_args_t; + +typedef struct _oe_syscall_accept_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_host_fd_t oe_retval; + oe_host_fd_t sockfd; + struct oe_sockaddr* addr; + oe_socklen_t addrlen_in; + oe_socklen_t* addrlen_out; + int ocall_errno; +} oe_syscall_accept_ocall_args_t; + +typedef struct _oe_syscall_bind_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t sockfd; + struct oe_sockaddr* addr; + oe_socklen_t addrlen; + int ocall_errno; +} oe_syscall_bind_ocall_args_t; + +typedef struct _oe_syscall_listen_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t sockfd; + int backlog; + int ocall_errno; +} oe_syscall_listen_ocall_args_t; + +typedef struct _oe_syscall_recvmsg_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t sockfd; + void* msg_name; + oe_socklen_t msg_namelen; + oe_socklen_t* msg_namelen_out; + void* msg_iov_buf; + size_t msg_iovlen; + size_t msg_iov_buf_size; + void* msg_control; + size_t msg_controllen; + size_t* msg_controllen_out; + int flags; + int ocall_errno; +} oe_syscall_recvmsg_ocall_args_t; + +typedef struct _oe_syscall_sendmsg_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t sockfd; + void* msg_name; + oe_socklen_t msg_namelen; + void* msg_iov_buf; + size_t msg_iovlen; + size_t msg_iov_buf_size; + void* msg_control; + size_t msg_controllen; + int flags; + int ocall_errno; +} oe_syscall_sendmsg_ocall_args_t; + +typedef struct _oe_syscall_recv_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t sockfd; + void* buf; + size_t len; + int flags; + int ocall_errno; +} oe_syscall_recv_ocall_args_t; + +typedef struct _oe_syscall_recvfrom_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t sockfd; + void* buf; + size_t len; + int flags; + struct oe_sockaddr* src_addr; + oe_socklen_t addrlen_in; + oe_socklen_t* addrlen_out; + int ocall_errno; +} oe_syscall_recvfrom_ocall_args_t; + +typedef struct _oe_syscall_send_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t sockfd; + void* buf; + size_t len; + int flags; + int ocall_errno; +} oe_syscall_send_ocall_args_t; + +typedef struct _oe_syscall_sendto_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t sockfd; + void* buf; + size_t len; + int flags; + struct oe_sockaddr* dest_addr; + oe_socklen_t addrlen; + int ocall_errno; +} oe_syscall_sendto_ocall_args_t; + +typedef struct _oe_syscall_recvv_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t fd; + void* iov_buf; + int iovcnt; + size_t iov_buf_size; + int ocall_errno; +} oe_syscall_recvv_ocall_args_t; + +typedef struct _oe_syscall_sendv_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + ssize_t oe_retval; + oe_host_fd_t fd; + void* iov_buf; + int iovcnt; + size_t iov_buf_size; + int ocall_errno; +} oe_syscall_sendv_ocall_args_t; + +typedef struct _oe_syscall_shutdown_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t sockfd; + int how; + int ocall_errno; +} oe_syscall_shutdown_ocall_args_t; + +typedef struct _oe_syscall_setsockopt_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t sockfd; + int level; + int optname; + void* optval; + oe_socklen_t optlen; + int ocall_errno; +} oe_syscall_setsockopt_ocall_args_t; + +typedef struct _oe_syscall_getsockopt_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t sockfd; + int level; + int optname; + void* optval; + oe_socklen_t optlen_in; + oe_socklen_t* optlen_out; + int ocall_errno; +} oe_syscall_getsockopt_ocall_args_t; + +typedef struct _oe_syscall_getsockname_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t sockfd; + struct oe_sockaddr* addr; + oe_socklen_t addrlen_in; + oe_socklen_t* addrlen_out; + int ocall_errno; +} oe_syscall_getsockname_ocall_args_t; + +typedef struct _oe_syscall_getpeername_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_host_fd_t sockfd; + struct oe_sockaddr* addr; + oe_socklen_t addrlen_in; + oe_socklen_t* addrlen_out; + int ocall_errno; +} oe_syscall_getpeername_ocall_args_t; + +typedef struct _oe_syscall_getaddrinfo_open_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + char* node; + size_t node_len; + char* service; + size_t service_len; + struct oe_addrinfo* hints; + uint64_t* handle; + int ocall_errno; +} oe_syscall_getaddrinfo_open_ocall_args_t; + +typedef struct _oe_syscall_getaddrinfo_read_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + uint64_t handle; + int* ai_flags; + int* ai_family; + int* ai_socktype; + int* ai_protocol; + oe_socklen_t ai_addrlen_in; + oe_socklen_t* ai_addrlen; + struct oe_sockaddr* ai_addr; + size_t ai_canonnamelen_in; + size_t* ai_canonnamelen; + char* ai_canonname; + int ocall_errno; +} oe_syscall_getaddrinfo_read_ocall_args_t; + +typedef struct _oe_syscall_getaddrinfo_close_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + uint64_t handle; + int ocall_errno; +} oe_syscall_getaddrinfo_close_ocall_args_t; + +typedef struct _oe_syscall_getnameinfo_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + struct oe_sockaddr* sa; + oe_socklen_t salen; + char* host; + oe_socklen_t hostlen; + char* serv; + oe_socklen_t servlen; + int flags; + int ocall_errno; +} oe_syscall_getnameinfo_ocall_args_t; + +typedef struct _oe_syscall_nanosleep_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + struct oe_timespec* req; + struct oe_timespec* rem; + int ocall_errno; +} oe_syscall_nanosleep_ocall_args_t; + +typedef struct _oe_syscall_clock_nanosleep_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + oe_clockid_t clockid; + int flag; + struct oe_timespec* req; + struct oe_timespec* rem; + int ocall_errno; +} oe_syscall_clock_nanosleep_ocall_args_t; + +typedef struct _oe_syscall_getpid_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; +} oe_syscall_getpid_ocall_args_t; + +typedef struct _oe_syscall_getppid_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; +} oe_syscall_getppid_ocall_args_t; + +typedef struct _oe_syscall_getpgrp_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; +} oe_syscall_getpgrp_ocall_args_t; + +typedef struct _oe_syscall_getuid_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + unsigned int oe_retval; +} oe_syscall_getuid_ocall_args_t; + +typedef struct _oe_syscall_geteuid_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + unsigned int oe_retval; +} oe_syscall_geteuid_ocall_args_t; + +typedef struct _oe_syscall_getgid_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + unsigned int oe_retval; +} oe_syscall_getgid_ocall_args_t; + +typedef struct _oe_syscall_getegid_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + unsigned int oe_retval; +} oe_syscall_getegid_ocall_args_t; + +typedef struct _oe_syscall_getpgid_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + int pid; + int ocall_errno; +} oe_syscall_getpgid_ocall_args_t; + +typedef struct _oe_syscall_getgroups_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + size_t size; + unsigned int* list; + int ocall_errno; +} oe_syscall_getgroups_ocall_args_t; + +typedef struct _oe_syscall_uname_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + int oe_retval; + struct oe_utsname* buf; + int ocall_errno; +} oe_syscall_uname_ocall_args_t; + +typedef struct _oe_get_supported_attester_format_ids_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_result_t oe_retval; + format_ids_t* format_ids; +} oe_get_supported_attester_format_ids_ocall_args_t; + +typedef struct _oe_get_qetarget_info_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_result_t oe_retval; + oe_uuid_t* format_id; + void* opt_params; + size_t opt_params_size; + sgx_target_info_t* target_info; +} oe_get_qetarget_info_ocall_args_t; + +typedef struct _oe_get_quote_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_result_t oe_retval; + oe_uuid_t* format_id; + void* opt_params; + size_t opt_params_size; + sgx_report_t* sgx_report; + void* quote; + size_t quote_size; + size_t* quote_size_out; +} oe_get_quote_ocall_args_t; + +typedef struct _oe_get_quote_verification_collateral_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_result_t oe_retval; + uint8_t* fmspc; + uint8_t collateral_provider; + void* tcb_info; + size_t tcb_info_size; + size_t* tcb_info_size_out; + void* tcb_info_issuer_chain; + size_t tcb_info_issuer_chain_size; + size_t* tcb_info_issuer_chain_size_out; + void* pck_crl; + size_t pck_crl_size; + size_t* pck_crl_size_out; + void* root_ca_crl; + size_t root_ca_crl_size; + size_t* root_ca_crl_size_out; + void* pck_crl_issuer_chain; + size_t pck_crl_issuer_chain_size; + size_t* pck_crl_issuer_chain_size_out; + void* qe_identity; + size_t qe_identity_size; + size_t* qe_identity_size_out; + void* qe_identity_issuer_chain; + size_t qe_identity_issuer_chain_size; + size_t* qe_identity_issuer_chain_size_out; +} oe_get_quote_verification_collateral_ocall_args_t; + +typedef struct _oe_verify_quote_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_result_t oe_retval; + oe_uuid_t* format_id; + void* opt_params; + size_t opt_params_size; + void* p_quote; + uint32_t quote_size; + time_t expiration_check_date; + uint32_t* p_collateral_expiration_status; + uint32_t* p_quote_verification_result; + void* p_qve_report_info; + uint32_t qve_report_info_size; + void* p_supplemental_data; + uint32_t supplemental_data_size; + uint32_t* p_supplemental_data_size_out; + uint32_t collateral_version; + void* p_tcb_info; + uint32_t tcb_info_size; + void* p_tcb_info_issuer_chain; + uint32_t tcb_info_issuer_chain_size; + void* p_pck_crl; + uint32_t pck_crl_size; + void* p_root_ca_crl; + uint32_t root_ca_crl_size; + void* p_pck_crl_issuer_chain; + uint32_t pck_crl_issuer_chain_size; + void* p_qe_identity; + uint32_t qe_identity_size; + void* p_qe_identity_issuer_chain; + uint32_t qe_identity_issuer_chain_size; +} oe_verify_quote_ocall_args_t; + +typedef struct _oe_sgx_get_cpuid_table_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_result_t oe_retval; + void* cpuid_table_buffer; + size_t cpuid_table_buffer_size; +} oe_sgx_get_cpuid_table_ocall_args_t; + +typedef struct _oe_sgx_backtrace_symbols_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_result_t oe_retval; + oe_enclave_t* oe_enclave; + uint64_t* buffer; + size_t size; + void* symbols_buffer; + size_t symbols_buffer_size; + size_t* symbols_buffer_size_out; +} oe_sgx_backtrace_symbols_ocall_args_t; + +typedef struct _oe_sgx_thread_wake_wait_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_enclave_t* oe_enclave; + uint64_t waiter_tcs; + uint64_t self_tcs; +} oe_sgx_thread_wake_wait_ocall_args_t; + +typedef struct _oe_sgx_wake_switchless_worker_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_host_worker_context_t* context; +} oe_sgx_wake_switchless_worker_ocall_args_t; + +typedef struct _oe_sgx_sleep_switchless_worker_ocall_args_t +{ + oe_result_t oe_result; + uint8_t* deepcopy_out_buffer; + size_t deepcopy_out_buffer_size; + oe_enclave_worker_context_t* context; +} oe_sgx_sleep_switchless_worker_ocall_args_t; + +/**** OCALL functions. ****/ + +static void ocall_oe_syscall_epoll_create1_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_epoll_create1_ocall_args_t* _pargs_in = (oe_syscall_epoll_create1_ocall_args_t*)input_buffer; + oe_syscall_epoll_create1_ocall_args_t* _pargs_out = (oe_syscall_epoll_create1_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_epoll_create1_ocall( + _pargs_in->flags); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_epoll_wait_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_epoll_wait_ocall_args_t* _pargs_in = (oe_syscall_epoll_wait_ocall_args_t*)input_buffer; + oe_syscall_epoll_wait_ocall_args_t* _pargs_out = (oe_syscall_epoll_wait_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->events) + OE_SET_OUT_POINTER(events, _pargs_in->maxevents, sizeof(struct oe_epoll_event), struct oe_epoll_event*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_epoll_wait_ocall( + _pargs_in->epfd, + _pargs_in->events, + _pargs_in->maxevents, + _pargs_in->timeout); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_epoll_wake_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_epoll_wake_ocall_args_t* _pargs_in = (oe_syscall_epoll_wake_ocall_args_t*)input_buffer; + oe_syscall_epoll_wake_ocall_args_t* _pargs_out = (oe_syscall_epoll_wake_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_epoll_wake_ocall( + ); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_epoll_ctl_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_epoll_ctl_ocall_args_t* _pargs_in = (oe_syscall_epoll_ctl_ocall_args_t*)input_buffer; + oe_syscall_epoll_ctl_ocall_args_t* _pargs_out = (oe_syscall_epoll_ctl_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->event) + OE_SET_IN_POINTER(event, 1, sizeof(struct oe_epoll_event), struct oe_epoll_event*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_epoll_ctl_ocall( + _pargs_in->epfd, + _pargs_in->op, + _pargs_in->fd, + _pargs_in->event); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_epoll_close_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_epoll_close_ocall_args_t* _pargs_in = (oe_syscall_epoll_close_ocall_args_t*)input_buffer; + oe_syscall_epoll_close_ocall_args_t* _pargs_out = (oe_syscall_epoll_close_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_epoll_close_ocall( + _pargs_in->epfd); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_open_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_open_ocall_args_t* _pargs_in = (oe_syscall_open_ocall_args_t*)input_buffer; + oe_syscall_open_ocall_args_t* _pargs_out = (oe_syscall_open_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->pathname) + OE_SET_IN_POINTER(pathname, _pargs_in->pathname_len, sizeof(char), char*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_open_ocall( + (const char*)_pargs_in->pathname, + _pargs_in->flags, + _pargs_in->mode); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_read_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_read_ocall_args_t* _pargs_in = (oe_syscall_read_ocall_args_t*)input_buffer; + oe_syscall_read_ocall_args_t* _pargs_out = (oe_syscall_read_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->buf) + OE_SET_OUT_POINTER(buf, 1, _pargs_in->count, void*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_read_ocall( + _pargs_in->fd, + _pargs_in->buf, + _pargs_in->count); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_write_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_write_ocall_args_t* _pargs_in = (oe_syscall_write_ocall_args_t*)input_buffer; + oe_syscall_write_ocall_args_t* _pargs_out = (oe_syscall_write_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->buf) + OE_SET_IN_POINTER(buf, 1, _pargs_in->count, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_write_ocall( + _pargs_in->fd, + (const void*)_pargs_in->buf, + _pargs_in->count); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_readv_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_readv_ocall_args_t* _pargs_in = (oe_syscall_readv_ocall_args_t*)input_buffer; + oe_syscall_readv_ocall_args_t* _pargs_out = (oe_syscall_readv_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->iov_buf) + OE_SET_IN_OUT_POINTER(iov_buf, 1, _pargs_in->iov_buf_size, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->iov_buf) + OE_COPY_AND_SET_IN_OUT_POINTER(iov_buf, 1, _pargs_in->iov_buf_size, void*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_readv_ocall( + _pargs_in->fd, + _pargs_in->iov_buf, + _pargs_in->iovcnt, + _pargs_in->iov_buf_size); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_writev_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_writev_ocall_args_t* _pargs_in = (oe_syscall_writev_ocall_args_t*)input_buffer; + oe_syscall_writev_ocall_args_t* _pargs_out = (oe_syscall_writev_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->iov_buf) + OE_SET_IN_POINTER(iov_buf, 1, _pargs_in->iov_buf_size, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_writev_ocall( + _pargs_in->fd, + (const void*)_pargs_in->iov_buf, + _pargs_in->iovcnt, + _pargs_in->iov_buf_size); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_lseek_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_lseek_ocall_args_t* _pargs_in = (oe_syscall_lseek_ocall_args_t*)input_buffer; + oe_syscall_lseek_ocall_args_t* _pargs_out = (oe_syscall_lseek_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_lseek_ocall( + _pargs_in->fd, + _pargs_in->offset, + _pargs_in->whence); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_pread_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_pread_ocall_args_t* _pargs_in = (oe_syscall_pread_ocall_args_t*)input_buffer; + oe_syscall_pread_ocall_args_t* _pargs_out = (oe_syscall_pread_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->buf) + OE_SET_OUT_POINTER(buf, 1, _pargs_in->count, void*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_pread_ocall( + _pargs_in->fd, + _pargs_in->buf, + _pargs_in->count, + _pargs_in->offset); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_pwrite_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_pwrite_ocall_args_t* _pargs_in = (oe_syscall_pwrite_ocall_args_t*)input_buffer; + oe_syscall_pwrite_ocall_args_t* _pargs_out = (oe_syscall_pwrite_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->buf) + OE_SET_IN_POINTER(buf, 1, _pargs_in->count, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_pwrite_ocall( + _pargs_in->fd, + (const void*)_pargs_in->buf, + _pargs_in->count, + _pargs_in->offset); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_close_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_close_ocall_args_t* _pargs_in = (oe_syscall_close_ocall_args_t*)input_buffer; + oe_syscall_close_ocall_args_t* _pargs_out = (oe_syscall_close_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_close_ocall( + _pargs_in->fd); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_flock_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_flock_ocall_args_t* _pargs_in = (oe_syscall_flock_ocall_args_t*)input_buffer; + oe_syscall_flock_ocall_args_t* _pargs_out = (oe_syscall_flock_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_flock_ocall( + _pargs_in->fd, + _pargs_in->operation); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_fsync_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_fsync_ocall_args_t* _pargs_in = (oe_syscall_fsync_ocall_args_t*)input_buffer; + oe_syscall_fsync_ocall_args_t* _pargs_out = (oe_syscall_fsync_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_fsync_ocall( + _pargs_in->fd); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_fdatasync_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_fdatasync_ocall_args_t* _pargs_in = (oe_syscall_fdatasync_ocall_args_t*)input_buffer; + oe_syscall_fdatasync_ocall_args_t* _pargs_out = (oe_syscall_fdatasync_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_fdatasync_ocall( + _pargs_in->fd); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_dup_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_dup_ocall_args_t* _pargs_in = (oe_syscall_dup_ocall_args_t*)input_buffer; + oe_syscall_dup_ocall_args_t* _pargs_out = (oe_syscall_dup_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_dup_ocall( + _pargs_in->oldfd); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_opendir_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_opendir_ocall_args_t* _pargs_in = (oe_syscall_opendir_ocall_args_t*)input_buffer; + oe_syscall_opendir_ocall_args_t* _pargs_out = (oe_syscall_opendir_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->name) + OE_SET_IN_POINTER(name, _pargs_in->name_len, sizeof(char), char*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_opendir_ocall( + (const char*)_pargs_in->name); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_readdir_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_readdir_ocall_args_t* _pargs_in = (oe_syscall_readdir_ocall_args_t*)input_buffer; + oe_syscall_readdir_ocall_args_t* _pargs_out = (oe_syscall_readdir_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->entry) + OE_SET_OUT_POINTER(entry, 1, sizeof(struct oe_dirent), struct oe_dirent*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_readdir_ocall( + _pargs_in->dirp, + _pargs_in->entry); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_rewinddir_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_rewinddir_ocall_args_t* _pargs_in = (oe_syscall_rewinddir_ocall_args_t*)input_buffer; + oe_syscall_rewinddir_ocall_args_t* _pargs_out = (oe_syscall_rewinddir_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + oe_syscall_rewinddir_ocall( + _pargs_in->dirp); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_closedir_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_closedir_ocall_args_t* _pargs_in = (oe_syscall_closedir_ocall_args_t*)input_buffer; + oe_syscall_closedir_ocall_args_t* _pargs_out = (oe_syscall_closedir_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_closedir_ocall( + _pargs_in->dirp); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_stat_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_stat_ocall_args_t* _pargs_in = (oe_syscall_stat_ocall_args_t*)input_buffer; + oe_syscall_stat_ocall_args_t* _pargs_out = (oe_syscall_stat_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->pathname) + OE_SET_IN_POINTER(pathname, _pargs_in->pathname_len, sizeof(char), char*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->buf) + OE_SET_OUT_POINTER(buf, 1, sizeof(struct oe_stat_t), struct oe_stat_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_stat_ocall( + (const char*)_pargs_in->pathname, + _pargs_in->buf); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_fstat_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_fstat_ocall_args_t* _pargs_in = (oe_syscall_fstat_ocall_args_t*)input_buffer; + oe_syscall_fstat_ocall_args_t* _pargs_out = (oe_syscall_fstat_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->buf) + OE_SET_OUT_POINTER(buf, 1, sizeof(struct oe_stat_t), struct oe_stat_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_fstat_ocall( + _pargs_in->fd, + _pargs_in->buf); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_access_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_access_ocall_args_t* _pargs_in = (oe_syscall_access_ocall_args_t*)input_buffer; + oe_syscall_access_ocall_args_t* _pargs_out = (oe_syscall_access_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->pathname) + OE_SET_IN_POINTER(pathname, _pargs_in->pathname_len, sizeof(char), char*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_access_ocall( + (const char*)_pargs_in->pathname, + _pargs_in->mode); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_link_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_link_ocall_args_t* _pargs_in = (oe_syscall_link_ocall_args_t*)input_buffer; + oe_syscall_link_ocall_args_t* _pargs_out = (oe_syscall_link_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->oldpath) + OE_SET_IN_POINTER(oldpath, _pargs_in->oldpath_len, sizeof(char), char*); + if (_pargs_in->newpath) + OE_SET_IN_POINTER(newpath, _pargs_in->newpath_len, sizeof(char), char*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_link_ocall( + (const char*)_pargs_in->oldpath, + (const char*)_pargs_in->newpath); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_unlink_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_unlink_ocall_args_t* _pargs_in = (oe_syscall_unlink_ocall_args_t*)input_buffer; + oe_syscall_unlink_ocall_args_t* _pargs_out = (oe_syscall_unlink_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->pathname) + OE_SET_IN_POINTER(pathname, _pargs_in->pathname_len, sizeof(char), char*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_unlink_ocall( + (const char*)_pargs_in->pathname); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_rename_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_rename_ocall_args_t* _pargs_in = (oe_syscall_rename_ocall_args_t*)input_buffer; + oe_syscall_rename_ocall_args_t* _pargs_out = (oe_syscall_rename_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->oldpath) + OE_SET_IN_POINTER(oldpath, _pargs_in->oldpath_len, sizeof(char), char*); + if (_pargs_in->newpath) + OE_SET_IN_POINTER(newpath, _pargs_in->newpath_len, sizeof(char), char*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_rename_ocall( + (const char*)_pargs_in->oldpath, + (const char*)_pargs_in->newpath); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_truncate_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_truncate_ocall_args_t* _pargs_in = (oe_syscall_truncate_ocall_args_t*)input_buffer; + oe_syscall_truncate_ocall_args_t* _pargs_out = (oe_syscall_truncate_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->path) + OE_SET_IN_POINTER(path, _pargs_in->path_len, sizeof(char), char*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_truncate_ocall( + (const char*)_pargs_in->path, + _pargs_in->length); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_ftruncate_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_ftruncate_ocall_args_t* _pargs_in = (oe_syscall_ftruncate_ocall_args_t*)input_buffer; + oe_syscall_ftruncate_ocall_args_t* _pargs_out = (oe_syscall_ftruncate_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_ftruncate_ocall( + _pargs_in->fd, + _pargs_in->length); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_mkdir_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_mkdir_ocall_args_t* _pargs_in = (oe_syscall_mkdir_ocall_args_t*)input_buffer; + oe_syscall_mkdir_ocall_args_t* _pargs_out = (oe_syscall_mkdir_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->pathname) + OE_SET_IN_POINTER(pathname, _pargs_in->pathname_len, sizeof(char), char*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_mkdir_ocall( + (const char*)_pargs_in->pathname, + _pargs_in->mode); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_rmdir_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_rmdir_ocall_args_t* _pargs_in = (oe_syscall_rmdir_ocall_args_t*)input_buffer; + oe_syscall_rmdir_ocall_args_t* _pargs_out = (oe_syscall_rmdir_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->pathname) + OE_SET_IN_POINTER(pathname, _pargs_in->pathname_len, sizeof(char), char*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_rmdir_ocall( + (const char*)_pargs_in->pathname); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_fcntl_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_fcntl_ocall_args_t* _pargs_in = (oe_syscall_fcntl_ocall_args_t*)input_buffer; + oe_syscall_fcntl_ocall_args_t* _pargs_out = (oe_syscall_fcntl_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->argout) + OE_SET_IN_OUT_POINTER(argout, 1, _pargs_in->argsize, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->argout) + OE_COPY_AND_SET_IN_OUT_POINTER(argout, 1, _pargs_in->argsize, void*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_fcntl_ocall( + _pargs_in->fd, + _pargs_in->cmd, + _pargs_in->arg, + _pargs_in->argsize, + _pargs_in->argout); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_ioctl_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_ioctl_ocall_args_t* _pargs_in = (oe_syscall_ioctl_ocall_args_t*)input_buffer; + oe_syscall_ioctl_ocall_args_t* _pargs_out = (oe_syscall_ioctl_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->argout) + OE_SET_IN_OUT_POINTER(argout, 1, _pargs_in->argsize, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->argout) + OE_COPY_AND_SET_IN_OUT_POINTER(argout, 1, _pargs_in->argsize, void*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_ioctl_ocall( + _pargs_in->fd, + _pargs_in->request, + _pargs_in->arg, + _pargs_in->argsize, + _pargs_in->argout); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_poll_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_poll_ocall_args_t* _pargs_in = (oe_syscall_poll_ocall_args_t*)input_buffer; + oe_syscall_poll_ocall_args_t* _pargs_out = (oe_syscall_poll_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->host_fds) + OE_SET_IN_OUT_POINTER(host_fds, _pargs_in->nfds, sizeof(struct oe_host_pollfd), struct oe_host_pollfd*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->host_fds) + OE_COPY_AND_SET_IN_OUT_POINTER(host_fds, _pargs_in->nfds, sizeof(struct oe_host_pollfd), struct oe_host_pollfd*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_poll_ocall( + _pargs_in->host_fds, + _pargs_in->nfds, + _pargs_in->timeout); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_kill_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_kill_ocall_args_t* _pargs_in = (oe_syscall_kill_ocall_args_t*)input_buffer; + oe_syscall_kill_ocall_args_t* _pargs_out = (oe_syscall_kill_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_kill_ocall( + _pargs_in->pid, + _pargs_in->signum); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_close_socket_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_close_socket_ocall_args_t* _pargs_in = (oe_syscall_close_socket_ocall_args_t*)input_buffer; + oe_syscall_close_socket_ocall_args_t* _pargs_out = (oe_syscall_close_socket_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_close_socket_ocall( + _pargs_in->sockfd); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_socket_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_socket_ocall_args_t* _pargs_in = (oe_syscall_socket_ocall_args_t*)input_buffer; + oe_syscall_socket_ocall_args_t* _pargs_out = (oe_syscall_socket_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_socket_ocall( + _pargs_in->domain, + _pargs_in->type, + _pargs_in->protocol); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_shutdown_sockets_device_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_shutdown_sockets_device_ocall_args_t* _pargs_in = (oe_syscall_shutdown_sockets_device_ocall_args_t*)input_buffer; + oe_syscall_shutdown_sockets_device_ocall_args_t* _pargs_out = (oe_syscall_shutdown_sockets_device_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_shutdown_sockets_device_ocall( + _pargs_in->sockfd); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_socketpair_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_socketpair_ocall_args_t* _pargs_in = (oe_syscall_socketpair_ocall_args_t*)input_buffer; + oe_syscall_socketpair_ocall_args_t* _pargs_out = (oe_syscall_socketpair_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->sv) + OE_SET_OUT_POINTER(sv, 1, sizeof(oe_host_fd_t[2]), oe_host_fd_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_socketpair_ocall( + _pargs_in->domain, + _pargs_in->type, + _pargs_in->protocol, + *(oe_host_fd_t(*)[2])_pargs_in->sv); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_connect_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_connect_ocall_args_t* _pargs_in = (oe_syscall_connect_ocall_args_t*)input_buffer; + oe_syscall_connect_ocall_args_t* _pargs_out = (oe_syscall_connect_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->addr) + OE_SET_IN_POINTER(addr, 1, _pargs_in->addrlen, struct oe_sockaddr*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_connect_ocall( + _pargs_in->sockfd, + (const struct oe_sockaddr*)_pargs_in->addr, + _pargs_in->addrlen); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_accept_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_accept_ocall_args_t* _pargs_in = (oe_syscall_accept_ocall_args_t*)input_buffer; + oe_syscall_accept_ocall_args_t* _pargs_out = (oe_syscall_accept_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->addr) + OE_SET_OUT_POINTER(addr, 1, _pargs_in->addrlen_in, struct oe_sockaddr*); + if (_pargs_in->addrlen_out) + OE_SET_OUT_POINTER(addrlen_out, 1, sizeof(oe_socklen_t), oe_socklen_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_accept_ocall( + _pargs_in->sockfd, + _pargs_in->addr, + _pargs_in->addrlen_in, + _pargs_in->addrlen_out); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_bind_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_bind_ocall_args_t* _pargs_in = (oe_syscall_bind_ocall_args_t*)input_buffer; + oe_syscall_bind_ocall_args_t* _pargs_out = (oe_syscall_bind_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->addr) + OE_SET_IN_POINTER(addr, 1, _pargs_in->addrlen, struct oe_sockaddr*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_bind_ocall( + _pargs_in->sockfd, + (const struct oe_sockaddr*)_pargs_in->addr, + _pargs_in->addrlen); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_listen_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_listen_ocall_args_t* _pargs_in = (oe_syscall_listen_ocall_args_t*)input_buffer; + oe_syscall_listen_ocall_args_t* _pargs_out = (oe_syscall_listen_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_listen_ocall( + _pargs_in->sockfd, + _pargs_in->backlog); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_recvmsg_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_recvmsg_ocall_args_t* _pargs_in = (oe_syscall_recvmsg_ocall_args_t*)input_buffer; + oe_syscall_recvmsg_ocall_args_t* _pargs_out = (oe_syscall_recvmsg_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->msg_iov_buf) + OE_SET_IN_OUT_POINTER(msg_iov_buf, 1, _pargs_in->msg_iov_buf_size, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->msg_name) + OE_SET_OUT_POINTER(msg_name, 1, _pargs_in->msg_namelen, void*); + if (_pargs_in->msg_namelen_out) + OE_SET_OUT_POINTER(msg_namelen_out, 1, sizeof(oe_socklen_t), oe_socklen_t*); + if (_pargs_in->msg_iov_buf) + OE_COPY_AND_SET_IN_OUT_POINTER(msg_iov_buf, 1, _pargs_in->msg_iov_buf_size, void*); + if (_pargs_in->msg_control) + OE_SET_OUT_POINTER(msg_control, 1, _pargs_in->msg_controllen, void*); + if (_pargs_in->msg_controllen_out) + OE_SET_OUT_POINTER(msg_controllen_out, 1, sizeof(size_t), size_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_recvmsg_ocall( + _pargs_in->sockfd, + _pargs_in->msg_name, + _pargs_in->msg_namelen, + _pargs_in->msg_namelen_out, + _pargs_in->msg_iov_buf, + _pargs_in->msg_iovlen, + _pargs_in->msg_iov_buf_size, + _pargs_in->msg_control, + _pargs_in->msg_controllen, + _pargs_in->msg_controllen_out, + _pargs_in->flags); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_sendmsg_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_sendmsg_ocall_args_t* _pargs_in = (oe_syscall_sendmsg_ocall_args_t*)input_buffer; + oe_syscall_sendmsg_ocall_args_t* _pargs_out = (oe_syscall_sendmsg_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->msg_name) + OE_SET_IN_POINTER(msg_name, 1, _pargs_in->msg_namelen, void*); + if (_pargs_in->msg_iov_buf) + OE_SET_IN_POINTER(msg_iov_buf, 1, _pargs_in->msg_iov_buf_size, void*); + if (_pargs_in->msg_control) + OE_SET_IN_POINTER(msg_control, 1, _pargs_in->msg_controllen, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_sendmsg_ocall( + _pargs_in->sockfd, + (const void*)_pargs_in->msg_name, + _pargs_in->msg_namelen, + _pargs_in->msg_iov_buf, + _pargs_in->msg_iovlen, + _pargs_in->msg_iov_buf_size, + (const void*)_pargs_in->msg_control, + _pargs_in->msg_controllen, + _pargs_in->flags); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_recv_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_recv_ocall_args_t* _pargs_in = (oe_syscall_recv_ocall_args_t*)input_buffer; + oe_syscall_recv_ocall_args_t* _pargs_out = (oe_syscall_recv_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->buf) + OE_SET_OUT_POINTER(buf, 1, _pargs_in->len, void*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_recv_ocall( + _pargs_in->sockfd, + _pargs_in->buf, + _pargs_in->len, + _pargs_in->flags); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_recvfrom_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_recvfrom_ocall_args_t* _pargs_in = (oe_syscall_recvfrom_ocall_args_t*)input_buffer; + oe_syscall_recvfrom_ocall_args_t* _pargs_out = (oe_syscall_recvfrom_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->buf) + OE_SET_OUT_POINTER(buf, 1, _pargs_in->len, void*); + if (_pargs_in->src_addr) + OE_SET_OUT_POINTER(src_addr, 1, _pargs_in->addrlen_in, struct oe_sockaddr*); + if (_pargs_in->addrlen_out) + OE_SET_OUT_POINTER(addrlen_out, 1, sizeof(oe_socklen_t), oe_socklen_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_recvfrom_ocall( + _pargs_in->sockfd, + _pargs_in->buf, + _pargs_in->len, + _pargs_in->flags, + _pargs_in->src_addr, + _pargs_in->addrlen_in, + _pargs_in->addrlen_out); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_send_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_send_ocall_args_t* _pargs_in = (oe_syscall_send_ocall_args_t*)input_buffer; + oe_syscall_send_ocall_args_t* _pargs_out = (oe_syscall_send_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->buf) + OE_SET_IN_POINTER(buf, 1, _pargs_in->len, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_send_ocall( + _pargs_in->sockfd, + (const void*)_pargs_in->buf, + _pargs_in->len, + _pargs_in->flags); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_sendto_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_sendto_ocall_args_t* _pargs_in = (oe_syscall_sendto_ocall_args_t*)input_buffer; + oe_syscall_sendto_ocall_args_t* _pargs_out = (oe_syscall_sendto_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->buf) + OE_SET_IN_POINTER(buf, 1, _pargs_in->len, void*); + if (_pargs_in->dest_addr) + OE_SET_IN_POINTER(dest_addr, 1, _pargs_in->addrlen, struct oe_sockaddr*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_sendto_ocall( + _pargs_in->sockfd, + (const void*)_pargs_in->buf, + _pargs_in->len, + _pargs_in->flags, + (const struct oe_sockaddr*)_pargs_in->dest_addr, + _pargs_in->addrlen); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_recvv_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_recvv_ocall_args_t* _pargs_in = (oe_syscall_recvv_ocall_args_t*)input_buffer; + oe_syscall_recvv_ocall_args_t* _pargs_out = (oe_syscall_recvv_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->iov_buf) + OE_SET_IN_OUT_POINTER(iov_buf, 1, _pargs_in->iov_buf_size, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->iov_buf) + OE_COPY_AND_SET_IN_OUT_POINTER(iov_buf, 1, _pargs_in->iov_buf_size, void*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_recvv_ocall( + _pargs_in->fd, + _pargs_in->iov_buf, + _pargs_in->iovcnt, + _pargs_in->iov_buf_size); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_sendv_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_sendv_ocall_args_t* _pargs_in = (oe_syscall_sendv_ocall_args_t*)input_buffer; + oe_syscall_sendv_ocall_args_t* _pargs_out = (oe_syscall_sendv_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->iov_buf) + OE_SET_IN_POINTER(iov_buf, 1, _pargs_in->iov_buf_size, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_sendv_ocall( + _pargs_in->fd, + (const void*)_pargs_in->iov_buf, + _pargs_in->iovcnt, + _pargs_in->iov_buf_size); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_shutdown_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_shutdown_ocall_args_t* _pargs_in = (oe_syscall_shutdown_ocall_args_t*)input_buffer; + oe_syscall_shutdown_ocall_args_t* _pargs_out = (oe_syscall_shutdown_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_shutdown_ocall( + _pargs_in->sockfd, + _pargs_in->how); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_setsockopt_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_setsockopt_ocall_args_t* _pargs_in = (oe_syscall_setsockopt_ocall_args_t*)input_buffer; + oe_syscall_setsockopt_ocall_args_t* _pargs_out = (oe_syscall_setsockopt_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->optval) + OE_SET_IN_POINTER(optval, 1, _pargs_in->optlen, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_setsockopt_ocall( + _pargs_in->sockfd, + _pargs_in->level, + _pargs_in->optname, + (const void*)_pargs_in->optval, + _pargs_in->optlen); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getsockopt_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getsockopt_ocall_args_t* _pargs_in = (oe_syscall_getsockopt_ocall_args_t*)input_buffer; + oe_syscall_getsockopt_ocall_args_t* _pargs_out = (oe_syscall_getsockopt_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->optval) + OE_SET_OUT_POINTER(optval, 1, _pargs_in->optlen_in, void*); + if (_pargs_in->optlen_out) + OE_SET_OUT_POINTER(optlen_out, 1, sizeof(oe_socklen_t), oe_socklen_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getsockopt_ocall( + _pargs_in->sockfd, + _pargs_in->level, + _pargs_in->optname, + _pargs_in->optval, + _pargs_in->optlen_in, + _pargs_in->optlen_out); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getsockname_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getsockname_ocall_args_t* _pargs_in = (oe_syscall_getsockname_ocall_args_t*)input_buffer; + oe_syscall_getsockname_ocall_args_t* _pargs_out = (oe_syscall_getsockname_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->addr) + OE_SET_OUT_POINTER(addr, 1, _pargs_in->addrlen_in, struct oe_sockaddr*); + if (_pargs_in->addrlen_out) + OE_SET_OUT_POINTER(addrlen_out, 1, 1, oe_socklen_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getsockname_ocall( + _pargs_in->sockfd, + _pargs_in->addr, + _pargs_in->addrlen_in, + _pargs_in->addrlen_out); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getpeername_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getpeername_ocall_args_t* _pargs_in = (oe_syscall_getpeername_ocall_args_t*)input_buffer; + oe_syscall_getpeername_ocall_args_t* _pargs_out = (oe_syscall_getpeername_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->addr) + OE_SET_OUT_POINTER(addr, 1, _pargs_in->addrlen_in, struct oe_sockaddr*); + if (_pargs_in->addrlen_out) + OE_SET_OUT_POINTER(addrlen_out, 1, 1, oe_socklen_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getpeername_ocall( + _pargs_in->sockfd, + _pargs_in->addr, + _pargs_in->addrlen_in, + _pargs_in->addrlen_out); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getaddrinfo_open_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getaddrinfo_open_ocall_args_t* _pargs_in = (oe_syscall_getaddrinfo_open_ocall_args_t*)input_buffer; + oe_syscall_getaddrinfo_open_ocall_args_t* _pargs_out = (oe_syscall_getaddrinfo_open_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->node) + OE_SET_IN_POINTER(node, _pargs_in->node_len, sizeof(char), char*); + if (_pargs_in->service) + OE_SET_IN_POINTER(service, _pargs_in->service_len, sizeof(char), char*); + if (_pargs_in->hints) + OE_SET_IN_POINTER(hints, 1, sizeof(struct oe_addrinfo), struct oe_addrinfo*); + if (_pargs_in->hints && _pargs_in->hints->ai_addr) + OE_SET_IN_POINTER(hints->ai_addr, 1, _pargs_in->hints->ai_addrlen, struct oe_sockaddr*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->handle) + OE_SET_OUT_POINTER(handle, 1, sizeof(uint64_t), uint64_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getaddrinfo_open_ocall( + (const char*)_pargs_in->node, + (const char*)_pargs_in->service, + (const struct oe_addrinfo*)_pargs_in->hints, + _pargs_in->handle); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getaddrinfo_read_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getaddrinfo_read_ocall_args_t* _pargs_in = (oe_syscall_getaddrinfo_read_ocall_args_t*)input_buffer; + oe_syscall_getaddrinfo_read_ocall_args_t* _pargs_out = (oe_syscall_getaddrinfo_read_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->ai_flags) + OE_SET_OUT_POINTER(ai_flags, 1, sizeof(int), int*); + if (_pargs_in->ai_family) + OE_SET_OUT_POINTER(ai_family, 1, sizeof(int), int*); + if (_pargs_in->ai_socktype) + OE_SET_OUT_POINTER(ai_socktype, 1, sizeof(int), int*); + if (_pargs_in->ai_protocol) + OE_SET_OUT_POINTER(ai_protocol, 1, sizeof(int), int*); + if (_pargs_in->ai_addrlen) + OE_SET_OUT_POINTER(ai_addrlen, 1, sizeof(oe_socklen_t), oe_socklen_t*); + if (_pargs_in->ai_addr) + OE_SET_OUT_POINTER(ai_addr, 1, _pargs_in->ai_addrlen_in, struct oe_sockaddr*); + if (_pargs_in->ai_canonnamelen) + OE_SET_OUT_POINTER(ai_canonnamelen, 1, sizeof(size_t), size_t*); + if (_pargs_in->ai_canonname) + OE_SET_OUT_POINTER(ai_canonname, 1, _pargs_in->ai_canonnamelen_in, char*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getaddrinfo_read_ocall( + _pargs_in->handle, + _pargs_in->ai_flags, + _pargs_in->ai_family, + _pargs_in->ai_socktype, + _pargs_in->ai_protocol, + _pargs_in->ai_addrlen_in, + _pargs_in->ai_addrlen, + _pargs_in->ai_addr, + _pargs_in->ai_canonnamelen_in, + _pargs_in->ai_canonnamelen, + _pargs_in->ai_canonname); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getaddrinfo_close_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getaddrinfo_close_ocall_args_t* _pargs_in = (oe_syscall_getaddrinfo_close_ocall_args_t*)input_buffer; + oe_syscall_getaddrinfo_close_ocall_args_t* _pargs_out = (oe_syscall_getaddrinfo_close_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getaddrinfo_close_ocall( + _pargs_in->handle); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getnameinfo_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getnameinfo_ocall_args_t* _pargs_in = (oe_syscall_getnameinfo_ocall_args_t*)input_buffer; + oe_syscall_getnameinfo_ocall_args_t* _pargs_out = (oe_syscall_getnameinfo_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->sa) + OE_SET_IN_POINTER(sa, 1, _pargs_in->salen, struct oe_sockaddr*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->host) + OE_SET_OUT_POINTER(host, 1, _pargs_in->hostlen, char*); + if (_pargs_in->serv) + OE_SET_OUT_POINTER(serv, 1, _pargs_in->servlen, char*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getnameinfo_ocall( + (const struct oe_sockaddr*)_pargs_in->sa, + _pargs_in->salen, + _pargs_in->host, + _pargs_in->hostlen, + _pargs_in->serv, + _pargs_in->servlen, + _pargs_in->flags); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_nanosleep_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_nanosleep_ocall_args_t* _pargs_in = (oe_syscall_nanosleep_ocall_args_t*)input_buffer; + oe_syscall_nanosleep_ocall_args_t* _pargs_out = (oe_syscall_nanosleep_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->req) + OE_SET_IN_POINTER(req, 1, sizeof(struct oe_timespec), struct oe_timespec*); + if (_pargs_in->rem) + OE_SET_IN_OUT_POINTER(rem, 1, sizeof(struct oe_timespec), struct oe_timespec*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->rem) + OE_COPY_AND_SET_IN_OUT_POINTER(rem, 1, sizeof(struct oe_timespec), struct oe_timespec*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_nanosleep_ocall( + _pargs_in->req, + _pargs_in->rem); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_clock_nanosleep_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_clock_nanosleep_ocall_args_t* _pargs_in = (oe_syscall_clock_nanosleep_ocall_args_t*)input_buffer; + oe_syscall_clock_nanosleep_ocall_args_t* _pargs_out = (oe_syscall_clock_nanosleep_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->req) + OE_SET_IN_POINTER(req, 1, sizeof(struct oe_timespec), struct oe_timespec*); + if (_pargs_in->rem) + OE_SET_IN_OUT_POINTER(rem, 1, sizeof(struct oe_timespec), struct oe_timespec*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->rem) + OE_COPY_AND_SET_IN_OUT_POINTER(rem, 1, sizeof(struct oe_timespec), struct oe_timespec*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_clock_nanosleep_ocall( + _pargs_in->clockid, + _pargs_in->flag, + _pargs_in->req, + _pargs_in->rem); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getpid_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getpid_ocall_args_t* _pargs_in = (oe_syscall_getpid_ocall_args_t*)input_buffer; + oe_syscall_getpid_ocall_args_t* _pargs_out = (oe_syscall_getpid_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getpid_ocall( + ); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getppid_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getppid_ocall_args_t* _pargs_in = (oe_syscall_getppid_ocall_args_t*)input_buffer; + oe_syscall_getppid_ocall_args_t* _pargs_out = (oe_syscall_getppid_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getppid_ocall( + ); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getpgrp_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getpgrp_ocall_args_t* _pargs_in = (oe_syscall_getpgrp_ocall_args_t*)input_buffer; + oe_syscall_getpgrp_ocall_args_t* _pargs_out = (oe_syscall_getpgrp_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getpgrp_ocall( + ); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getuid_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getuid_ocall_args_t* _pargs_in = (oe_syscall_getuid_ocall_args_t*)input_buffer; + oe_syscall_getuid_ocall_args_t* _pargs_out = (oe_syscall_getuid_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getuid_ocall( + ); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_geteuid_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_geteuid_ocall_args_t* _pargs_in = (oe_syscall_geteuid_ocall_args_t*)input_buffer; + oe_syscall_geteuid_ocall_args_t* _pargs_out = (oe_syscall_geteuid_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_geteuid_ocall( + ); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getgid_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getgid_ocall_args_t* _pargs_in = (oe_syscall_getgid_ocall_args_t*)input_buffer; + oe_syscall_getgid_ocall_args_t* _pargs_out = (oe_syscall_getgid_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getgid_ocall( + ); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getegid_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getegid_ocall_args_t* _pargs_in = (oe_syscall_getegid_ocall_args_t*)input_buffer; + oe_syscall_getegid_ocall_args_t* _pargs_out = (oe_syscall_getegid_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getegid_ocall( + ); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getpgid_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getpgid_ocall_args_t* _pargs_in = (oe_syscall_getpgid_ocall_args_t*)input_buffer; + oe_syscall_getpgid_ocall_args_t* _pargs_out = (oe_syscall_getpgid_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getpgid_ocall( + _pargs_in->pid); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_getgroups_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_getgroups_ocall_args_t* _pargs_in = (oe_syscall_getgroups_ocall_args_t*)input_buffer; + oe_syscall_getgroups_ocall_args_t* _pargs_out = (oe_syscall_getgroups_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->list) + OE_SET_OUT_POINTER(list, _pargs_in->size, sizeof(unsigned int), unsigned int*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_getgroups_ocall( + _pargs_in->size, + _pargs_in->list); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_syscall_uname_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_syscall_uname_ocall_args_t* _pargs_in = (oe_syscall_uname_ocall_args_t*)input_buffer; + oe_syscall_uname_ocall_args_t* _pargs_out = (oe_syscall_uname_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->buf) + OE_SET_OUT_POINTER(buf, 1, sizeof(struct oe_utsname), struct oe_utsname*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_syscall_uname_ocall( + _pargs_in->buf); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + _pargs_out->ocall_errno = errno; + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_get_supported_attester_format_ids_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_get_supported_attester_format_ids_ocall_args_t* _pargs_in = (oe_get_supported_attester_format_ids_ocall_args_t*)input_buffer; + oe_get_supported_attester_format_ids_ocall_args_t* _pargs_out = (oe_get_supported_attester_format_ids_ocall_args_t*)output_buffer; + + uint8_t* _deepcopy_out_buffer = NULL; + size_t _deepcopy_out_buffer_offset = 0; + size_t _deepcopy_out_buffer_size = 0; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->format_ids) + OE_SET_OUT_POINTER(format_ids, 1, sizeof(format_ids_t), format_ids_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_get_supported_attester_format_ids_ocall( + _pargs_in->format_ids); + + /* Compute the size for the deep-copy out buffer. */ + if (_pargs_in->format_ids && _pargs_in->format_ids->data) + OE_ADD_ARG_SIZE(_deepcopy_out_buffer_size, 1, _pargs_in->format_ids->size); + + if (_deepcopy_out_buffer_size) + { + _deepcopy_out_buffer = (uint8_t*) oe_malloc(_deepcopy_out_buffer_size); + if (!_deepcopy_out_buffer) + { + _result = OE_OUT_OF_MEMORY; + goto done; + } + } + + /* Serialize the deep-copied content into the buffer. */ + if (_pargs_in->format_ids && _pargs_in->format_ids->data) + OE_WRITE_DEEPCOPY_OUT_PARAM(_pargs_in->format_ids->data, 1, _pargs_in->format_ids->size); + + if (_deepcopy_out_buffer_offset != _deepcopy_out_buffer_size) + { + _result = OE_FAILURE; + goto done; + } + + /* Set the _deepcopy_out_buffer and _deepcopy_out_buffer as part of _pargs_out. */ + _pargs_out->deepcopy_out_buffer = _deepcopy_out_buffer; + _pargs_out->deepcopy_out_buffer_size = _deepcopy_out_buffer_size; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + /* Free _pargs_out->deepcopy_out_buffer on failure. */ + if (_result != OE_OK) + { + oe_free(_pargs_out->deepcopy_out_buffer); + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + } + + /* Free nested buffers allocated by the user function. */ + if (_pargs_in->format_ids) + { + for (size_t _i_1 = 0; _i_1 < 1; _i_1++) + { + free(_pargs_in->format_ids[_i_1].data); + } + } + + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_get_qetarget_info_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_get_qetarget_info_ocall_args_t* _pargs_in = (oe_get_qetarget_info_ocall_args_t*)input_buffer; + oe_get_qetarget_info_ocall_args_t* _pargs_out = (oe_get_qetarget_info_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->format_id) + OE_SET_IN_POINTER(format_id, 1, sizeof(oe_uuid_t), oe_uuid_t*); + if (_pargs_in->opt_params) + OE_SET_IN_POINTER(opt_params, 1, _pargs_in->opt_params_size, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->target_info) + OE_SET_OUT_POINTER(target_info, 1, sizeof(sgx_target_info_t), sgx_target_info_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_get_qetarget_info_ocall( + (const oe_uuid_t*)_pargs_in->format_id, + (const void*)_pargs_in->opt_params, + _pargs_in->opt_params_size, + _pargs_in->target_info); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_get_quote_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_get_quote_ocall_args_t* _pargs_in = (oe_get_quote_ocall_args_t*)input_buffer; + oe_get_quote_ocall_args_t* _pargs_out = (oe_get_quote_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->format_id) + OE_SET_IN_POINTER(format_id, 1, sizeof(oe_uuid_t), oe_uuid_t*); + if (_pargs_in->opt_params) + OE_SET_IN_POINTER(opt_params, 1, _pargs_in->opt_params_size, void*); + if (_pargs_in->sgx_report) + OE_SET_IN_POINTER(sgx_report, 1, sizeof(sgx_report_t), sgx_report_t*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->quote) + OE_SET_OUT_POINTER(quote, 1, _pargs_in->quote_size, void*); + if (_pargs_in->quote_size_out) + OE_SET_OUT_POINTER(quote_size_out, 1, sizeof(size_t), size_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_get_quote_ocall( + (const oe_uuid_t*)_pargs_in->format_id, + (const void*)_pargs_in->opt_params, + _pargs_in->opt_params_size, + (const sgx_report_t*)_pargs_in->sgx_report, + _pargs_in->quote, + _pargs_in->quote_size, + _pargs_in->quote_size_out); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_get_quote_verification_collateral_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_get_quote_verification_collateral_ocall_args_t* _pargs_in = (oe_get_quote_verification_collateral_ocall_args_t*)input_buffer; + oe_get_quote_verification_collateral_ocall_args_t* _pargs_out = (oe_get_quote_verification_collateral_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->fmspc) + OE_SET_IN_POINTER(fmspc, 1, sizeof(uint8_t[6]), uint8_t*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->tcb_info) + OE_SET_OUT_POINTER(tcb_info, 1, _pargs_in->tcb_info_size, void*); + if (_pargs_in->tcb_info_size_out) + OE_SET_OUT_POINTER(tcb_info_size_out, 1, sizeof(size_t), size_t*); + if (_pargs_in->tcb_info_issuer_chain) + OE_SET_OUT_POINTER(tcb_info_issuer_chain, 1, _pargs_in->tcb_info_issuer_chain_size, void*); + if (_pargs_in->tcb_info_issuer_chain_size_out) + OE_SET_OUT_POINTER(tcb_info_issuer_chain_size_out, 1, sizeof(size_t), size_t*); + if (_pargs_in->pck_crl) + OE_SET_OUT_POINTER(pck_crl, 1, _pargs_in->pck_crl_size, void*); + if (_pargs_in->pck_crl_size_out) + OE_SET_OUT_POINTER(pck_crl_size_out, 1, sizeof(size_t), size_t*); + if (_pargs_in->root_ca_crl) + OE_SET_OUT_POINTER(root_ca_crl, 1, _pargs_in->root_ca_crl_size, void*); + if (_pargs_in->root_ca_crl_size_out) + OE_SET_OUT_POINTER(root_ca_crl_size_out, 1, sizeof(size_t), size_t*); + if (_pargs_in->pck_crl_issuer_chain) + OE_SET_OUT_POINTER(pck_crl_issuer_chain, 1, _pargs_in->pck_crl_issuer_chain_size, void*); + if (_pargs_in->pck_crl_issuer_chain_size_out) + OE_SET_OUT_POINTER(pck_crl_issuer_chain_size_out, 1, sizeof(size_t), size_t*); + if (_pargs_in->qe_identity) + OE_SET_OUT_POINTER(qe_identity, 1, _pargs_in->qe_identity_size, void*); + if (_pargs_in->qe_identity_size_out) + OE_SET_OUT_POINTER(qe_identity_size_out, 1, sizeof(size_t), size_t*); + if (_pargs_in->qe_identity_issuer_chain) + OE_SET_OUT_POINTER(qe_identity_issuer_chain, 1, _pargs_in->qe_identity_issuer_chain_size, void*); + if (_pargs_in->qe_identity_issuer_chain_size_out) + OE_SET_OUT_POINTER(qe_identity_issuer_chain_size_out, 1, sizeof(size_t), size_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_get_quote_verification_collateral_ocall( + *(uint8_t(*)[6])_pargs_in->fmspc, + _pargs_in->collateral_provider, + _pargs_in->tcb_info, + _pargs_in->tcb_info_size, + _pargs_in->tcb_info_size_out, + _pargs_in->tcb_info_issuer_chain, + _pargs_in->tcb_info_issuer_chain_size, + _pargs_in->tcb_info_issuer_chain_size_out, + _pargs_in->pck_crl, + _pargs_in->pck_crl_size, + _pargs_in->pck_crl_size_out, + _pargs_in->root_ca_crl, + _pargs_in->root_ca_crl_size, + _pargs_in->root_ca_crl_size_out, + _pargs_in->pck_crl_issuer_chain, + _pargs_in->pck_crl_issuer_chain_size, + _pargs_in->pck_crl_issuer_chain_size_out, + _pargs_in->qe_identity, + _pargs_in->qe_identity_size, + _pargs_in->qe_identity_size_out, + _pargs_in->qe_identity_issuer_chain, + _pargs_in->qe_identity_issuer_chain_size, + _pargs_in->qe_identity_issuer_chain_size_out); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_verify_quote_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_verify_quote_ocall_args_t* _pargs_in = (oe_verify_quote_ocall_args_t*)input_buffer; + oe_verify_quote_ocall_args_t* _pargs_out = (oe_verify_quote_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->format_id) + OE_SET_IN_POINTER(format_id, 1, sizeof(oe_uuid_t), oe_uuid_t*); + if (_pargs_in->opt_params) + OE_SET_IN_POINTER(opt_params, 1, _pargs_in->opt_params_size, void*); + if (_pargs_in->p_quote) + OE_SET_IN_POINTER(p_quote, 1, _pargs_in->quote_size, void*); + if (_pargs_in->p_qve_report_info) + OE_SET_IN_OUT_POINTER(p_qve_report_info, 1, _pargs_in->qve_report_info_size, void*); + if (_pargs_in->p_tcb_info) + OE_SET_IN_POINTER(p_tcb_info, 1, _pargs_in->tcb_info_size, void*); + if (_pargs_in->p_tcb_info_issuer_chain) + OE_SET_IN_POINTER(p_tcb_info_issuer_chain, 1, _pargs_in->tcb_info_issuer_chain_size, void*); + if (_pargs_in->p_pck_crl) + OE_SET_IN_POINTER(p_pck_crl, 1, _pargs_in->pck_crl_size, void*); + if (_pargs_in->p_root_ca_crl) + OE_SET_IN_POINTER(p_root_ca_crl, 1, _pargs_in->root_ca_crl_size, void*); + if (_pargs_in->p_pck_crl_issuer_chain) + OE_SET_IN_POINTER(p_pck_crl_issuer_chain, 1, _pargs_in->pck_crl_issuer_chain_size, void*); + if (_pargs_in->p_qe_identity) + OE_SET_IN_POINTER(p_qe_identity, 1, _pargs_in->qe_identity_size, void*); + if (_pargs_in->p_qe_identity_issuer_chain) + OE_SET_IN_POINTER(p_qe_identity_issuer_chain, 1, _pargs_in->qe_identity_issuer_chain_size, void*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->p_collateral_expiration_status) + OE_SET_OUT_POINTER(p_collateral_expiration_status, 1, sizeof(uint32_t), uint32_t*); + if (_pargs_in->p_quote_verification_result) + OE_SET_OUT_POINTER(p_quote_verification_result, 1, sizeof(uint32_t), uint32_t*); + if (_pargs_in->p_qve_report_info) + OE_COPY_AND_SET_IN_OUT_POINTER(p_qve_report_info, 1, _pargs_in->qve_report_info_size, void*); + if (_pargs_in->p_supplemental_data) + OE_SET_OUT_POINTER(p_supplemental_data, 1, _pargs_in->supplemental_data_size, void*); + if (_pargs_in->p_supplemental_data_size_out) + OE_SET_OUT_POINTER(p_supplemental_data_size_out, 1, sizeof(uint32_t), uint32_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_verify_quote_ocall( + (const oe_uuid_t*)_pargs_in->format_id, + (const void*)_pargs_in->opt_params, + _pargs_in->opt_params_size, + (const void*)_pargs_in->p_quote, + _pargs_in->quote_size, + _pargs_in->expiration_check_date, + _pargs_in->p_collateral_expiration_status, + _pargs_in->p_quote_verification_result, + _pargs_in->p_qve_report_info, + _pargs_in->qve_report_info_size, + _pargs_in->p_supplemental_data, + _pargs_in->supplemental_data_size, + _pargs_in->p_supplemental_data_size_out, + _pargs_in->collateral_version, + (const void*)_pargs_in->p_tcb_info, + _pargs_in->tcb_info_size, + (const void*)_pargs_in->p_tcb_info_issuer_chain, + _pargs_in->tcb_info_issuer_chain_size, + (const void*)_pargs_in->p_pck_crl, + _pargs_in->pck_crl_size, + (const void*)_pargs_in->p_root_ca_crl, + _pargs_in->root_ca_crl_size, + (const void*)_pargs_in->p_pck_crl_issuer_chain, + _pargs_in->pck_crl_issuer_chain_size, + (const void*)_pargs_in->p_qe_identity, + _pargs_in->qe_identity_size, + (const void*)_pargs_in->p_qe_identity_issuer_chain, + _pargs_in->qe_identity_issuer_chain_size); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_sgx_get_cpuid_table_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_sgx_get_cpuid_table_ocall_args_t* _pargs_in = (oe_sgx_get_cpuid_table_ocall_args_t*)input_buffer; + oe_sgx_get_cpuid_table_ocall_args_t* _pargs_out = (oe_sgx_get_cpuid_table_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->cpuid_table_buffer) + OE_SET_OUT_POINTER(cpuid_table_buffer, 1, _pargs_in->cpuid_table_buffer_size, void*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_sgx_get_cpuid_table_ocall( + _pargs_in->cpuid_table_buffer, + _pargs_in->cpuid_table_buffer_size); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_sgx_backtrace_symbols_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_sgx_backtrace_symbols_ocall_args_t* _pargs_in = (oe_sgx_backtrace_symbols_ocall_args_t*)input_buffer; + oe_sgx_backtrace_symbols_ocall_args_t* _pargs_out = (oe_sgx_backtrace_symbols_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + if (_pargs_in->buffer) + OE_SET_IN_POINTER(buffer, _pargs_in->size, sizeof(uint64_t), uint64_t*); + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + if (_pargs_in->symbols_buffer) + OE_SET_OUT_POINTER(symbols_buffer, 1, _pargs_in->symbols_buffer_size, void*); + if (_pargs_in->symbols_buffer_size_out) + OE_SET_OUT_POINTER(symbols_buffer_size_out, 1, sizeof(size_t), size_t*); + + /* Call user function. */ + _pargs_out->oe_retval = oe_sgx_backtrace_symbols_ocall( + _pargs_in->oe_enclave, + (const uint64_t*)_pargs_in->buffer, + _pargs_in->size, + _pargs_in->symbols_buffer, + _pargs_in->symbols_buffer_size, + _pargs_in->symbols_buffer_size_out); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_sgx_thread_wake_wait_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_sgx_thread_wake_wait_ocall_args_t* _pargs_in = (oe_sgx_thread_wake_wait_ocall_args_t*)input_buffer; + oe_sgx_thread_wake_wait_ocall_args_t* _pargs_out = (oe_sgx_thread_wake_wait_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + oe_sgx_thread_wake_wait_ocall( + _pargs_in->oe_enclave, + _pargs_in->waiter_tcs, + _pargs_in->self_tcs); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_sgx_wake_switchless_worker_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_sgx_wake_switchless_worker_ocall_args_t* _pargs_in = (oe_sgx_wake_switchless_worker_ocall_args_t*)input_buffer; + oe_sgx_wake_switchless_worker_ocall_args_t* _pargs_out = (oe_sgx_wake_switchless_worker_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + oe_sgx_wake_switchless_worker_ocall( + _pargs_in->context); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +static void ocall_oe_sgx_sleep_switchless_worker_ocall( + uint8_t* input_buffer, + size_t input_buffer_size, + uint8_t* output_buffer, + size_t output_buffer_size, + size_t* output_bytes_written) +{ + oe_result_t _result = OE_FAILURE; + OE_UNUSED(input_buffer_size); + + /* Prepare parameters. */ + oe_sgx_sleep_switchless_worker_ocall_args_t* _pargs_in = (oe_sgx_sleep_switchless_worker_ocall_args_t*)input_buffer; + oe_sgx_sleep_switchless_worker_ocall_args_t* _pargs_out = (oe_sgx_sleep_switchless_worker_ocall_args_t*)output_buffer; + + size_t _input_buffer_offset = 0; + size_t _output_buffer_offset = 0; + OE_ADD_SIZE(_input_buffer_offset, sizeof(*_pargs_in)); + OE_ADD_SIZE(_output_buffer_offset, sizeof(*_pargs_out)); + + if (input_buffer_size < sizeof(*_pargs_in) || output_buffer_size < sizeof(*_pargs_in)) + goto done; + + /* Make sure input and output buffers are valid. */ + if (!input_buffer || !output_buffer) { + _result = OE_INVALID_PARAMETER; + goto done; + } + + /* Set in and in-out pointers. */ + /* There were no in nor in-out parameters. */ + + /* Set out and in-out pointers. */ + /* In-out parameters are copied to output buffer. */ + /* There were no out nor in-out parameters. */ + + /* Call user function. */ + oe_sgx_sleep_switchless_worker_ocall( + _pargs_in->context); + + /* There is no deep-copyable out parameter. */ + _pargs_out->deepcopy_out_buffer = NULL; + _pargs_out->deepcopy_out_buffer_size = 0; + + /* Propagate errno back to enclave. */ + /* Errno propagation not enabled. */ + + /* Success. */ + _result = OE_OK; + *output_bytes_written = _output_buffer_offset; + +done: + if (_pargs_out && output_buffer_size >= sizeof(*_pargs_out)) + _pargs_out->oe_result = _result; +} + +/**** OCALL function table. ****/ + +static oe_ocall_func_t _sgx_cpp_ocall_function_table[] = { + (oe_ocall_func_t) ocall_oe_syscall_epoll_create1_ocall, + (oe_ocall_func_t) ocall_oe_syscall_epoll_wait_ocall, + (oe_ocall_func_t) ocall_oe_syscall_epoll_wake_ocall, + (oe_ocall_func_t) ocall_oe_syscall_epoll_ctl_ocall, + (oe_ocall_func_t) ocall_oe_syscall_epoll_close_ocall, + (oe_ocall_func_t) ocall_oe_syscall_open_ocall, + (oe_ocall_func_t) ocall_oe_syscall_read_ocall, + (oe_ocall_func_t) ocall_oe_syscall_write_ocall, + (oe_ocall_func_t) ocall_oe_syscall_readv_ocall, + (oe_ocall_func_t) ocall_oe_syscall_writev_ocall, + (oe_ocall_func_t) ocall_oe_syscall_lseek_ocall, + (oe_ocall_func_t) ocall_oe_syscall_pread_ocall, + (oe_ocall_func_t) ocall_oe_syscall_pwrite_ocall, + (oe_ocall_func_t) ocall_oe_syscall_close_ocall, + (oe_ocall_func_t) ocall_oe_syscall_flock_ocall, + (oe_ocall_func_t) ocall_oe_syscall_fsync_ocall, + (oe_ocall_func_t) ocall_oe_syscall_fdatasync_ocall, + (oe_ocall_func_t) ocall_oe_syscall_dup_ocall, + (oe_ocall_func_t) ocall_oe_syscall_opendir_ocall, + (oe_ocall_func_t) ocall_oe_syscall_readdir_ocall, + (oe_ocall_func_t) ocall_oe_syscall_rewinddir_ocall, + (oe_ocall_func_t) ocall_oe_syscall_closedir_ocall, + (oe_ocall_func_t) ocall_oe_syscall_stat_ocall, + (oe_ocall_func_t) ocall_oe_syscall_fstat_ocall, + (oe_ocall_func_t) ocall_oe_syscall_access_ocall, + (oe_ocall_func_t) ocall_oe_syscall_link_ocall, + (oe_ocall_func_t) ocall_oe_syscall_unlink_ocall, + (oe_ocall_func_t) ocall_oe_syscall_rename_ocall, + (oe_ocall_func_t) ocall_oe_syscall_truncate_ocall, + (oe_ocall_func_t) ocall_oe_syscall_ftruncate_ocall, + (oe_ocall_func_t) ocall_oe_syscall_mkdir_ocall, + (oe_ocall_func_t) ocall_oe_syscall_rmdir_ocall, + (oe_ocall_func_t) ocall_oe_syscall_fcntl_ocall, + (oe_ocall_func_t) ocall_oe_syscall_ioctl_ocall, + (oe_ocall_func_t) ocall_oe_syscall_poll_ocall, + (oe_ocall_func_t) ocall_oe_syscall_kill_ocall, + (oe_ocall_func_t) ocall_oe_syscall_close_socket_ocall, + (oe_ocall_func_t) ocall_oe_syscall_socket_ocall, + (oe_ocall_func_t) ocall_oe_syscall_shutdown_sockets_device_ocall, + (oe_ocall_func_t) ocall_oe_syscall_socketpair_ocall, + (oe_ocall_func_t) ocall_oe_syscall_connect_ocall, + (oe_ocall_func_t) ocall_oe_syscall_accept_ocall, + (oe_ocall_func_t) ocall_oe_syscall_bind_ocall, + (oe_ocall_func_t) ocall_oe_syscall_listen_ocall, + (oe_ocall_func_t) ocall_oe_syscall_recvmsg_ocall, + (oe_ocall_func_t) ocall_oe_syscall_sendmsg_ocall, + (oe_ocall_func_t) ocall_oe_syscall_recv_ocall, + (oe_ocall_func_t) ocall_oe_syscall_recvfrom_ocall, + (oe_ocall_func_t) ocall_oe_syscall_send_ocall, + (oe_ocall_func_t) ocall_oe_syscall_sendto_ocall, + (oe_ocall_func_t) ocall_oe_syscall_recvv_ocall, + (oe_ocall_func_t) ocall_oe_syscall_sendv_ocall, + (oe_ocall_func_t) ocall_oe_syscall_shutdown_ocall, + (oe_ocall_func_t) ocall_oe_syscall_setsockopt_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getsockopt_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getsockname_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getpeername_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getaddrinfo_open_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getaddrinfo_read_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getaddrinfo_close_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getnameinfo_ocall, + (oe_ocall_func_t) ocall_oe_syscall_nanosleep_ocall, + (oe_ocall_func_t) ocall_oe_syscall_clock_nanosleep_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getpid_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getppid_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getpgrp_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getuid_ocall, + (oe_ocall_func_t) ocall_oe_syscall_geteuid_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getgid_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getegid_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getpgid_ocall, + (oe_ocall_func_t) ocall_oe_syscall_getgroups_ocall, + (oe_ocall_func_t) ocall_oe_syscall_uname_ocall, + (oe_ocall_func_t) ocall_oe_get_supported_attester_format_ids_ocall, + (oe_ocall_func_t) ocall_oe_get_qetarget_info_ocall, + (oe_ocall_func_t) ocall_oe_get_quote_ocall, + (oe_ocall_func_t) ocall_oe_get_quote_verification_collateral_ocall, + (oe_ocall_func_t) ocall_oe_verify_quote_ocall, + (oe_ocall_func_t) ocall_oe_sgx_get_cpuid_table_ocall, + (oe_ocall_func_t) ocall_oe_sgx_backtrace_symbols_ocall, + (oe_ocall_func_t) ocall_oe_sgx_thread_wake_wait_ocall, + (oe_ocall_func_t) ocall_oe_sgx_wake_switchless_worker_ocall, + (oe_ocall_func_t) ocall_oe_sgx_sleep_switchless_worker_ocall, + NULL +}; + +oe_result_t oe_create_sgx_cpp_enclave( + const char* path, + oe_enclave_type_t type, + uint32_t flags, + const oe_enclave_setting_t* settings, + uint32_t setting_count, + oe_enclave_t** enclave) +{ + return oe_create_enclave( + path, + type, + flags, + settings, + setting_count, + _sgx_cpp_ocall_function_table, + 83, + _sgx_cpp_ecall_info_table, + 15, + enclave); +} + +OE_EXTERNC_END diff --git a/enclave/sgx_cpp_u.h b/enclave/sgx_cpp_u.h new file mode 100644 index 000000000..9f001874e --- /dev/null +++ b/enclave/sgx_cpp_u.h @@ -0,0 +1,559 @@ +/* + * This file is auto generated by oeedger8r. DO NOT EDIT. + */ +#ifndef EDGER8R_SGX_CPP_U_H +#define EDGER8R_SGX_CPP_U_H + +#include + +#include "sgx_cpp_args.h" + +OE_EXTERNC_BEGIN + +oe_result_t oe_create_sgx_cpp_enclave( + const char* path, + oe_enclave_type_t type, + uint32_t flags, + const oe_enclave_setting_t* settings, + uint32_t setting_count, + oe_enclave_t** enclave); + +/**** ECALL prototypes. ****/ +oe_result_t request_counter( + oe_enclave_t* enclave, + int* _retval, + uint32_t* index); + +oe_result_t get_counter( + oe_enclave_t* enclave, + int* _retval, + uint32_t* index, + size_t previous_size, + size_t limit_count, + uint32_t* counter_value_array, + size_t* buffer_size_array, + unsigned char** previous_attestation, + uint32_t* counter_value); + +oe_result_t reset_prng( + oe_enclave_t* enclave, + int* _retval, + uint32_t* seed, + uint32_t* range); + +oe_result_t generate_rdrand( + oe_enclave_t* enclave, + int* _retval, + uint32_t* rdrandNum); + +oe_result_t generate_rand( + oe_enclave_t* enclave, + int* _retval, + size_t input_len, + size_t limit_count, + uint32_t* counter_value_array, + size_t* buffer_size_array, + unsigned char** previous_attestation, + uint32_t* randNum); + +oe_result_t generate_key( + oe_enclave_t* enclave, + int* _retval, + size_t* key_size); + +oe_result_t update_key( + oe_enclave_t* enclave, + int* _retval, + unsigned char* priv_key, + size_t priv_len, + unsigned char* pub_key, + size_t pub_len); + +oe_result_t get_pubkey( + oe_enclave_t* enclave, + int* _retval, + unsigned char** key_buf, + size_t* key_len); + +oe_result_t encrypt( + oe_enclave_t* enclave, + int* _retval, + unsigned char* input_buf, + unsigned char** output_buf, + size_t input_len, + size_t* output_len); + +oe_result_t decrypt( + oe_enclave_t* enclave, + int* _retval, + unsigned char* input_buf, + unsigned char** output_buf, + size_t input_len, + size_t* output_len); + +oe_result_t oe_get_sgx_report_ecall( + oe_enclave_t* enclave, + oe_result_t* _retval, + const void* opt_params, + size_t opt_params_size, + sgx_report_t* report); + +oe_result_t oe_get_report_v2_ecall( + oe_enclave_t* enclave, + oe_result_t* _retval, + uint32_t flags, + const void* opt_params, + size_t opt_params_size, + uint8_t** report_buffer, + size_t* report_buffer_size); + +oe_result_t oe_verify_local_report_ecall( + oe_enclave_t* enclave, + oe_result_t* _retval, + const uint8_t* report, + size_t report_size, + oe_report_t* parsed_report); + +oe_result_t oe_sgx_init_context_switchless_ecall( + oe_enclave_t* enclave, + oe_result_t* _retval, + oe_host_worker_context_t* host_worker_contexts, + uint64_t num_host_workers); + +oe_result_t oe_sgx_switchless_enclave_worker_thread_ecall( + oe_enclave_t* enclave, + oe_enclave_worker_context_t* context); + +/**** OCALL prototypes. ****/ +oe_host_fd_t oe_syscall_epoll_create1_ocall(int flags); + +int oe_syscall_epoll_wait_ocall( + int64_t epfd, + struct oe_epoll_event* events, + unsigned int maxevents, + int timeout); + +int oe_syscall_epoll_wake_ocall(void); + +int oe_syscall_epoll_ctl_ocall( + int64_t epfd, + int op, + int64_t fd, + struct oe_epoll_event* event); + +int oe_syscall_epoll_close_ocall(oe_host_fd_t epfd); + +oe_host_fd_t oe_syscall_open_ocall( + const char* pathname, + int flags, + oe_mode_t mode); + +ssize_t oe_syscall_read_ocall( + oe_host_fd_t fd, + void* buf, + size_t count); + +ssize_t oe_syscall_write_ocall( + oe_host_fd_t fd, + const void* buf, + size_t count); + +ssize_t oe_syscall_readv_ocall( + oe_host_fd_t fd, + void* iov_buf, + int iovcnt, + size_t iov_buf_size); + +ssize_t oe_syscall_writev_ocall( + oe_host_fd_t fd, + const void* iov_buf, + int iovcnt, + size_t iov_buf_size); + +oe_off_t oe_syscall_lseek_ocall( + oe_host_fd_t fd, + oe_off_t offset, + int whence); + +ssize_t oe_syscall_pread_ocall( + oe_host_fd_t fd, + void* buf, + size_t count, + oe_off_t offset); + +ssize_t oe_syscall_pwrite_ocall( + oe_host_fd_t fd, + const void* buf, + size_t count, + oe_off_t offset); + +int oe_syscall_close_ocall(oe_host_fd_t fd); + +int oe_syscall_flock_ocall( + oe_host_fd_t fd, + int operation); + +int oe_syscall_fsync_ocall(oe_host_fd_t fd); + +int oe_syscall_fdatasync_ocall(oe_host_fd_t fd); + +oe_host_fd_t oe_syscall_dup_ocall(oe_host_fd_t oldfd); + +uint64_t oe_syscall_opendir_ocall(const char* name); + +int oe_syscall_readdir_ocall( + uint64_t dirp, + struct oe_dirent* entry); + +void oe_syscall_rewinddir_ocall(uint64_t dirp); + +int oe_syscall_closedir_ocall(uint64_t dirp); + +int oe_syscall_stat_ocall( + const char* pathname, + struct oe_stat_t* buf); + +int oe_syscall_fstat_ocall( + oe_host_fd_t fd, + struct oe_stat_t* buf); + +int oe_syscall_access_ocall( + const char* pathname, + int mode); + +int oe_syscall_link_ocall( + const char* oldpath, + const char* newpath); + +int oe_syscall_unlink_ocall(const char* pathname); + +int oe_syscall_rename_ocall( + const char* oldpath, + const char* newpath); + +int oe_syscall_truncate_ocall( + const char* path, + oe_off_t length); + +int oe_syscall_ftruncate_ocall( + oe_host_fd_t fd, + oe_off_t length); + +int oe_syscall_mkdir_ocall( + const char* pathname, + oe_mode_t mode); + +int oe_syscall_rmdir_ocall(const char* pathname); + +int oe_syscall_fcntl_ocall( + oe_host_fd_t fd, + int cmd, + uint64_t arg, + uint64_t argsize, + void* argout); + +int oe_syscall_ioctl_ocall( + oe_host_fd_t fd, + uint64_t request, + uint64_t arg, + uint64_t argsize, + void* argout); + +int oe_syscall_poll_ocall( + struct oe_host_pollfd* host_fds, + oe_nfds_t nfds, + int timeout); + +int oe_syscall_kill_ocall( + int pid, + int signum); + +int oe_syscall_close_socket_ocall(oe_host_fd_t sockfd); + +oe_host_fd_t oe_syscall_socket_ocall( + int domain, + int type, + int protocol); + +int oe_syscall_shutdown_sockets_device_ocall(oe_host_fd_t sockfd); + +int oe_syscall_socketpair_ocall( + int domain, + int type, + int protocol, + oe_host_fd_t sv[2]); + +int oe_syscall_connect_ocall( + oe_host_fd_t sockfd, + const struct oe_sockaddr* addr, + oe_socklen_t addrlen); + +oe_host_fd_t oe_syscall_accept_ocall( + oe_host_fd_t sockfd, + struct oe_sockaddr* addr, + oe_socklen_t addrlen_in, + oe_socklen_t* addrlen_out); + +int oe_syscall_bind_ocall( + oe_host_fd_t sockfd, + const struct oe_sockaddr* addr, + oe_socklen_t addrlen); + +int oe_syscall_listen_ocall( + oe_host_fd_t sockfd, + int backlog); + +ssize_t oe_syscall_recvmsg_ocall( + oe_host_fd_t sockfd, + void* msg_name, + oe_socklen_t msg_namelen, + oe_socklen_t* msg_namelen_out, + void* msg_iov_buf, + size_t msg_iovlen, + size_t msg_iov_buf_size, + void* msg_control, + size_t msg_controllen, + size_t* msg_controllen_out, + int flags); + +ssize_t oe_syscall_sendmsg_ocall( + oe_host_fd_t sockfd, + const void* msg_name, + oe_socklen_t msg_namelen, + void* msg_iov_buf, + size_t msg_iovlen, + size_t msg_iov_buf_size, + const void* msg_control, + size_t msg_controllen, + int flags); + +ssize_t oe_syscall_recv_ocall( + oe_host_fd_t sockfd, + void* buf, + size_t len, + int flags); + +ssize_t oe_syscall_recvfrom_ocall( + oe_host_fd_t sockfd, + void* buf, + size_t len, + int flags, + struct oe_sockaddr* src_addr, + oe_socklen_t addrlen_in, + oe_socklen_t* addrlen_out); + +ssize_t oe_syscall_send_ocall( + oe_host_fd_t sockfd, + const void* buf, + size_t len, + int flags); + +ssize_t oe_syscall_sendto_ocall( + oe_host_fd_t sockfd, + const void* buf, + size_t len, + int flags, + const struct oe_sockaddr* dest_addr, + oe_socklen_t addrlen); + +ssize_t oe_syscall_recvv_ocall( + oe_host_fd_t fd, + void* iov_buf, + int iovcnt, + size_t iov_buf_size); + +ssize_t oe_syscall_sendv_ocall( + oe_host_fd_t fd, + const void* iov_buf, + int iovcnt, + size_t iov_buf_size); + +int oe_syscall_shutdown_ocall( + oe_host_fd_t sockfd, + int how); + +int oe_syscall_setsockopt_ocall( + oe_host_fd_t sockfd, + int level, + int optname, + const void* optval, + oe_socklen_t optlen); + +int oe_syscall_getsockopt_ocall( + oe_host_fd_t sockfd, + int level, + int optname, + void* optval, + oe_socklen_t optlen_in, + oe_socklen_t* optlen_out); + +int oe_syscall_getsockname_ocall( + oe_host_fd_t sockfd, + struct oe_sockaddr* addr, + oe_socklen_t addrlen_in, + oe_socklen_t* addrlen_out); + +int oe_syscall_getpeername_ocall( + oe_host_fd_t sockfd, + struct oe_sockaddr* addr, + oe_socklen_t addrlen_in, + oe_socklen_t* addrlen_out); + +int oe_syscall_getaddrinfo_open_ocall( + const char* node, + const char* service, + const struct oe_addrinfo* hints, + uint64_t* handle); + +int oe_syscall_getaddrinfo_read_ocall( + uint64_t handle, + int* ai_flags, + int* ai_family, + int* ai_socktype, + int* ai_protocol, + oe_socklen_t ai_addrlen_in, + oe_socklen_t* ai_addrlen, + struct oe_sockaddr* ai_addr, + size_t ai_canonnamelen_in, + size_t* ai_canonnamelen, + char* ai_canonname); + +int oe_syscall_getaddrinfo_close_ocall(uint64_t handle); + +int oe_syscall_getnameinfo_ocall( + const struct oe_sockaddr* sa, + oe_socklen_t salen, + char* host, + oe_socklen_t hostlen, + char* serv, + oe_socklen_t servlen, + int flags); + +int oe_syscall_nanosleep_ocall( + struct oe_timespec* req, + struct oe_timespec* rem); + +int oe_syscall_clock_nanosleep_ocall( + oe_clockid_t clockid, + int flag, + struct oe_timespec* req, + struct oe_timespec* rem); + +int oe_syscall_getpid_ocall(void); + +int oe_syscall_getppid_ocall(void); + +int oe_syscall_getpgrp_ocall(void); + +unsigned int oe_syscall_getuid_ocall(void); + +unsigned int oe_syscall_geteuid_ocall(void); + +unsigned int oe_syscall_getgid_ocall(void); + +unsigned int oe_syscall_getegid_ocall(void); + +int oe_syscall_getpgid_ocall(int pid); + +int oe_syscall_getgroups_ocall( + size_t size, + unsigned int* list); + +int oe_syscall_uname_ocall(struct oe_utsname* buf); + +oe_result_t oe_get_supported_attester_format_ids_ocall(format_ids_t* format_ids); + +oe_result_t oe_get_qetarget_info_ocall( + const oe_uuid_t* format_id, + const void* opt_params, + size_t opt_params_size, + sgx_target_info_t* target_info); + +oe_result_t oe_get_quote_ocall( + const oe_uuid_t* format_id, + const void* opt_params, + size_t opt_params_size, + const sgx_report_t* sgx_report, + void* quote, + size_t quote_size, + size_t* quote_size_out); + +oe_result_t oe_get_quote_verification_collateral_ocall( + uint8_t fmspc[6], + uint8_t collateral_provider, + void* tcb_info, + size_t tcb_info_size, + size_t* tcb_info_size_out, + void* tcb_info_issuer_chain, + size_t tcb_info_issuer_chain_size, + size_t* tcb_info_issuer_chain_size_out, + void* pck_crl, + size_t pck_crl_size, + size_t* pck_crl_size_out, + void* root_ca_crl, + size_t root_ca_crl_size, + size_t* root_ca_crl_size_out, + void* pck_crl_issuer_chain, + size_t pck_crl_issuer_chain_size, + size_t* pck_crl_issuer_chain_size_out, + void* qe_identity, + size_t qe_identity_size, + size_t* qe_identity_size_out, + void* qe_identity_issuer_chain, + size_t qe_identity_issuer_chain_size, + size_t* qe_identity_issuer_chain_size_out); + +oe_result_t oe_verify_quote_ocall( + const oe_uuid_t* format_id, + const void* opt_params, + size_t opt_params_size, + const void* p_quote, + uint32_t quote_size, + const time_t expiration_check_date, + uint32_t* p_collateral_expiration_status, + uint32_t* p_quote_verification_result, + void* p_qve_report_info, + uint32_t qve_report_info_size, + void* p_supplemental_data, + uint32_t supplemental_data_size, + uint32_t* p_supplemental_data_size_out, + uint32_t collateral_version, + const void* p_tcb_info, + uint32_t tcb_info_size, + const void* p_tcb_info_issuer_chain, + uint32_t tcb_info_issuer_chain_size, + const void* p_pck_crl, + uint32_t pck_crl_size, + const void* p_root_ca_crl, + uint32_t root_ca_crl_size, + const void* p_pck_crl_issuer_chain, + uint32_t pck_crl_issuer_chain_size, + const void* p_qe_identity, + uint32_t qe_identity_size, + const void* p_qe_identity_issuer_chain, + uint32_t qe_identity_issuer_chain_size); + +oe_result_t oe_sgx_get_cpuid_table_ocall( + void* cpuid_table_buffer, + size_t cpuid_table_buffer_size); + +oe_result_t oe_sgx_backtrace_symbols_ocall( + oe_enclave_t* oe_enclave, + const uint64_t* buffer, + size_t size, + void* symbols_buffer, + size_t symbols_buffer_size, + size_t* symbols_buffer_size_out); + +void oe_sgx_thread_wake_wait_ocall( + oe_enclave_t* oe_enclave, + uint64_t waiter_tcs, + uint64_t self_tcs); + +void oe_sgx_wake_switchless_worker_ocall(oe_host_worker_context_t* context); + +void oe_sgx_sleep_switchless_worker_ocall(oe_enclave_worker_context_t* context); + +OE_EXTERNC_END + +#endif // EDGER8R_SGX_CPP_U_H diff --git a/enclave/sgxcode/CMakeLists.txt b/enclave/sgxcode/CMakeLists.txt new file mode 100644 index 000000000..4e76c9d1b --- /dev/null +++ b/enclave/sgxcode/CMakeLists.txt @@ -0,0 +1,56 @@ +# Copyright (c) Open Enclave SDK contributors. +# Licensed under the MIT License. + +cmake_minimum_required(VERSION 3.11) + +# If the CC environment variable has been specified or if the CMAKE_C_COMPILER +# cmake variable has been passed to cmake, use the C compiler that has been +# specified. Otherwise, prefer clang. Same for C++ compiler. +# This must be done before the `project` command. +if (UNIX) + if (NOT DEFINED ENV{CC} AND NOT DEFINED CMAKE_C_COMPILER) + find_program(CMAKE_C_COMPILER clang-11 clang-10 clang) + endif () + if (NOT DEFINED ENV{CXX} AND NOT DEFINED CMAKE_CXX_COMPILER) + find_program(CMAKE_CXX_COMPILER clang++-11 clang++-10 clang++) + endif () +endif () + +project("sgx code" LANGUAGES C CXX) + +find_package(OpenEnclave CONFIG REQUIRED) + +set(CMAKE_CXX_STANDARD 11) +set(OE_CRYPTO_LIB + mbedtls + CACHE STRING "Crypto library used by enclaves.") + +add_subdirectory(enclave) +add_subdirectory(host) + +# Generate key +add_custom_command( + OUTPUT private.pem public.pem + COMMAND openssl genrsa -out private.pem -3 3072 + COMMAND openssl rsa -in private.pem -pubout -out public.pem) + +# Sign enclave +add_custom_command( + OUTPUT enclave/enclave.signed + DEPENDS enclave enclave/common/file-encryptor.conf private.pem + COMMAND openenclave::oesign sign -e $ -c + ${CMAKE_SOURCE_DIR}/enclave/common/file-encryptor.conf -k private.pem) + +add_custom_target(sign ALL DEPENDS enclave/enclave.signed) + +if ((NOT DEFINED ENV{OE_SIMULATION}) OR (NOT $ENV{OE_SIMULATION})) + add_custom_target( + run + DEPENDS sgxhost sign + COMMAND sgxhost ${CMAKE_BINARY_DIR}/enclave/enclave.signed) +endif () + +add_custom_target( + simulate + DEPENDS sgxhost sign + COMMAND sgxhost ${CMAKE_BINARY_DIR}/enclave/enclave.signed --simulate) diff --git a/enclave/sgxcode/Makefile b/enclave/sgxcode/Makefile new file mode 100644 index 000000000..d2d10d2b0 --- /dev/null +++ b/enclave/sgxcode/Makefile @@ -0,0 +1,24 @@ +# Copyright (c) Open Enclave SDK contributors. +# Licensed under the MIT License. + +.PHONY: all build clean run simulate + +OE_CRYPTO_LIB := mbedtls +export OE_CRYPTO_LIB + +all: build + +build: + $(MAKE) -C enclave + $(MAKE) -C host + +clean: + $(MAKE) -C enclave clean + $(MAKE) -C host clean + +run: + host/file-encryptorhost ./enclave/file-encryptorenc.signed + +simulate: + host/file-encryptorhost ./enclave/file-encryptorenc.signed --simulate + diff --git a/enclave/sgxcode/README.md b/enclave/sgxcode/README.md new file mode 100644 index 000000000..473d67e05 --- /dev/null +++ b/enclave/sgxcode/README.md @@ -0,0 +1,138 @@ +# The File-Encryptor Sample + +OE SDK comes with a default crypto support library that supports a [subset of the open sources mbedTLS](https://github.com/openenclave/openenclave/blob/master/docs/MbedtlsSupport.md) library. +This sample demonstrates how to perform simple file cryptographic operations inside an enclave using mbedTLS library. + +It has the following properties: + +- Written in C++ +- Show how to encrypt and decrypt data inside an enclave +- Show how to derive a key from a password string using [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2) +- Use AES mbedTLS API to perform encryption and decryption +- Use the following OE APIs + - mbedtls_aes_setkey_* + - mbedtls_aes_crypt_cbc + - mbedtls_pkcs5_pbkdf2_hmac + - mbedtls_ctr_drbg_random + - mbedtls_entropy_* + - mbedtls_ctr_drbg_* + - mbedtls_sha256_* +- Also runs in OE simulation mode + +## Host application + +This sample is relatively straightforward, It's all about the use of the mbedTLS library. + +![Sample components diagram](diagram.png) + +The host application drives an enclave to perform the following operations: + +1. Create an enclave from the host. + +2. Encrypt a `testfile` into `out.encrypted`. It breaks an input file into 16-byte blocks. + It then sends each block to the enclave for encryption one block after the other until the + very last block is encountered. It makes sure the last block is padded to make it a 16-byte block, + which was required AES-CBC encryption algorithm used by the enclave. + +3. Decrypt the `out.encrypted` file to the `out.decrypted` file. + + The decryption process is a reverse of the encryption except that it provides a encryption header + to the encryptor in the enclave in its `initialize_encryptor` call, which contains a + `encryption_header_t` (defined below), that has encryption metadata for the encryptor + to validate its password and retrieve the encryption key from it. + + In the end, the host makes sure the contents of `testfile` and `out.decrypted` are identical + i.e. that the encryption and the decryption produce the expected result. + +4. Terminate the enclave. + +## Enclave library + +### ECALLs + +There are three ECALLs implemented inside the enclave library: + +### 1. initialize_encryptor + +```c +int initialize_encryptor( + bool encrypt, + const char* password, + size_t password_len, + encryption_header_t* header) +``` + +The bulk of the operations done in this enclave call involve allocating resources and setting up mbedTLS for encryption and decryption operations. + +#### For encryption operation + +It does the following operations to generate `encryption_header_t` information for passing back the host to write into the encrypted file. + +```c +typedef struct _encryption_header +{ + size_t fileDataSize; + unsigned char digest[HASH_VALUE_SIZE_IN_BYTES]; + unsigned char encrypted_key[ENCRYPTION_KEY_SIZE_IN_BYTES]; +} encryption_header_t; +``` + +- Generate a SHA256 digest for the input password, stored in digest field. +- Derive a password key from the input password. +- Produce an encryption key. +- Encrypt the encryption key with the password key, stored in `encrypted_key` field. + +See the following routine for implementation details: + +```c +int ecall_dispatcher::prepare_encryption_header( + encryption_header_t* header, + string password) +``` + +#### For decryption operation + +In decryption, instead of generating `encryption_header_t` information, initialize_encryptor uses the host provided `encryption_header_t` +information to validate the input password and extract encryption key for later decryption operations. + +Here what it does: + +- Check password by comparing `encryption_header_t.digest` with the calculated hash of the input password. +- Derive a password key from the input password. +- Decrypt `encryption_header_t.encrypted_key` with the password key produced above, in preparing for upcoming decryption operations. + +See the following routine for details: + +```c +int ecall_dispatcher::parse_encryption_header( + encryption_header_t* header, + string password) +``` + +#### 2. encrypt_block + +```c +int encrypt_block( + bool encrypt, + unsigned char* input_buf, + unsigned char* output_buf, + size_t size) +``` + +Send a block of data to the enclave for encryption using the configuration setup up by the `initialize_encryptor()` call. + +#### 3. close_encryptor() + +```c +void close_encryptor() +``` + +Free all the resources allocated for this encryptor instance. + +## Build and run + +To build and run this sample, please refer to documentation provided in the main [README file](../README.md#building-the-samples) + +#### Note + +The file-encryptor sample can run under OE simulation mode. \ No newline at end of file diff --git a/enclave/sgxcode/enclave/CMakeLists.txt b/enclave/sgxcode/enclave/CMakeLists.txt new file mode 100644 index 000000000..107491317 --- /dev/null +++ b/enclave/sgxcode/enclave/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (c) Open Enclave SDK contributors. +# Licensed under the MIT License. + +# Use the edger8r to generate C bindings from the EDL file. +add_custom_command( + OUTPUT sgx_cpp_t.h sgx_cpp_t.c sgx_cpp_args.h + DEPENDS ${CMAKE_SOURCE_DIR}/enclave/sgx_cpp.edl + COMMAND + openenclave::oeedger8r --trusted ${CMAKE_SOURCE_DIR}/enclave/sgx_cpp.edl + --search-path ${OE_INCLUDEDIR} --search-path + ${OE_INCLUDEDIR}/openenclave/edl/sgx) + +set(COUNTER_SRC simulated_counter_src) +set(RANDOM_SRC random_src) +set(DECRYPTOR_SRC decryptor_src) + +add_executable( + enclave common/ecalls.cpp common/dispatcher.cpp + ${COUNTER_SRC}/simulated_counter.cpp + ${RANDOM_SRC}/random.cpp + ${DECRYPTOR_SRC}/decryptor.cpp + ${CMAKE_CURRENT_BINARY_DIR}/sgx_cpp_t.c) +if (WIN32) + maybe_build_using_clangw(enclave) +endif () + +target_compile_definitions(enclave PUBLIC OE_API_VERSION=2) + +target_include_directories( + enclave + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} # Needed for #include "../shared.h" + ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) + +if (OE_CRYPTO_LIB STREQUAL "openssl_3") + message(STATUS "openssl_3 enable.") +else() + message(STATUS "openssl_3 not enable. ${OE_CRYPTO_LIB}") +endif () + +target_link_libraries( + enclave openenclave::oeenclave openenclave::oecryptoopenssl + openenclave::oelibcxx) diff --git a/enclave/sgxcode/enclave/Makefile b/enclave/sgxcode/enclave/Makefile new file mode 100644 index 000000000..218fbd02d --- /dev/null +++ b/enclave/sgxcode/enclave/Makefile @@ -0,0 +1,53 @@ +# Copyright (c) Open Enclave SDK contributors. +# Licensed under the MIT License. + +include ../../config.mk + +ifeq ($(OE_CRYPTO_LIB),openssl_3) + CFLAGS=$(shell pkg-config oeenclave-$(C_COMPILER) --variable=${OE_CRYPTO_LIB}flags) + CXXFLAGS=$(shell pkg-config oeenclave-$(CXX_COMPILER) --variable=${OE_CRYPTO_LIB}flags) +else + CFLAGS=$(shell pkg-config oeenclave-$(C_COMPILER) --cflags) + CXXFLAGS=$(shell pkg-config oeenclave-$(CXX_COMPILER) --cflags) +endif +LDFLAGS=$(shell pkg-config oeenclave-$(CXX_COMPILER) --libs) +INCDIR=$(shell pkg-config oeenclave-$(C_COMPILER) --variable=includedir) +CRYPTO_LDFLAGS=$(shell pkg-config oeenclave-$(COMPILER) --variable=${OE_CRYPTO_LIB}libs) + +CRYPTO_SRC = $(OE_CRYPTO_LIB)_src +CXXINCDIR = -I. -I../ -I../.. +CXXSRCS = common/ecalls.cpp \ + $(CRYPTO_SRC)/encryptor.cpp \ + $(CRYPTO_SRC)/keys.cpp + +# Cover openssl, openssl_symcrypt_fips, and openssl_3 +ifneq (,$(findstring openssl,$(OE_CRYPTO_LIB))) + CRYPTO_SRC = openssl_src +endif + +all: + $(MAKE) build + $(MAKE) keys + $(MAKE) sign + +build: + @ echo "Compilers used: $(CC), $(CXX)" + oeedger8r ../enclave/sgx_cpp.edl --trusted \ + --search-path $(INCDIR) \ + --search-path $(INCDIR)/openenclave/edl/sgx + $(CXX) -g -c $(CXXFLAGS) -DOE_API_VERSION=2 -std=c++11 $(CXXINCDIR) \ + $(CXXSRCS) + $(CC) -g -c $(CFLAGS) -DOE_API_VERSION=2 sgx_cpp_t.c -o sgx_cpp_t.o + $(CXX) -o file-encryptorenc ecalls.o encryptor.o keys.o sgx_cpp_t.o $(LDFLAGS) $(CRYPTO_LDFLAGS) + +sign: + oesign sign -e file-encryptorenc -c common/file-encryptor.conf -k private.pem + +clean: + rm -f file-encryptorenc file-encryptorenc.signed *.o sgx_cpp_t.* sgx_cpp_args.h private.pem public.pem + +keys: + openssl genrsa -out private.pem -3 3072 + openssl rsa -in private.pem -pubout -out public.pem + + diff --git a/enclave/sgxcode/enclave/common/dispatcher.cpp b/enclave/sgxcode/enclave/common/dispatcher.cpp new file mode 100644 index 000000000..1d0e0abd6 --- /dev/null +++ b/enclave/sgxcode/enclave/common/dispatcher.cpp @@ -0,0 +1,7 @@ +#include "common/dispatcher.h" +#include "common/trace.h" + + +ecall_dispatcher::ecall_dispatcher() : counterNum(0) +{ +} diff --git a/enclave/sgxcode/enclave/common/dispatcher.h b/enclave/sgxcode/enclave/common/dispatcher.h new file mode 100644 index 000000000..dd25ab2f8 --- /dev/null +++ b/enclave/sgxcode/enclave/common/dispatcher.h @@ -0,0 +1,87 @@ +// Copyright (c) Open Enclave SDK contributors. +// Licensed under the MIT License. + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include + + +using namespace std; + +class ecall_dispatcher +{ + private: + // counter + uint32_t counterNum; + std::vector counters; + + // random generator + std::random_device rd; // Obtain a random number from hardware + uint32_t seed; + uint32_t range; + std::mt19937 eng; + uint32_t randUseCount; + + // decryptor + unsigned char* pubKeyData; + unsigned char* privKeyData; + int pubLen; + int privLen; + + public: + ecall_dispatcher(); + + // counter + int request_counter(uint32_t* index); + int get_counter( + uint32_t* index, + size_t previous_size, + size_t limit_count, + uint32_t* counter_value_array, + size_t * buffer_size_array, + unsigned char ** previous_attestation, + uint32_t* counter_value); + + // random generator + int reset_prng( + uint32_t* seed, + uint32_t* range); + int generate_rdrand(uint32_t* rdrandNum); + int generate_rand(size_t previous_size, + size_t limit_count, + uint32_t* counter_value_array, + size_t * buffer_size_array, + unsigned char ** previous_attestation, + uint32_t* randNum); + + // decryptor + int generate_key(size_t* key_size); + int update_key( + unsigned char* priv_key, + size_t priv_len, + unsigned char* pub_key, + size_t pub_len); + int get_pubkey( + unsigned char **key_buf, + size_t *key_len); + int encrypt( + unsigned char* input_buf, + unsigned char** output_buf, + size_t input_len, + size_t* output_len); + + int decrypt( + unsigned char* input_buf, + unsigned char** output_buf, + size_t input_len, + size_t* output_len); + +}; diff --git a/enclave/sgxcode/enclave/common/ecalls.cpp b/enclave/sgxcode/enclave/common/ecalls.cpp new file mode 100644 index 000000000..2a90cfa6f --- /dev/null +++ b/enclave/sgxcode/enclave/common/ecalls.cpp @@ -0,0 +1,93 @@ +// Copyright (c) Open Enclave SDK contributors. +// Licensed under the MIT License. + +#include + +#include "dispatcher.h" +#include "sgx_cpp_t.h" + +// Declare a static dispatcher object for enabling for better organization +// of enclave-wise global variables +static ecall_dispatcher dispatcher; + +int request_counter( + uint32_t* index) +{ + return dispatcher.request_counter(index); +} + +int get_counter( + uint32_t* index, + size_t previous_size, + size_t limit_count, + uint32_t* counter_value_array, + size_t * buffer_size_array, + unsigned char ** previous_attestation, + uint32_t* counter_value) +{ + return dispatcher.get_counter(index,previous_size,limit_count,counter_value_array,buffer_size_array,previous_attestation,counter_value); +} + +int reset_prng( + uint32_t* seed, + uint32_t* range) +{ + return dispatcher.reset_prng(seed, range); +} + +int generate_rdrand(uint32_t* rdrandNum) +{ + return dispatcher.generate_rdrand(rdrandNum); +} + +int generate_rand(size_t previous_size, + size_t limit_count, + uint32_t* counter_value_array, + size_t * buffer_size_array, + unsigned char ** previous_attestation, + uint32_t* randNum) +{ + return dispatcher.generate_rand(previous_size, limit_count, counter_value_array, buffer_size_array, + previous_attestation, randNum); +} + +int generate_key( + size_t *key_size) +{ + return dispatcher.generate_key(key_size); +} + +int update_key( + unsigned char* priv_key, + size_t priv_len, + unsigned char* pub_key, + size_t pub_len) +{ + return dispatcher.update_key(priv_key, priv_len, pub_key, pub_len); +} + +int get_pubkey( + unsigned char **key_buf, + size_t *key_len) +{ + return dispatcher.get_pubkey(key_buf, key_len); +} + +int encrypt( + unsigned char* input_buf, + unsigned char** output_buf, + size_t input_len, + size_t* output_len) +{ + return dispatcher.encrypt(input_buf, output_buf, input_len, output_len); +} + +int decrypt( + unsigned char* input_buf, + unsigned char** output_buf, + size_t input_len, + size_t* output_len) +{ + return dispatcher.decrypt(input_buf, output_buf, input_len, output_len); +} + diff --git a/enclave/sgxcode/enclave/common/file-encryptor.conf b/enclave/sgxcode/enclave/common/file-encryptor.conf new file mode 100644 index 000000000..10e63351b --- /dev/null +++ b/enclave/sgxcode/enclave/common/file-encryptor.conf @@ -0,0 +1,10 @@ +# Copyright (c) Open Enclave SDK contributors. +# Licensed under the MIT License. + +# Enclave settings: +Debug=1 +NumHeapPages=2048 +NumStackPages=1024 +NumTCS=2 +ProductID=1 +SecurityVersion=1 diff --git a/enclave/sgxcode/enclave/common/random.h b/enclave/sgxcode/enclave/common/random.h new file mode 100644 index 000000000..e69de29bb diff --git a/enclave/sgxcode/enclave/common/trace.h b/enclave/sgxcode/enclave/common/trace.h new file mode 100644 index 000000000..5d0df7e36 --- /dev/null +++ b/enclave/sgxcode/enclave/common/trace.h @@ -0,0 +1,5 @@ +// Copyright (c) Open Enclave SDK contributors. +// Licensed under the MIT License. + +#define TRACE_ENCLAVE(fmt, ...) \ + printf("Enclave: %s(%d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) diff --git a/enclave/sgxcode/enclave/decryptor_src/decryptor copy.cpp b/enclave/sgxcode/enclave/decryptor_src/decryptor copy.cpp new file mode 100644 index 000000000..a654ee85c --- /dev/null +++ b/enclave/sgxcode/enclave/decryptor_src/decryptor copy.cpp @@ -0,0 +1,139 @@ +#include "common/dispatcher.h" +#include "common/trace.h" +#include +#include +#include +#include +#include +#include + +using namespace std; + +// Generate an encryption key: this is the key used to encrypt data +int ecall_dispatcher::generate_key(size_t key_size) +{ + TRACE_ENCLAVE("generating encryption key"); + int ret = 0; + + RSA *keypair = RSA_generate_key(key_size, RSA_F4, NULL, NULL); + + BIO *pubBIO = BIO_new(BIO_s_mem()); + BIO *privBIO = BIO_new(BIO_s_mem()); + + PEM_write_bio_RSAPublicKey(pubBIO, keypair); + PEM_write_bio_RSAPrivateKey(privBIO, keypair, NULL, NULL, 0, NULL, NULL); + + pubLen = BIO_pending(pubBIO); + privLen = BIO_pending(privBIO); + + pubKeyData = new unsigned char[pubLen + 1]; + privKeyData = new unsigned char[privLen + 1]; + + BIO_read(pubBIO, pubKeyData, pubLen); + BIO_read(privBIO, privKeyData, privLen); + + pubKeyData[pubLen] = '\0'; + privKeyData[privLen] = '\0'; + + BIO_free_all(pubBIO); + BIO_free_all(privBIO); + +exit: + return ret; +} + +int ecall_dispatcher::update_key( + unsigned char* priv_key, + size_t priv_len, + unsigned char* pub_key, + size_t pub_len) +{ + delete[] privKeyData; + privKeyData = new unsigned char[priv_len + 1]; + privLen = priv_len; + memcpy(privKeyData, priv_key, priv_len); + + delete[] pubKeyData; + pubKeyData = new unsigned char[pub_len + 1]; + pubLen = pub_len; + memcpy(pubKeyData, pub_key, pub_len); +} + +RSA *load_key_from_memory(unsigned char *keydata, bool public_key) +{ + BIO *bio = BIO_new_mem_buf(keydata, -1); + RSA *key = NULL; + if (public_key) + { + PEM_read_bio_RSAPublicKey(bio, &key, NULL, NULL); + } + else + { + PEM_read_bio_RSAPrivateKey(bio, &key, NULL, NULL); + } + + BIO_free_all(bio); + return key; +} + + +int ecall_dispatcher::encrypt( + unsigned char *input_buf, + unsigned char **output_buf, + size_t input_len, + size_t *output_len) +{ + TRACE_ENCLAVE("encrypting data"); + int ret = 0; + + RSA *pub_key = load_key_from_memory(pubKeyData, true); + *output_buf = new unsigned char[RSA_size(pub_key)]; + + if (*output_buf == nullptr) { + delete[] *output_buf; + return -1; // Memory allocation failed + } + + int encrypt_length = RSA_public_encrypt(input_len, input_buf, *output_buf, pub_key, RSA_PKCS1_PADDING); + + if (encrypt_length == -1) { + TRACE_ENCLAVE("encrypting data failed"); + delete[] *output_buf; + return -1; // Encryption failed + } + + *output_len = encrypt_length; + + return ret; // success +} + + +int ecall_dispatcher::decrypt( + unsigned char *input_buf, + unsigned char **output_buf, + size_t input_len, + size_t *output_len) +{ + TRACE_ENCLAVE("decrypting data"); + int ret = 0; + + RSA *priv_key = load_key_from_memory(privKeyData, false); + *output_buf = new unsigned char[RSA_size(priv_key)]; + + if (*output_buf == nullptr) { + delete[] *output_buf; + return -1; // Memory allocation failed + } + + int decrypt_length = RSA_private_decrypt(input_len, input_buf, *output_buf, priv_key, RSA_PKCS1_PADDING); + + if (decrypt_length == -1) { + delete[] *output_buf; + return -1; // Encryption failed + } + + *output_len = decrypt_length; + + return ret; // success +} + diff --git a/enclave/sgxcode/enclave/decryptor_src/decryptor.cpp b/enclave/sgxcode/enclave/decryptor_src/decryptor.cpp new file mode 100644 index 000000000..5e239d910 --- /dev/null +++ b/enclave/sgxcode/enclave/decryptor_src/decryptor.cpp @@ -0,0 +1,224 @@ +#include "common/dispatcher.h" +#include "common/trace.h" +#include +#include +#include +#include +#include +#include + +using namespace std; + +// Generate an encryption key: this is the key used to encrypt data +int ecall_dispatcher::generate_key(size_t* key_size) +{ + TRACE_ENCLAVE("generating encryption key 1"); + ERR_load_crypto_strings(); + int ret = 0; + +/* + RSA *keypair = RSA_generate_key(*key_size, RSA_F4, NULL, NULL); + + BIO *pubBIO = BIO_new(BIO_s_mem()); + BIO *privBIO = BIO_new(BIO_s_mem()); + + PEM_write_bio_RSAPublicKey(pubBIO, keypair); + PEM_write_bio_RSAPrivateKey(privBIO, keypair, NULL, NULL, 0, NULL, NULL); + + pubLen = BIO_pending(pubBIO); + privLen = BIO_pending(privBIO); + + pubKeyData = new unsigned char[pubLen + 1]; + privKeyData = new unsigned char[privLen + 1]; + + BIO_read(pubBIO, pubKeyData, pubLen); + BIO_read(privBIO, privKeyData, privLen); + + pubKeyData[pubLen] = '\0'; + privKeyData[privLen] = '\0'; + + pubLen = BIO_pending(pubBIO); + privLen = BIO_pending(privBIO); + + BIO_free_all(pubBIO); + BIO_free_all(privBIO); +*/ + +{ + size_t pubLen_ = 426; + size_t privLen_ = 1679; + std::string pubKeyDataStr = R"(-----BEGIN RSA PUBLIC KEY----- +sample public key +-----END RSA PUBLIC KEY-----)"; + std::string privKeyDataStr = R"(-----BEGIN RSA PRIVATE KEY----- +sample private key +-----END RSA PRIVATE KEY-----)"; + + pubKeyData = new unsigned char[pubKeyDataStr.size() + 1]; + privKeyData = new unsigned char[privKeyDataStr.size() + 1]; + + std::memcpy(pubKeyData, pubKeyDataStr.c_str(), pubKeyDataStr.size() + 1); // 包括 null terminator + std::memcpy(privKeyData, privKeyDataStr.c_str(), privKeyDataStr.size() + 1); + + pubLen = pubKeyDataStr.size() + 1; + privLen = privKeyDataStr.size() + 1; +} + + TRACE_ENCLAVE("pubKeyData: \n%s",pubKeyData); + TRACE_ENCLAVE("privKeyData: \n%s",privKeyData); + TRACE_ENCLAVE("pubLen: %d",pubLen); + TRACE_ENCLAVE("privLen: %d",privLen); + + return ret; +} + +int ecall_dispatcher::update_key( + unsigned char* priv_key, + size_t priv_len, + unsigned char* pub_key, + size_t pub_len) +{ + delete[] privKeyData; + privKeyData = new unsigned char[priv_len + 1]; + privLen = priv_len; + memcpy(privKeyData, priv_key, priv_len); + + delete[] pubKeyData; + pubKeyData = new unsigned char[pub_len + 1]; + pubLen = pub_len; + memcpy(pubKeyData, pub_key, pub_len); +} + +RSA *load_key_from_memory(unsigned char *keydata, bool public_key) +{ + BIO *bio = BIO_new_mem_buf(keydata, -1); + RSA *key = NULL; + if (public_key) + { + PEM_read_bio_RSAPublicKey(bio, &key, NULL, NULL); + } + else + { + PEM_read_bio_RSAPrivateKey(bio, &key, NULL, NULL); + } + + BIO_free_all(bio); + return key; +} + +int ecall_dispatcher::get_pubkey( + unsigned char **key_buf, + size_t *key_len) +{ + TRACE_ENCLAVE("get_pubkey: \n%s",pubKeyData); + int ret = 0; + *key_buf = new unsigned char[pubLen + 1]; + std::memcpy(*key_buf, pubKeyData, pubLen); + (*key_buf)[pubLen] = '\0'; + *key_len = pubLen; + return ret; +} + + +int ecall_dispatcher::encrypt( + unsigned char *input_buf, + unsigned char **output_buf, + size_t input_len, + size_t *output_len) +{ + TRACE_ENCLAVE("encrypting data"); + int ret = 0; + + RSA *pub_key = load_key_from_memory(pubKeyData, true); + *output_buf = new unsigned char[RSA_size(pub_key)]; + + if (*output_buf == nullptr) { + delete[] *output_buf; + return -1; // Memory allocation failed + } + + int encrypt_length = RSA_public_encrypt(input_len, input_buf, *output_buf, pub_key, RSA_PKCS1_PADDING); + + if (encrypt_length == -1) { + TRACE_ENCLAVE("encrypting data failed"); + delete[] *output_buf; + return -1; // Encryption failed + } + + *output_len = encrypt_length; + + return ret; // success +} + + +// int ecall_dispatcher::decrypt( +// unsigned char *input_buf, +// unsigned char **output_buf, +// size_t input_len, +// size_t *output_len) +// { +// int ret = 0; + +// RSA *priv_key = load_key_from_memory(privKeyData, false); +// *output_buf = new unsigned char[RSA_size(priv_key)]; + +// if (*output_buf == nullptr) { +// delete[] *output_buf; +// return -1; // Memory allocation failed +// } + +// int decrypt_length = RSA_private_decrypt(input_len, input_buf, *output_buf, priv_key, RSA_PKCS1_PADDING); + +// if (decrypt_length == -1) { +// delete[] *output_buf; +// return -1; // Encryption failed +// } + +// *output_len = decrypt_length; + +// return ret; // succeed +// } + +int ecall_dispatcher::decrypt( + unsigned char *input_buf, + unsigned char **output_buf, + size_t input_len, + size_t *output_len) +{ + int ret = 0; + + RSA *priv_key = load_key_from_memory(privKeyData, false); + if (priv_key == nullptr) { + TRACE_ENCLAVE("Failed to load private key."); + return -1; + } + + int key_size = RSA_size(priv_key); + *output_buf = new unsigned char[key_size]; + if (*output_buf == nullptr) { + TRACE_ENCLAVE("Memory allocation failed."); + RSA_free(priv_key); + return -1; + } + + int decrypt_length = RSA_private_decrypt( + input_len, + input_buf, + *output_buf, + priv_key, + RSA_PKCS1_PADDING); + + if (decrypt_length == -1) { + unsigned long err = ERR_get_error(); + char err_msg[120]; + ERR_error_string(err, err_msg); + TRACE_ENCLAVE("Decryption failed: %s",err_msg); + delete[] *output_buf; + RSA_free(priv_key); + return -1; // Decryption failed + } + + *output_len = decrypt_length; + RSA_free(priv_key); + return ret; // Success +} diff --git a/enclave/sgxcode/enclave/random_src/random.cpp b/enclave/sgxcode/enclave/random_src/random.cpp new file mode 100644 index 000000000..d33020f7b --- /dev/null +++ b/enclave/sgxcode/enclave/random_src/random.cpp @@ -0,0 +1,63 @@ +#include "common/dispatcher.h" +#include "common/trace.h" + +int ecall_dispatcher::reset_prng(uint32_t* seed, uint32_t* range) { + int ret = 0; + // TRACE_ENCLAVE("ecall_dispatcher::set_seed"); + + this->seed = *seed; + this->range = *range; + eng.seed(*seed); + this->randUseCount = 0; + +exit: + return ret; +} + +int ecall_dispatcher::generate_rdrand(uint32_t* rdrandNum) { + int ret = 0; + // TRACE_ENCLAVE("ecall_dispatcher::generate_rdrand"); + + *rdrandNum = rd(); + +exit: + return ret; +} + +int ecall_dispatcher::generate_rand(size_t previous_size, + size_t limit_count, + uint32_t* counter_value_array, + size_t * buffer_size_array, + unsigned char ** previous_attestation, + uint32_t* randNum) { + int ret = 0; + // TRACE_ENCLAVE("ecall_dispatcher::generate_rdrand"); + + // TRACE_ENCLAVE("counter_value:%d, randUseCount:%d, generate_rand",counter_value_array[0],randUseCount); + + if (randUseCount != 0 && previous_size < limit_count) { + TRACE_ENCLAVE("%d,%d: Insufficient previous cert number",previous_size,limit_count); + goto exit; + } + + // Check previous counter info and attestation here + for (size_t i = 0; i < previous_size; i++) + { + if (!std::strncmp((const char*)previous_attestation[i], "Fake Attestation", buffer_size_array[i]) == 0) { + TRACE_ENCLAVE("Could not verify the attestation"); + goto exit; + } + if (counter_value_array[i]/3 + 1 != randUseCount) { + TRACE_ENCLAVE("counter_value:%d, randUseCount:%d, Counter value invalid",counter_value_array[i],randUseCount); + goto exit; + } + // TRACE_ENCLAVE("previous_size: %d, counter: %d, attestation: %.*s", previous_size, + // counter_value_array[i], buffer_size_array[i], previous_attestation[i]); + } + + *randNum = eng() % range; + randUseCount++; + +exit: + return ret; +} diff --git a/enclave/sgxcode/enclave/sgx_cpp.edl b/enclave/sgxcode/enclave/sgx_cpp.edl new file mode 100644 index 000000000..149327118 --- /dev/null +++ b/enclave/sgxcode/enclave/sgx_cpp.edl @@ -0,0 +1,45 @@ +// Copyright (c) Open Enclave SDK contributors. +// Licensed under the MIT License. + +enclave { + from "openenclave/edl/syscall.edl" import *; + from "platform.edl" import *; + + + trusted { + public int request_counter([out] uint32_t* index); + public int get_counter([in] uint32_t* index, + size_t previous_size, + size_t limit_count, + [user_check] uint32_t* counter_value_array, + [user_check] size_t* buffer_size_array, + [user_check] unsigned char** previous_attestation, + [out] uint32_t* counter_value); + + public int reset_prng([in] uint32_t* seed, [in] uint32_t* range); + public int generate_rdrand([out] uint32_t* rdrandNum); + public int generate_rand(size_t input_len, + size_t limit_count, + [user_check] uint32_t* counter_value_array, + [user_check] size_t* buffer_size_array, + [user_check] unsigned char** previous_attestation, + [out] uint32_t* randNum); + + public int generate_key([in] size_t *key_size); + public int update_key([in] unsigned char* priv_key, size_t priv_len, + [in] unsigned char* pub_key, size_t pub_len); + public int get_pubkey([user_check] unsigned char** key_buf, + [out] size_t* key_len); + public int encrypt([user_check] unsigned char* input_buf, + [user_check] unsigned char** output_buf, + size_t input_len, size_t* output_len); + public int decrypt([user_check] unsigned char* input_buf, + [user_check] unsigned char** output_buf, + size_t input_len, size_t* output_len); + }; + + //untrusted { + // no untrusted functions in this sample + //}; +}; + diff --git a/enclave/sgxcode/enclave/simulated_counter_src/simulated_counter.cpp b/enclave/sgxcode/enclave/simulated_counter_src/simulated_counter.cpp new file mode 100644 index 000000000..351fba954 --- /dev/null +++ b/enclave/sgxcode/enclave/simulated_counter_src/simulated_counter.cpp @@ -0,0 +1,59 @@ +#include "common/dispatcher.h" +#include "common/trace.h" +#include + +int ecall_dispatcher::request_counter(uint32_t* index) { + int ret = 0; + // TRACE_ENCLAVE("ecall_dispatcher::request_counter"); + + counters.push_back(0); + *index = counterNum; + counterNum++; + +exit: + return ret; +} + +int ecall_dispatcher::get_counter( + uint32_t* index, + size_t previous_size, + size_t limit_count, + uint32_t* counter_value_array, + size_t * buffer_size_array, + unsigned char ** previous_attestation, + uint32_t* counter_value) { + + int ret = 0; + + if (counters[*index]!=0 && previous_size < limit_count) { + TRACE_ENCLAVE("%d,%d: Insufficient previous cert number",previous_size,limit_count); + goto exit; + } + + // Check previous counter info and attestation here + for (size_t i = 0; i < previous_size; i++) + { + if (!std::strncmp((const char*)previous_attestation[i], "Fake Attestation", buffer_size_array[i]) == 0) { + TRACE_ENCLAVE("Could not verify the attestation"); + goto exit; + } + if (counter_value_array[i] != counters[*index] - 1) { + TRACE_ENCLAVE("Counter value invalid"); + goto exit; + } + // TRACE_ENCLAVE("previous_size: %d, counter: %d, attestation: %.*s", previous_size, + // counter_value_array[i], buffer_size_array[i], previous_attestation[i]); + } + // */ + + if (*index < 0 || *index >= counterNum) { + // TRACE_ENCLAVE("Counter index out of range"); + goto exit; + } + + *counter_value = counters[*index]; + counters[*index]++; + +exit: + return ret; +} diff --git a/enclave/sgxcode/host/CMakeLists.txt b/enclave/sgxcode/host/CMakeLists.txt new file mode 100644 index 000000000..b5faeed2c --- /dev/null +++ b/enclave/sgxcode/host/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright (c) Open Enclave SDK contributors. +# Licensed under the MIT License. + +add_custom_command( + OUTPUT sgx_cpp_u.h sgx_cpp_u.c sgx_cpp_args.h + DEPENDS ${CMAKE_SOURCE_DIR}/enclave/sgx_cpp.edl + COMMAND + openenclave::oeedger8r --untrusted ${CMAKE_SOURCE_DIR}/enclave/sgx_cpp.edl + --search-path ${OE_INCLUDEDIR} --search-path + ${OE_INCLUDEDIR}/openenclave/edl/sgx) + +add_executable(sgxhost + host.cpp ${CMAKE_CURRENT_BINARY_DIR}/sgx_cpp_u.c) + +if (WIN32) + copy_oedebugrt_target(sgxhost_oedebugrt) + add_dependencies(sgxhost sgxhost_oedebugrt) +endif () + +target_include_directories( + sgxhost + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} # Needed for #include "../shared.h" + ${CMAKE_CURRENT_BINARY_DIR}) + +target_link_libraries(sgxhost openenclave::oehost) diff --git a/enclave/sgxcode/host/Makefile b/enclave/sgxcode/host/Makefile new file mode 100644 index 000000000..79719228a --- /dev/null +++ b/enclave/sgxcode/host/Makefile @@ -0,0 +1,24 @@ +# Copyright (c) Open Enclave SDK contributors. +# Licensed under the MIT License. + +include ../../config.mk + +CFLAGS=$(shell pkg-config oehost-$(C_COMPILER) --cflags) +CXXFLAGS=$(shell pkg-config oehost-$(CXX_COMPILER) --cflags) +LDFLAGS=$(shell pkg-config oehost-$(CXX_COMPILER) --libs) +INCDIR=$(shell pkg-config oehost-$(C_COMPILER) --variable=includedir) + +all: build + +build: + @ echo "Compilers used: $(CC), $(CXX)" + oeedger8r ../enclave/sgx_cpp.edl --untrusted \ + --search-path $(INCDIR) \ + --search-path $(INCDIR)/openenclave/edl/sgx + $(CXX) -g -c $(CXXFLAGS) host.cpp + $(CC) -g -c $(CFLAGS) sgx_cpp_u.c + $(CXX) -o file-encryptorhost host.o sgx_cpp_u.o $(LDFLAGS) + +clean: + rm -f file-encryptorhost sgx_cpp_u.* sgx_cpp_args.h *.o ../out.decrypted ../out.encrypted + diff --git a/enclave/sgxcode/host/host.cpp b/enclave/sgxcode/host/host.cpp new file mode 100644 index 000000000..8ff11d940 --- /dev/null +++ b/enclave/sgxcode/host/host.cpp @@ -0,0 +1,278 @@ +// Copyright (c) Open Enclave SDK contributors. +// Licensed under the MIT License. + +// Note: Only for testing enclave ! + +#include +#include +#include +#include +#include +#include "sgx_cpp_u.h" + +using namespace std; + +#define CIPHER_BLOCK_SIZE 16 +#define DATA_BLOCK_SIZE 256 +#define ENCRYPT_OPERATION true +#define DECRYPT_OPERATION false + +oe_enclave_t *enclave = NULL; + +bool check_simulate_opt(int *argc, const char *argv[]) +{ + for (int i = 0; i < *argc; i++) + { + if (strcmp(argv[i], "--simulate") == 0) + { + cout << "Running in simulation mode" << endl; + memmove(&argv[i], &argv[i + 1], (*argc - i) * sizeof(char *)); + (*argc)--; + return true; + } + } + return false; +} + +void printHex(unsigned char* data, size_t length) { + cout << "{"; + for (size_t i = 0; i < length; ++i) { + printf("0x%02x ", data[i]); + } + ::cout << "}" << endl; +} + + +int main(int argc, const char *argv[]) +{ + oe_result_t result; + int ret = 0; + uint32_t flags = OE_ENCLAVE_FLAG_DEBUG; + + if (check_simulate_opt(&argc, argv)) + { + flags |= OE_ENCLAVE_FLAG_SIMULATE; + } + + cout << "Host: enter main" << endl; + if (argc != 2) + { + cerr << "Usage: " << argv[0] + << " enclave_image_path [ --simulate ]" << endl; + return 1; + } + + cout << "Host: create enclave for image:" << argv[1] << endl; + result = oe_create_sgx_cpp_enclave( + argv[1], OE_ENCLAVE_TYPE_SGX, flags, NULL, 0, &enclave); + if (result != OE_OK) + { + cerr << "oe_create_sgx_cpp_enclave() failed with " << argv[0] + << " " << result << endl; + ret = 1; + // goto exit; + } + + // counter test + { + // request a counter + cout << "Host: requesting a counter:" << endl; + uint32_t index = -1; + result = request_counter(enclave, &ret, &index); + if (result != OE_OK) + { + ret = 1; + // goto exit; + } + if (ret != 0) + { + cerr << "Host: request_counter failed with " << ret << endl; + // goto exit; + } + + // request a counter + cout << "Host: requesting a counter:" << endl; + uint32_t index2 = -1; + result = request_counter(enclave, &ret, &index2); + if (result != OE_OK) + { + ret = 1; + // goto exit; + } + if (ret != 0) + { + cerr << "Host: request_counter failed with " << ret << endl; + // goto exit; + } + + // get the counter + uint32_t value = -1; + result = get_counter(enclave, &ret, &index, 0, 0, nullptr, nullptr, nullptr, &value); + if (result != OE_OK) + { + ret = 1; + // goto exit; + } + if (ret != 0) + { + cerr << "Host: get_counter failed with " << ret + << endl; + // goto exit; + } + cout << "Host: get the " << index << "th counter, value: " << value << endl; + + // get the counter + result = get_counter(enclave, &ret, &index2, 0, 0, nullptr, nullptr, nullptr, &value); + if (result != OE_OK) + { + ret = 1; + // goto exit; + } + if (ret != 0) + { + cerr << "Host: get_counter failed with " << ret + << endl; + // goto exit; + } + cout << "Host: get the " << index2 << "th counter, value: " << value << endl; + + // get the counter + result = get_counter(enclave, &ret, &index, 0, 0, nullptr, nullptr, nullptr, &value); + if (result != OE_OK) + { + ret = 1; + // goto exit; + } + if (ret != 0) + { + cerr << "Host: get_counter failed with " << ret + << endl; + // goto exit; + } + cout << "Host: get the " << index << "th counter, value: " << value << endl; + } + + // random test + { + // generate random device rand + cout << "Host: generate random device rand:" << endl; + uint32_t rdrandNum = -1; + result = generate_rdrand(enclave, &ret, &rdrandNum); + if (result != OE_OK) + { + ret = 1; + // goto exit; + } + if (ret != 0) + { + cerr << "Host: reset_prng failed with " << ret << endl; + // goto exit; + } + cout << "Host: get the rdrandNum: " << rdrandNum << endl; + + // reset prng + cout << "Host: reset prng:" << endl; + uint32_t range = 50; + result = reset_prng(enclave, &ret, &rdrandNum, &range); + if (result != OE_OK) + { + ret = 1; + // goto exit; + } + if (ret != 0) + { + cerr << "Host: reset_prng failed with " << ret << endl; + // goto exit; + } + cout << "Host: reset prng." << endl; + + // generate random device rand + cout << "Host: generate random from prng:" << endl; + uint32_t randNum = -1; + for (size_t i = 0; i < 10; i++) + { + result = generate_rand(enclave, &ret, 0, 0, nullptr, nullptr, nullptr, &randNum); + cout << "Host: get the randNum: " << randNum << endl; + } + if (result != OE_OK) + { + ret = 1; + // goto exit; + } + if (ret != 0) + { + cerr << "Host: reset_prng failed with " << ret << endl; + // goto exit; + } + } + +/* + // decryptor test + { + cout << "Host: generate key" << endl; + size_t key_size = 2048; + result = generate_key(enclave, &ret, &key_size); + if (result != OE_OK) + { + ret = 1; + // goto exit; + } + if (ret != 0) + { + cerr << "Host: generate_key failed with " << ret << endl; + // goto exit; + } + + // Simulating binary data + unsigned char binary_data[] = {0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe}; + int data_len = sizeof(binary_data) / sizeof(binary_data[0]); + + unsigned char* key_buf; + size_t key_len = 0; + result = get_pubkey(enclave, &ret, &key_buf, &key_len); + + BIO *bio = BIO_new_mem_buf(key_buf, -1); + RSA *pub_key = NULL; + PEM_read_bio_RSAPublicKey(bio, &pub_key, NULL, NULL); + + size_t encrypted_len = RSA_size(pub_key); + unsigned char* encrypted_data = new unsigned char[encrypted_len]; // Initialize buffer + std::cout<<"Before RSA_public_encrypt."; + size_t result_len = RSA_public_encrypt(data_len, binary_data, encrypted_data, + pub_key, RSA_PKCS1_PADDING); + std::cout<<"After RSA_public_encrypt."; + cout << "Host: encrypt data" << endl; + BIO_free_all(bio); + + cout << "Host: decrypt data" << endl; + unsigned char * decrypted_data; + size_t decrypted_len; + result = decrypt(enclave, &ret, encrypted_data, &decrypted_data, encrypted_len, &decrypted_len); + if (result != OE_OK) + { + ret = 1; + // goto exit; + } + if (ret != 0) + { + cerr << "Host: decrypt failed with " << ret << endl; + // goto exit; + } + + printHex(binary_data, data_len); + printHex(decrypted_data, decrypted_len); + std::cout << "Decrypted data matches original: " << (memcmp(binary_data, decrypted_data, decrypted_len) == 0) << std::endl; + + } +*/ + +exit: + cout << "Host: terminate the enclave" << endl; + cout << "Host: Sample completed successfully." << endl; + oe_terminate_enclave(enclave); + return ret; +} + + +// Command: +// g++ host.cpp /root/code_dev/tee-code/sgx_cpp/build/host/sgx_cpp_u.c -I/root/code_dev/tee-code/sgx_cpp/build/host -I/opt/openenclave_0_17_0/include/ -L/opt/openenclave_0_17_0/lib/openenclave/host/ -loehost -lcrypto -ldl -lpthread diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 000000000..a5ef6599c --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +./service/tools/kv/server_tools/start_kv_service.sh +tail -f /dev/null \ No newline at end of file diff --git a/executor/common/custom_query.h b/executor/common/custom_query.h index e574a98dd..2c8bf4a7a 100644 --- a/executor/common/custom_query.h +++ b/executor/common/custom_query.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/executor/common/mock_transaction_manager.h b/executor/common/mock_transaction_manager.h index 86972f662..b4a6ba532 100644 --- a/executor/common/mock_transaction_manager.h +++ b/executor/common/mock_transaction_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/executor/common/transaction_manager.cpp b/executor/common/transaction_manager.cpp index 854715863..74df05c9c 100644 --- a/executor/common/transaction_manager.cpp +++ b/executor/common/transaction_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/common/transaction_manager.h" @@ -41,6 +35,50 @@ std::unique_ptr TransactionManager::ExecuteData( return std::make_unique(); } +std::unique_ptr TransactionManager::ParseData( + const std::string& data) { + return nullptr; +} + +std::unique_ptr>> +TransactionManager::Prepare(const BatchUserRequest& request) { + std::unique_ptr>> + batch_response = std::make_unique< + std::vector>>(); + { + for (auto& sub_request : request.user_requests()) { + std::unique_ptr response = + ParseData(sub_request.request().data()); + batch_response->push_back(std::move(response)); + } + // LOG(ERROR)<<"prepare data size:"< TransactionManager::ExecuteRequest( + const google::protobuf::Message& request) { + return nullptr; +} + +std::vector> TransactionManager::ExecuteBatchData( + const std::vector>& requests) { + // LOG(ERROR)<<"execute data:"<> ret; + { + for (auto& sub_request : requests) { + std::unique_ptr response = ExecuteRequest(*sub_request); + if (response == nullptr) { + response = std::make_unique(); + } + ret.push_back(std::move(response)); + } + } + return ret; +} + + std::unique_ptr TransactionManager::ExecuteBatch( const BatchUserRequest& request) { std::unique_ptr batch_response = diff --git a/executor/common/transaction_manager.h b/executor/common/transaction_manager.h index 7e243f97a..b1d564ac6 100644 --- a/executor/common/transaction_manager.h +++ b/executor/common/transaction_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once @@ -46,6 +40,11 @@ class TransactionManager { virtual std::unique_ptr ExecuteBatch( const BatchUserRequest& request); + std::unique_ptr>> + Prepare(const BatchUserRequest& request); + + std::vector> ExecuteBatchData( + const std::vector>& requests); virtual std::unique_ptr ExecuteData(const std::string& request); bool IsOutOfOrder(); @@ -54,6 +53,11 @@ class TransactionManager { virtual Storage* GetStorage() { return nullptr; }; + protected: + virtual std::unique_ptr ParseData( + const std::string& data); + virtual std::unique_ptr ExecuteRequest( + const google::protobuf::Message& request); private: bool is_out_of_order_ = false; bool need_response_ = true; diff --git a/executor/contract/executor/contract_executor.cpp b/executor/contract/executor/contract_executor.cpp index 6e8c994a0..6db35ad71 100644 --- a/executor/contract/executor/contract_executor.cpp +++ b/executor/contract/executor/contract_executor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/contract/executor/contract_executor.h" diff --git a/executor/contract/executor/contract_executor.h b/executor/contract/executor/contract_executor.h index 8c2a50c80..c902e2977 100644 --- a/executor/contract/executor/contract_executor.h +++ b/executor/contract/executor/contract_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/executor/contract/executor/contract_executor_test.cpp b/executor/contract/executor/contract_executor_test.cpp index 5d29333dd..b8b63aec5 100644 --- a/executor/contract/executor/contract_executor_test.cpp +++ b/executor/contract/executor/contract_executor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/contract/executor/contract_executor.h" diff --git a/executor/contract/manager/address_manager.cpp b/executor/contract/manager/address_manager.cpp index e155d9f83..2a886dac5 100644 --- a/executor/contract/manager/address_manager.cpp +++ b/executor/contract/manager/address_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/contract/manager/address_manager.h" diff --git a/executor/contract/manager/address_manager.h b/executor/contract/manager/address_manager.h index b0446503c..4e6055aad 100644 --- a/executor/contract/manager/address_manager.h +++ b/executor/contract/manager/address_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/executor/contract/manager/address_manager_test.cpp b/executor/contract/manager/address_manager_test.cpp index 08287b622..21fd9044c 100644 --- a/executor/contract/manager/address_manager_test.cpp +++ b/executor/contract/manager/address_manager_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/contract/manager/address_manager.h" diff --git a/executor/contract/manager/contract_manager.cpp b/executor/contract/manager/contract_manager.cpp index 3b8ff11c5..426a0b8a3 100644 --- a/executor/contract/manager/contract_manager.cpp +++ b/executor/contract/manager/contract_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/contract/manager/contract_manager.h" diff --git a/executor/contract/manager/contract_manager.h b/executor/contract/manager/contract_manager.h index b645d7286..7e250aa60 100644 --- a/executor/contract/manager/contract_manager.h +++ b/executor/contract/manager/contract_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/executor/contract/manager/contract_manager_test.cpp b/executor/contract/manager/contract_manager_test.cpp index 7b7cc32db..23746b49a 100644 --- a/executor/contract/manager/contract_manager_test.cpp +++ b/executor/contract/manager/contract_manager_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/contract/manager/contract_manager.h" diff --git a/executor/contract/manager/utils.h b/executor/contract/manager/utils.h index 2d243d66f..ff9548ca3 100644 --- a/executor/contract/manager/utils.h +++ b/executor/contract/manager/utils.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/executor/kv/BUILD b/executor/kv/BUILD index 9117dd93b..85a5e2168 100644 --- a/executor/kv/BUILD +++ b/executor/kv/BUILD @@ -2,40 +2,12 @@ package(default_visibility = ["//visibility:public"]) load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") -bool_flag( - name = "enable_leveldb", - build_setting_default = False, - visibility = ["//visibility:public"], -) - -bool_flag( - name = "enable_rocksdb", - build_setting_default = False, - visibility = ["//visibility:public"], -) - -config_setting( - name = "enable_leveldb_setting", - values = { - "define": "enable_leveldb=True", - }, - visibility = ["//visibility:public"], -) - -config_setting( - name = "enable_rocksdb_setting", - values = { - "define": "enable_rocksdb=True", - }, - visibility = ["//visibility:public"], -) - cc_library( name = "kv_executor", srcs = ["kv_executor.cpp"], hdrs = ["kv_executor.h"], deps = [ - "//chain/state:chain_state", + "//chain/storage", "//common:comm", "//executor/common:transaction_manager", "//platform/config:resdb_config_utils", @@ -48,7 +20,7 @@ cc_test( srcs = ["kv_executor_test.cpp"], deps = [ ":kv_executor", - "//chain/storage:mock_storage", + "//chain/storage:memory_db", "//common/test:test_main", ], ) diff --git a/executor/kv/kv_executor.cpp b/executor/kv/kv_executor.cpp index 8d2ecf557..ff375264f 100644 --- a/executor/kv/kv_executor.cpp +++ b/executor/kv/kv_executor.cpp @@ -1,38 +1,80 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/kv/kv_executor.h" #include -#include "proto/kv/kv.pb.h" - namespace resdb { -KVExecutor::KVExecutor(std::unique_ptr state) - : state_(std::move(state)) {} +KVExecutor::KVExecutor(std::unique_ptr storage) + : storage_(std::move(storage)) {} + +std::unique_ptr KVExecutor::ParseData( + const std::string& request) { + std::unique_ptr kv_request = std::make_unique(); + if (!kv_request->ParseFromString(request)) { + LOG(ERROR) << "parse data fail in KVExecutor!"; + return nullptr; + } + return kv_request; +} + +std::unique_ptr KVExecutor::ExecuteRequest( + const google::protobuf::Message& request) { + KVResponse kv_response; + const KVRequest& kv_request = dynamic_cast(request); + // LOG(ERROR)<<"execute request:"; + + if (kv_request.cmd() == KVRequest::SET) { + Set(kv_request.key(), kv_request.value()); + } else if (kv_request.cmd() == KVRequest::GET) { + kv_response.set_value(Get(kv_request.key())); + } else if (kv_request.cmd() == KVRequest::GETALLVALUES) { + kv_response.set_value(GetAllValues()); + } else if (kv_request.cmd() == KVRequest::GETRANGE) { + kv_response.set_value(GetRange(kv_request.key(), kv_request.value())); + } else if (kv_request.cmd() == KVRequest::SET_WITH_VERSION) { + SetWithVersion(kv_request.key(), kv_request.value(), kv_request.version()); + } else if (kv_request.cmd() == KVRequest::GET_WITH_VERSION) { + GetWithVersion(kv_request.key(), kv_request.version(), + kv_response.mutable_value_info()); + } else if (kv_request.cmd() == KVRequest::GET_ALL_ITEMS) { + GetAllItems(kv_response.mutable_items()); + } else if (kv_request.cmd() == KVRequest::GET_KEY_RANGE) { + GetKeyRange(kv_request.min_key(), kv_request.max_key(), + kv_response.mutable_items()); + } else if (kv_request.cmd() == KVRequest::GET_HISTORY) { + GetHistory(kv_request.key(), kv_request.min_version(), + kv_request.max_version(), kv_response.mutable_items()); + } else if (kv_request.cmd() == KVRequest::GET_TOP) { + GetTopHistory(kv_request.key(), kv_request.top_number(), + kv_response.mutable_items()); + } + + std::unique_ptr resp_str = std::make_unique(); + if (!kv_response.SerializeToString(resp_str.get())) { + return nullptr; + } + + return resp_str; +} std::unique_ptr KVExecutor::ExecuteData( const std::string& request) { @@ -40,7 +82,7 @@ std::unique_ptr KVExecutor::ExecuteData( KVResponse kv_response; if (!kv_request.ParseFromString(request)) { - LOG(ERROR) << "parse data fail"; + LOG(ERROR) << "parse data fail in KVExecutor!"; return nullptr; } @@ -48,34 +90,108 @@ std::unique_ptr KVExecutor::ExecuteData( Set(kv_request.key(), kv_request.value()); } else if (kv_request.cmd() == KVRequest::GET) { kv_response.set_value(Get(kv_request.key())); - } else if (kv_request.cmd() == KVRequest::GETVALUES) { - kv_response.set_value(GetValues()); + } else if (kv_request.cmd() == KVRequest::GETALLVALUES) { + kv_response.set_value(GetAllValues()); } else if (kv_request.cmd() == KVRequest::GETRANGE) { kv_response.set_value(GetRange(kv_request.key(), kv_request.value())); + } else if (kv_request.cmd() == KVRequest::SET_WITH_VERSION) { + SetWithVersion(kv_request.key(), kv_request.value(), kv_request.version()); + } else if (kv_request.cmd() == KVRequest::GET_WITH_VERSION) { + GetWithVersion(kv_request.key(), kv_request.version(), + kv_response.mutable_value_info()); + } else if (kv_request.cmd() == KVRequest::GET_ALL_ITEMS) { + GetAllItems(kv_response.mutable_items()); + } else if (kv_request.cmd() == KVRequest::GET_KEY_RANGE) { + GetKeyRange(kv_request.min_key(), kv_request.max_key(), + kv_response.mutable_items()); + } else if (kv_request.cmd() == KVRequest::GET_HISTORY) { + GetHistory(kv_request.key(), kv_request.min_version(), + kv_request.max_version(), kv_response.mutable_items()); + } else if (kv_request.cmd() == KVRequest::GET_TOP) { + GetTopHistory(kv_request.key(), kv_request.top_number(), + kv_response.mutable_items()); } std::unique_ptr resp_str = std::make_unique(); if (!kv_response.SerializeToString(resp_str.get())) { return nullptr; } - return resp_str; } void KVExecutor::Set(const std::string& key, const std::string& value) { - state_->SetValue(key, value); + storage_->SetValue(key, value); } std::string KVExecutor::Get(const std::string& key) { - return state_->GetValue(key); + return storage_->GetValue(key); } -std::string KVExecutor::GetValues() { return state_->GetAllValues(); } +std::string KVExecutor::GetAllValues() { return storage_->GetAllValues(); } // Get values on a range of keys std::string KVExecutor::GetRange(const std::string& min_key, const std::string& max_key) { - return state_->GetRange(min_key, max_key); + return storage_->GetRange(min_key, max_key); +} + +void KVExecutor::SetWithVersion(const std::string& key, + const std::string& value, int version) { + storage_->SetValueWithVersion(key, value, version); +} + +void KVExecutor::GetWithVersion(const std::string& key, int version, + ValueInfo* info) { + std::pair ret = storage_->GetValueWithVersion(key, version); + info->set_value(ret.first); + info->set_version(ret.second); +} + +void KVExecutor::GetAllItems(Items* items) { + const std::map>& ret = + storage_->GetAllItems(); + for (auto it : ret) { + Item* item = items->add_item(); + item->set_key(it.first); + item->mutable_value_info()->set_value(it.second.first); + item->mutable_value_info()->set_version(it.second.second); + } +} + +void KVExecutor::GetKeyRange(const std::string& min_key, + const std::string& max_key, Items* items) { + const std::map>& ret = + storage_->GetKeyRange(min_key, max_key); + for (auto it : ret) { + Item* item = items->add_item(); + item->set_key(it.first); + item->mutable_value_info()->set_value(it.second.first); + item->mutable_value_info()->set_version(it.second.second); + } +} + +void KVExecutor::GetHistory(const std::string& key, int min_version, + int max_version, Items* items) { + const std::vector>& ret = + storage_->GetHistory(key, min_version, max_version); + for (auto it : ret) { + Item* item = items->add_item(); + item->set_key(key); + item->mutable_value_info()->set_value(it.first); + item->mutable_value_info()->set_version(it.second); + } +} + +void KVExecutor::GetTopHistory(const std::string& key, int top_number, + Items* items) { + const std::vector>& ret = + storage_->GetTopHistory(key, top_number); + for (auto it : ret) { + Item* item = items->add_item(); + item->set_key(key); + item->mutable_value_info()->set_value(it.first); + item->mutable_value_info()->set_version(it.second); + } } } // namespace resdb diff --git a/executor/kv/kv_executor.h b/executor/kv/kv_executor.h index 58392f03f..fb1bcde4e 100644 --- a/executor/kv/kv_executor.h +++ b/executor/kv/kv_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once @@ -29,27 +23,41 @@ #include #include -#include "chain/state/chain_state.h" +#include "chain/storage/storage.h" #include "executor/common/transaction_manager.h" -#include "platform/config/resdb_config_utils.h" +#include "proto/kv/kv.pb.h" namespace resdb { class KVExecutor : public TransactionManager { public: - KVExecutor(std::unique_ptr state); + KVExecutor(std::unique_ptr storage); virtual ~KVExecutor() = default; std::unique_ptr ExecuteData(const std::string& request) override; + std::unique_ptr ParseData( + const std::string& request) override; + std::unique_ptr ExecuteRequest( + const google::protobuf::Message& kv_request) override; protected: virtual void Set(const std::string& key, const std::string& value); std::string Get(const std::string& key); - std::string GetValues(); + std::string GetAllValues(); std::string GetRange(const std::string& min_key, const std::string& max_key); + void SetWithVersion(const std::string& key, const std::string& value, + int version); + void GetWithVersion(const std::string& key, int version, ValueInfo* info); + void GetAllItems(Items* items); + void GetKeyRange(const std::string& min_key, const std::string& max_key, + Items* items); + void GetHistory(const std::string& key, int min_key, int max_key, + Items* items); + void GetTopHistory(const std::string& key, int top_number, Items* items); + private: - std::unique_ptr state_; + std::unique_ptr storage_; }; } // namespace resdb diff --git a/executor/kv/kv_executor_test.cpp b/executor/kv/kv_executor_test.cpp index 17b32a46b..9bf78dc4c 100644 --- a/executor/kv/kv_executor_test.cpp +++ b/executor/kv/kv_executor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/kv/kv_executor.h" @@ -28,13 +22,17 @@ #include #include -#include "chain/storage/mock_storage.h" +#include "chain/storage/memory_db.h" +#include "chain/storage/storage.h" +#include "common/test/test_macros.h" #include "platform/config/resdb_config_utils.h" #include "proto/kv/kv.pb.h" namespace resdb { namespace { +using ::resdb::testing::EqualsProto; +using storage::MemoryDB; using ::testing::Invoke; using ::testing::Return; using ::testing::Test; @@ -42,10 +40,9 @@ using ::testing::Test; class KVExecutorTest : public Test { public: KVExecutorTest() { - auto mock_storage = std::make_unique(); - mock_storage_ptr_ = mock_storage.get(); - impl_ = std::make_unique( - std::make_unique(std::move(mock_storage))); + auto storage = std::make_unique(); + storage_ptr_ = storage.get(); + impl_ = std::make_unique(std::move(storage)); } int Set(const std::string& key, const std::string& value) { @@ -83,9 +80,9 @@ class KVExecutorTest : public Test { return kv_response.value(); } - std::string GetValues() { + std::string GetAllValues() { KVRequest request; - request.set_cmd(KVRequest::GETVALUES); + request.set_cmd(KVRequest::GETALLVALUES); std::string str; if (!request.SerializeToString(&str)) { @@ -123,8 +120,115 @@ class KVExecutorTest : public Test { return kv_response.value(); } + int Set(const std::string& key, const std::string& value, int version) { + KVRequest request; + request.set_cmd(KVRequest::SET_WITH_VERSION); + request.set_key(key); + request.set_value(value); + request.set_version(version); + + std::string str; + if (!request.SerializeToString(&str)) { + return -1; + } + + impl_->ExecuteData(str); + return 0; + } + + ValueInfo Get(const std::string& key, int version) { + KVRequest request; + request.set_cmd(KVRequest::GET_WITH_VERSION); + request.set_key(key); + request.set_version(version); + + std::string str; + if (!request.SerializeToString(&str)) { + return ValueInfo(); + } + + auto resp = impl_->ExecuteData(str); + if (resp == nullptr) { + return ValueInfo(); + } + KVResponse kv_response; + if (!kv_response.ParseFromString(*resp)) { + return ValueInfo(); + } + + return kv_response.value_info(); + } + + Items GetAllItems() { + KVRequest request; + request.set_cmd(KVRequest::GET_ALL_ITEMS); + + std::string str; + if (!request.SerializeToString(&str)) { + return Items(); + } + + auto resp = impl_->ExecuteData(str); + if (resp == nullptr) { + return Items(); + } + KVResponse kv_response; + if (!kv_response.ParseFromString(*resp)) { + return Items(); + } + + return kv_response.items(); + } + + Items GetKeyRange(const std::string& min_key, const std::string& max_key) { + KVRequest request; + request.set_cmd(KVRequest::GET_KEY_RANGE); + request.set_min_key(min_key); + request.set_max_key(max_key); + + std::string str; + if (!request.SerializeToString(&str)) { + return Items(); + } + + auto resp = impl_->ExecuteData(str); + if (resp == nullptr) { + return Items(); + } + KVResponse kv_response; + if (!kv_response.ParseFromString(*resp)) { + return Items(); + } + + return kv_response.items(); + } + + Items GetHistory(const std::string& key, int min_version, int max_version) { + KVRequest request; + request.set_cmd(KVRequest::GET_HISTORY); + request.set_key(key); + request.set_min_version(min_version); + request.set_max_version(max_version); + + std::string str; + if (!request.SerializeToString(&str)) { + return Items(); + } + + auto resp = impl_->ExecuteData(str); + if (resp == nullptr) { + return Items(); + } + KVResponse kv_response; + if (!kv_response.ParseFromString(*resp)) { + return Items(); + } + + return kv_response.items(); + } + protected: - MockStorage* mock_storage_ptr_; + Storage* storage_ptr_; private: std::unique_ptr impl_; @@ -133,33 +237,105 @@ class KVExecutorTest : public Test { TEST_F(KVExecutorTest, SetValue) { std::map data; - EXPECT_CALL(*mock_storage_ptr_, SetValue("test_key", "test_value")) - .WillOnce(Invoke([&](const std::string& key, const std::string& value) { - data[key] = value; - return 0; - })); + EXPECT_EQ(GetAllValues(), "[]"); + EXPECT_EQ(Set("test_key", "test_value"), 0); + EXPECT_EQ(Get("test_key"), "test_value"); - EXPECT_CALL(*mock_storage_ptr_, GetValue("test_key")) - .WillOnce(Invoke([&](const std::string& key) { - std::string ret = data[key]; - return ret; - })); + // GetAllValues and GetRange may be out of order for in-memory, so we test up + // to 1 key-value pair + EXPECT_EQ(GetAllValues(), "[test_value]"); + EXPECT_EQ(GetRange("a", "z"), "[test_value]"); +} - EXPECT_CALL(*mock_storage_ptr_, GetAllValues()) - .WillOnce(Return("[]")) - .WillOnce(Return("[test_value]")); +TEST_F(KVExecutorTest, SetValueWithVersion) { + std::map data; - EXPECT_CALL(*mock_storage_ptr_, GetRange("a", "z")) - .WillOnce(Return("[test_value]")); + { + EXPECT_EQ(Set("test_key", "test_value", 0), 0); + ValueInfo expected_info; + expected_info.set_value("test_value"); + expected_info.set_version(1); + EXPECT_THAT(Get("test_key", 1), EqualsProto(expected_info)); + } - EXPECT_EQ(GetValues(), "[]"); - EXPECT_EQ(Set("test_key", "test_value"), 0); - EXPECT_EQ(Get("test_key"), "test_value"); + { + EXPECT_EQ(Set("test_key", "test_value1", 1), 0); + ValueInfo expected_info; + expected_info.set_value("test_value1"); + expected_info.set_version(2); + EXPECT_THAT(Get("test_key", 2), EqualsProto(expected_info)); + } + { + EXPECT_EQ(Set("test_key", "test_value1", 1), 0); + ValueInfo expected_info; + expected_info.set_value("test_value"); + expected_info.set_version(1); + EXPECT_THAT(Get("test_key", 1), EqualsProto(expected_info)); + } - // GetValues and GetRange may be out of order for in-memory, so we test up to - // 1 key-value pair - EXPECT_EQ(GetValues(), "[test_value]"); - EXPECT_EQ(GetRange("a", "z"), "[test_value]"); + { + EXPECT_EQ(Set("test_key1", "test_key1", 0), 0); + ValueInfo expected_info; + expected_info.set_value("test_key1"); + expected_info.set_version(1); + EXPECT_THAT(Get("test_key1", 1), EqualsProto(expected_info)); + + ValueInfo expected_info2; + expected_info2.set_value("test_value"); + expected_info2.set_version(1); + EXPECT_THAT(Get("test_key", 1), EqualsProto(expected_info2)); + + ValueInfo expected_info3; + expected_info3.set_value("test_value1"); + expected_info3.set_version(2); + EXPECT_THAT(Get("test_key", 0), EqualsProto(expected_info3)); + } + + { + Items items; + { + Item* item = items.add_item(); + item->set_key("test_key"); + item->mutable_value_info()->set_value("test_value1"); + item->mutable_value_info()->set_version(2); + } + { + Item* item = items.add_item(); + item->set_key("test_key1"); + item->mutable_value_info()->set_value("test_key1"); + item->mutable_value_info()->set_version(1); + } + + EXPECT_THAT(GetAllItems(), EqualsProto(items)); + } + + { + Items items; + { + Item* item = items.add_item(); + item->set_key("test_key"); + item->mutable_value_info()->set_value("test_value1"); + item->mutable_value_info()->set_version(2); + } + EXPECT_THAT(GetKeyRange("test_key", "test_key"), EqualsProto(items)); + } + + { + Items items; + { + Item* item = items.add_item(); + item->set_key("test_key"); + item->mutable_value_info()->set_value("test_value1"); + item->mutable_value_info()->set_version(2); + } + { + Item* item = items.add_item(); + item->set_key("test_key"); + item->mutable_value_info()->set_value("test_value"); + item->mutable_value_info()->set_version(1); + } + EXPECT_THAT(GetHistory("test_key", 0, 2), EqualsProto(items)); + } } } // namespace diff --git a/executor/utxo/executor/utxo_executor.cpp b/executor/utxo/executor/utxo_executor.cpp index ff84f7ddc..a60e535a1 100644 --- a/executor/utxo/executor/utxo_executor.cpp +++ b/executor/utxo/executor/utxo_executor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/utxo/executor/utxo_executor.h" diff --git a/executor/utxo/executor/utxo_executor.h b/executor/utxo/executor/utxo_executor.h index a0b625424..2e9acf8bc 100644 --- a/executor/utxo/executor/utxo_executor.h +++ b/executor/utxo/executor/utxo_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/executor/utxo/executor/utxo_executor_test.cpp b/executor/utxo/executor/utxo_executor_test.cpp index cda4a8396..0de5d69d0 100644 --- a/executor/utxo/executor/utxo_executor_test.cpp +++ b/executor/utxo/executor/utxo_executor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/utxo/executor/utxo_executor.h" diff --git a/executor/utxo/manager/transaction.cpp b/executor/utxo/manager/transaction.cpp index b2c750677..787e20118 100644 --- a/executor/utxo/manager/transaction.cpp +++ b/executor/utxo/manager/transaction.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/utxo/manager/transaction.h" diff --git a/executor/utxo/manager/transaction.h b/executor/utxo/manager/transaction.h index 238101af3..556d75b08 100644 --- a/executor/utxo/manager/transaction.h +++ b/executor/utxo/manager/transaction.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/executor/utxo/manager/transaction_test.cpp b/executor/utxo/manager/transaction_test.cpp index 0fe154d78..50e239f0a 100644 --- a/executor/utxo/manager/transaction_test.cpp +++ b/executor/utxo/manager/transaction_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/utxo/manager/transaction.h" diff --git a/executor/utxo/manager/tx_mempool.cpp b/executor/utxo/manager/tx_mempool.cpp index 889b1fea6..ef832bc63 100644 --- a/executor/utxo/manager/tx_mempool.cpp +++ b/executor/utxo/manager/tx_mempool.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/utxo/manager/tx_mempool.h" diff --git a/executor/utxo/manager/tx_mempool.h b/executor/utxo/manager/tx_mempool.h index 13af92bd5..808361b40 100644 --- a/executor/utxo/manager/tx_mempool.h +++ b/executor/utxo/manager/tx_mempool.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/executor/utxo/manager/tx_mempool_test.cpp b/executor/utxo/manager/tx_mempool_test.cpp index 205ad66c9..a9af05176 100644 --- a/executor/utxo/manager/tx_mempool_test.cpp +++ b/executor/utxo/manager/tx_mempool_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/utxo/manager/tx_mempool.h" diff --git a/executor/utxo/manager/wallet.cpp b/executor/utxo/manager/wallet.cpp index b69e7568c..644b35d90 100644 --- a/executor/utxo/manager/wallet.cpp +++ b/executor/utxo/manager/wallet.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/utxo/manager/wallet.h" diff --git a/executor/utxo/manager/wallet.h b/executor/utxo/manager/wallet.h index 5ed03c1ac..b9755515f 100644 --- a/executor/utxo/manager/wallet.h +++ b/executor/utxo/manager/wallet.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/executor/utxo/manager/wallet_test.cpp b/executor/utxo/manager/wallet_test.cpp index ebf6e2b35..6e606e207 100644 --- a/executor/utxo/manager/wallet_test.cpp +++ b/executor/utxo/manager/wallet_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "executor/utxo/manager/wallet.h" diff --git a/img/apache-incubator.png b/img/apache-incubator.png new file mode 100644 index 000000000..338169e4d Binary files /dev/null and b/img/apache-incubator.png differ diff --git a/img/apache-resdb.png b/img/apache-resdb.png new file mode 100644 index 000000000..1e2d0a0a9 Binary files /dev/null and b/img/apache-resdb.png differ diff --git a/img/resdb-v2.png b/img/resdb-v2.png new file mode 100644 index 000000000..aa5bf1660 Binary files /dev/null and b/img/resdb-v2.png differ diff --git a/img/resdb.png b/img/resdb.png new file mode 100644 index 000000000..bce6eb40c Binary files /dev/null and b/img/resdb.png differ diff --git a/interface/common/mock_resdb_txn_accessor.h b/interface/common/mock_resdb_txn_accessor.h index c900dba47..3962ba275 100644 --- a/interface/common/mock_resdb_txn_accessor.h +++ b/interface/common/mock_resdb_txn_accessor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/interface/common/resdb_state_accessor.cpp b/interface/common/resdb_state_accessor.cpp index 9dbc847c7..8784f8f18 100644 --- a/interface/common/resdb_state_accessor.cpp +++ b/interface/common/resdb_state_accessor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "interface/common/resdb_state_accessor.h" diff --git a/interface/common/resdb_state_accessor.h b/interface/common/resdb_state_accessor.h index 8ce5dbede..17efc5971 100644 --- a/interface/common/resdb_state_accessor.h +++ b/interface/common/resdb_state_accessor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/interface/common/resdb_state_accessor_test.cpp b/interface/common/resdb_state_accessor_test.cpp index 77e0954f0..66ff594fb 100644 --- a/interface/common/resdb_state_accessor_test.cpp +++ b/interface/common/resdb_state_accessor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "interface/common/resdb_state_accessor.h" diff --git a/interface/common/resdb_txn_accessor.cpp b/interface/common/resdb_txn_accessor.cpp index b6e4fb137..55ef23b43 100644 --- a/interface/common/resdb_txn_accessor.cpp +++ b/interface/common/resdb_txn_accessor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "interface/common/resdb_txn_accessor.h" diff --git a/interface/common/resdb_txn_accessor.h b/interface/common/resdb_txn_accessor.h index 5aa1305b7..9fab8d222 100644 --- a/interface/common/resdb_txn_accessor.h +++ b/interface/common/resdb_txn_accessor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/interface/common/resdb_txn_accessor_test.cpp b/interface/common/resdb_txn_accessor_test.cpp index f7832c2e0..b85e9e50a 100644 --- a/interface/common/resdb_txn_accessor_test.cpp +++ b/interface/common/resdb_txn_accessor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "interface/common/resdb_txn_accessor.h" diff --git a/interface/contract/contract_client.cpp b/interface/contract/contract_client.cpp index a2d944b9e..2d8b2e98e 100644 --- a/interface/contract/contract_client.cpp +++ b/interface/contract/contract_client.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "interface/contract/contract_client.h" diff --git a/interface/contract/contract_client.h b/interface/contract/contract_client.h index 69e2d4052..7b0c5aed3 100644 --- a/interface/contract/contract_client.h +++ b/interface/contract/contract_client.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/interface/kv/kv_client.cpp b/interface/kv/kv_client.cpp index e3a3e7e48..25526395b 100644 --- a/interface/kv/kv_client.cpp +++ b/interface/kv/kv_client.cpp @@ -1,34 +1,26 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "interface/kv/kv_client.h" #include -#include "proto/kv/kv.pb.h" - namespace resdb { KVClient::KVClient(const ResDBConfig& config) @@ -55,9 +47,9 @@ std::unique_ptr KVClient::Get(const std::string& key) { return std::make_unique(response.value()); } -std::unique_ptr KVClient::GetValues() { +std::unique_ptr KVClient::GetAllValues() { KVRequest request; - request.set_cmd(KVRequest::GETVALUES); + request.set_cmd(KVRequest::GETALLVALUES); KVResponse response; int ret = SendRequest(request, &response); if (ret != 0) { @@ -82,4 +74,75 @@ std::unique_ptr KVClient::GetRange(const std::string& min_key, return std::make_unique(response.value()); } +int KVClient::Set(const std::string& key, const std::string& data, + int version) { + KVRequest request; + request.set_cmd(KVRequest::SET_WITH_VERSION); + request.set_key(key); + request.set_value(data); + request.set_version(version); + return SendRequest(request); +} + +std::unique_ptr KVClient::Get(const std::string& key, int version) { + KVRequest request; + request.set_cmd(KVRequest::GET_WITH_VERSION); + request.set_key(key); + request.set_version(version); + KVResponse response; + int ret = SendRequest(request, &response); + if (ret != 0) { + LOG(ERROR) << "send request fail, ret:" << ret; + return nullptr; + } + return std::make_unique(response.value_info()); +} + +std::unique_ptr KVClient::GetKeyRange(const std::string& min_key, + const std::string& max_key) { + KVRequest request; + request.set_cmd(KVRequest::GET_KEY_RANGE); + request.set_min_key(min_key); + request.set_max_key(max_key); + KVResponse response; + int ret = SendRequest(request, &response); + if (ret != 0) { + LOG(ERROR) << "send request fail, ret:" << ret; + return nullptr; + } + return std::make_unique(response.items()); +} + +std::unique_ptr KVClient::GetKeyHistory(const std::string& key, + int min_version, + int max_version) { + KVRequest request; + request.set_cmd(KVRequest::GET_HISTORY); + request.set_key(key); + request.set_min_version(min_version); + request.set_max_version(max_version); + KVResponse response; + int ret = SendRequest(request, &response); + if (ret != 0) { + LOG(ERROR) << "send request fail, ret:" << ret; + return nullptr; + } + return std::make_unique(response.items()); +} + +std::unique_ptr KVClient::GetKeyTopHistory(const std::string& key, + int top_number) { + KVRequest request; + request.set_cmd(KVRequest::GET_TOP); + request.set_key(key); + request.set_top_number(top_number); + KVResponse response; + int ret = SendRequest(request, &response); + if (ret != 0) { + LOG(ERROR) << "send request fail, ret:" << ret; + return nullptr; + } + return std::make_unique(response.items()); +} + } // namespace resdb diff --git a/interface/kv/kv_client.h b/interface/kv/kv_client.h index 03724d380..52cbcab19 100644 --- a/interface/kv/kv_client.h +++ b/interface/kv/kv_client.h @@ -1,31 +1,26 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once #include "interface/rdbc/transaction_constructor.h" +#include "proto/kv/kv.pb.h" namespace resdb { @@ -34,9 +29,36 @@ class KVClient : public TransactionConstructor { public: KVClient(const ResDBConfig& config); + // Version-based interfaces. + // Obtain the current version before setting a new data + int Set(const std::string& key, const std::string& data, int version); + + // Obtain the value with a specific version. + // If the version parameter is zero, it will return the data with the current + // version in the database. ValueInfo contains the version and its version. + // Return nullptr if there is an error. + std::unique_ptr Get(const std::string& key, int version); + + // Obtain the latest values of the keys within [min_key, max_key]. + // Keys should be comparable. + std::unique_ptr GetKeyRange(const std::string& min_key, + const std::string& max_key); + + // Obtain the histories of `key` with the versions in [min_version, + // max_version] + std::unique_ptr GetKeyHistory(const std::string& key, int min_version, + int max_version); + + // Obtain the top `top_number` histories of the `key`. + std::unique_ptr GetKeyTopHistory(const std::string& key, + int top_number); + + // Non-version-based Interfaces. + // These interfaces are not compatible with the version-based interfaces + // above. int Set(const std::string& key, const std::string& data); std::unique_ptr Get(const std::string& key); - std::unique_ptr GetValues(); + std::unique_ptr GetAllValues(); std::unique_ptr GetRange(const std::string& min_key, const std::string& max_key); }; diff --git a/interface/rdbc/mock_net_channel.h b/interface/rdbc/mock_net_channel.h index 39874da1f..73785c226 100644 --- a/interface/rdbc/mock_net_channel.h +++ b/interface/rdbc/mock_net_channel.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/interface/rdbc/mock_resdb_txn_accessor.h b/interface/rdbc/mock_resdb_txn_accessor.h index 281c05103..f70fa9a31 100644 --- a/interface/rdbc/mock_resdb_txn_accessor.h +++ b/interface/rdbc/mock_resdb_txn_accessor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/interface/rdbc/net_channel.cpp b/interface/rdbc/net_channel.cpp index c4999c4bc..981b0af29 100644 --- a/interface/rdbc/net_channel.cpp +++ b/interface/rdbc/net_channel.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "interface/rdbc/net_channel.h" diff --git a/interface/rdbc/net_channel.h b/interface/rdbc/net_channel.h index 53b1578e2..d1baa692e 100644 --- a/interface/rdbc/net_channel.h +++ b/interface/rdbc/net_channel.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/interface/rdbc/net_channel_test.cpp b/interface/rdbc/net_channel_test.cpp index 1ac81a024..a0da76755 100644 --- a/interface/rdbc/net_channel_test.cpp +++ b/interface/rdbc/net_channel_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "interface/rdbc/net_channel.h" diff --git a/interface/rdbc/transaction_constructor.cpp b/interface/rdbc/transaction_constructor.cpp index f71433484..be42224aa 100644 --- a/interface/rdbc/transaction_constructor.cpp +++ b/interface/rdbc/transaction_constructor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "interface/rdbc/transaction_constructor.h" diff --git a/interface/rdbc/transaction_constructor.h b/interface/rdbc/transaction_constructor.h index c305badf3..39754a846 100644 --- a/interface/rdbc/transaction_constructor.h +++ b/interface/rdbc/transaction_constructor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/interface/rdbc/transaction_constructor_test.cpp b/interface/rdbc/transaction_constructor_test.cpp index 1dda2a895..cd00646d1 100644 --- a/interface/rdbc/transaction_constructor_test.cpp +++ b/interface/rdbc/transaction_constructor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "interface/rdbc/transaction_constructor.h" diff --git a/interface/utxo/utxo_client.cpp b/interface/utxo/utxo_client.cpp index fa68656a3..8ed006f1a 100644 --- a/interface/utxo/utxo_client.cpp +++ b/interface/utxo/utxo_client.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "interface/utxo/utxo_client.h" diff --git a/interface/utxo/utxo_client.h b/interface/utxo/utxo_client.h index b42175452..9cf0d8fce 100644 --- a/interface/utxo/utxo_client.h +++ b/interface/utxo/utxo_client.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/common/data_comm/data_comm.h b/platform/common/data_comm/data_comm.h index 3a568314d..9f7d48821 100644 --- a/platform/common/data_comm/data_comm.h +++ b/platform/common/data_comm/data_comm.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/common/data_comm/network_comm.h b/platform/common/data_comm/network_comm.h index 7a4c3f5d2..2eb682992 100644 --- a/platform/common/data_comm/network_comm.h +++ b/platform/common/data_comm/network_comm.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/common/network/mock_socket.h b/platform/common/network/mock_socket.h index 69172bc4c..008c1f9bc 100644 --- a/platform/common/network/mock_socket.h +++ b/platform/common/network/mock_socket.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/common/network/network_utils.cpp b/platform/common/network/network_utils.cpp index 0ac783491..24c52beb9 100644 --- a/platform/common/network/network_utils.cpp +++ b/platform/common/network/network_utils.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "network/network_utils.h" diff --git a/platform/common/network/network_utils.h b/platform/common/network/network_utils.h index cd307c3be..512c3054c 100644 --- a/platform/common/network/network_utils.h +++ b/platform/common/network/network_utils.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/common/network/network_utils_test.cpp b/platform/common/network/network_utils_test.cpp index 967cd03cc..12303c564 100644 --- a/platform/common/network/network_utils_test.cpp +++ b/platform/common/network/network_utils_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "network/network_utils.h" diff --git a/platform/common/network/socket.h b/platform/common/network/socket.h index d6f2df5d9..a0c775338 100644 --- a/platform/common/network/socket.h +++ b/platform/common/network/socket.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/common/network/tcp_socket.cpp b/platform/common/network/tcp_socket.cpp index bbba6ee1e..b541c71dc 100644 --- a/platform/common/network/tcp_socket.cpp +++ b/platform/common/network/tcp_socket.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/common/network/tcp_socket.h" diff --git a/platform/common/network/tcp_socket.h b/platform/common/network/tcp_socket.h index a84d280cc..b894c41c9 100644 --- a/platform/common/network/tcp_socket.h +++ b/platform/common/network/tcp_socket.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/common/network/tcp_socket_test.cpp b/platform/common/network/tcp_socket_test.cpp index 3b8311c0d..db5252348 100644 --- a/platform/common/network/tcp_socket_test.cpp +++ b/platform/common/network/tcp_socket_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/common/network/tcp_socket.h" diff --git a/platform/common/queue/batch_queue.h b/platform/common/queue/batch_queue.h index 1657bfe19..ab1cf3ac2 100644 --- a/platform/common/queue/batch_queue.h +++ b/platform/common/queue/batch_queue.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/common/queue/batch_queue_test.cpp b/platform/common/queue/batch_queue_test.cpp index 519da3da0..378a5f9c3 100644 --- a/platform/common/queue/batch_queue_test.cpp +++ b/platform/common/queue/batch_queue_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/common/queue/batch_queue.h" diff --git a/platform/common/queue/blocking_queue.h b/platform/common/queue/blocking_queue.h index 3dd377528..4cf7acfd7 100644 --- a/platform/common/queue/blocking_queue.h +++ b/platform/common/queue/blocking_queue.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/common/queue/lock_free_queue.h b/platform/common/queue/lock_free_queue.h index 5c1a89aa5..1bbfe249b 100644 --- a/platform/common/queue/lock_free_queue.h +++ b/platform/common/queue/lock_free_queue.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once @@ -47,7 +41,7 @@ class LockFreeQueue { bool old_v = true; if (need_notify_.compare_exchange_strong(old_v, false, std::memory_order_acq_rel, - std::memory_order_acq_rel)) { + std::memory_order_acquire)) { std::lock_guard lk(mutex_); cv_.notify_all(); return; diff --git a/platform/common/queue/lock_free_queue_test.cpp b/platform/common/queue/lock_free_queue_test.cpp index a0f6efab6..101d16e25 100644 --- a/platform/common/queue/lock_free_queue_test.cpp +++ b/platform/common/queue/lock_free_queue_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/common/queue/lock_free_queue.h" diff --git a/platform/config/resdb_config.cpp b/platform/config/resdb_config.cpp index d6383f6d3..370f2598b 100644 --- a/platform/config/resdb_config.cpp +++ b/platform/config/resdb_config.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/config/resdb_config.h" @@ -68,7 +62,7 @@ ResDBConfig::ResDBConfig(const ResConfigData& config_data, config_data_.set_view_change_timeout_ms(viewchange_commit_timeout_ms_); } if (config_data_.client_batch_num() == 0) { - config_data_.set_client_batch_num(client_batch_num_); + config_data_.set_client_batch_num(100); } if (config_data_.worker_num() == 0) { config_data_.set_worker_num(worker_num_); @@ -82,8 +76,8 @@ ResDBConfig::ResDBConfig(const ResConfigData& config_data, if (config_data_.tcp_batch_num() == 0) { config_data_.set_tcp_batch_num(100); } - if (!config_data_.has_recovery_enabled()) { - config_data_.set_recovery_enabled(true); + if (config_data_.max_process_txn() == 0) { + config_data_.set_max_process_txn(64); } } @@ -186,7 +180,7 @@ void ResDBConfig::SetSignatureVerifierEnabled(bool enable_sv) { } // Performance setting -bool ResDBConfig::IsPerformanceRunning() { +bool ResDBConfig::IsPerformanceRunning() const { return is_performance_running_ || GetConfigData().is_performance_running(); } @@ -259,4 +253,16 @@ void ResDBConfig::SetViewchangeCommitTimeout(uint64_t timeout_ms) { config_data_.set_view_change_timeout_ms(timeout_ms); } +uint32_t ResDBConfig::GetFailureNum() const { + if (config_data_.failure_num()) { + return config_data_.failure_num(); + } + return failure_num_; +} + +void ResDBConfig::SetFailureNum(uint32_t num) { + config_data_.set_failure_num(num); + failure_num_ = num; +} + } // namespace resdb diff --git a/platform/config/resdb_config.h b/platform/config/resdb_config.h index e4e9f8163..5f223f46e 100644 --- a/platform/config/resdb_config.h +++ b/platform/config/resdb_config.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once @@ -100,7 +94,7 @@ class ResDBConfig { void SetSignatureVerifierEnabled(bool enable_sv); // Performance setting - bool IsPerformanceRunning(); + bool IsPerformanceRunning() const; void RunningPerformance(bool); bool IsTestMode() const; @@ -127,6 +121,9 @@ class ResDBConfig { uint32_t GetViewchangeCommitTimeout() const; void SetViewchangeCommitTimeout(uint64_t timeout_ms); + uint32_t GetFailureNum() const; + void SetFailureNum(uint32_t num); + private: ResConfigData config_data_; std::vector replicas_; @@ -141,15 +138,18 @@ class ResDBConfig { bool signature_verifier_enabled_ = true; bool is_performance_running_ = false; bool is_test_mode_ = false; - uint32_t max_process_txn_ = 2048; uint32_t client_batch_wait_time_ms_ = 100; // milliseconds, 0.1s - uint32_t client_batch_num_ = 100; uint64_t viewchange_commit_timeout_ms_ = 60000; // default 60s to change viewchange - uint32_t worker_num_ = 64; - uint32_t input_worker_num_ = 1; - uint32_t output_worker_num_ = 1; + + // This is the default settings. + // change these parameters in the configuration. + uint32_t max_process_txn_ = 64; + uint32_t worker_num_ = 16; + uint32_t input_worker_num_ = 5; + uint32_t output_worker_num_ = 5; + uint32_t failure_num_ = 0; }; } // namespace resdb diff --git a/platform/config/resdb_config_test.cpp b/platform/config/resdb_config_test.cpp index be877c3a3..f480b11f5 100644 --- a/platform/config/resdb_config_test.cpp +++ b/platform/config/resdb_config_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/config/resdb_config.h" diff --git a/platform/config/resdb_config_utils.cpp b/platform/config/resdb_config_utils.cpp index 907bc4854..beae7e957 100644 --- a/platform/config/resdb_config_utils.cpp +++ b/platform/config/resdb_config_utils.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/config/resdb_config_utils.h" diff --git a/platform/config/resdb_config_utils.h b/platform/config/resdb_config_utils.h index aa6974b70..15d77a4bf 100644 --- a/platform/config/resdb_config_utils.h +++ b/platform/config/resdb_config_utils.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/config/resdb_poc_config.cpp b/platform/config/resdb_poc_config.cpp index 8c8fd414a..c644f391a 100644 --- a/platform/config/resdb_poc_config.cpp +++ b/platform/config/resdb_poc_config.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/config/resdb_poc_config.h" diff --git a/platform/config/resdb_poc_config.h b/platform/config/resdb_poc_config.h index e5895f89b..c0c73a5dd 100644 --- a/platform/config/resdb_poc_config.h +++ b/platform/config/resdb_poc_config.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/checkpoint/checkpoint.h b/platform/consensus/checkpoint/checkpoint.h index cd87e67cb..7a5b967ce 100644 --- a/platform/consensus/checkpoint/checkpoint.h +++ b/platform/consensus/checkpoint/checkpoint.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/checkpoint/mock_checkpoint.h b/platform/consensus/checkpoint/mock_checkpoint.h index 57b3f8397..837d895ca 100644 --- a/platform/consensus/checkpoint/mock_checkpoint.h +++ b/platform/consensus/checkpoint/mock_checkpoint.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/execution/duplicate_manager.cpp b/platform/consensus/execution/duplicate_manager.cpp index b2c396fbe..626174b59 100644 --- a/platform/consensus/execution/duplicate_manager.cpp +++ b/platform/consensus/execution/duplicate_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/execution/duplicate_manager.h" diff --git a/platform/consensus/execution/duplicate_manager.h b/platform/consensus/execution/duplicate_manager.h index 69b811cd9..2579196aa 100644 --- a/platform/consensus/execution/duplicate_manager.h +++ b/platform/consensus/execution/duplicate_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/execution/geo_global_executor.cpp b/platform/consensus/execution/geo_global_executor.cpp index 6fd3ef447..1daff7c80 100644 --- a/platform/consensus/execution/geo_global_executor.cpp +++ b/platform/consensus/execution/geo_global_executor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/execution/geo_global_executor.h" diff --git a/platform/consensus/execution/geo_global_executor.h b/platform/consensus/execution/geo_global_executor.h index 7b7f16c89..2a62baefa 100644 --- a/platform/consensus/execution/geo_global_executor.h +++ b/platform/consensus/execution/geo_global_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/execution/geo_global_executor_test.cpp b/platform/consensus/execution/geo_global_executor_test.cpp index 62a80c62a..e911d2aac 100644 --- a/platform/consensus/execution/geo_global_executor_test.cpp +++ b/platform/consensus/execution/geo_global_executor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/execution/geo_global_executor.h" diff --git a/platform/consensus/execution/geo_transaction_executor.cpp b/platform/consensus/execution/geo_transaction_executor.cpp index c798dd8cc..6b6f2a242 100644 --- a/platform/consensus/execution/geo_transaction_executor.cpp +++ b/platform/consensus/execution/geo_transaction_executor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/execution/geo_transaction_executor.h" diff --git a/platform/consensus/execution/geo_transaction_executor.h b/platform/consensus/execution/geo_transaction_executor.h index c120d3b94..04de32482 100644 --- a/platform/consensus/execution/geo_transaction_executor.h +++ b/platform/consensus/execution/geo_transaction_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/execution/geo_transaction_executor_test.cpp b/platform/consensus/execution/geo_transaction_executor_test.cpp index d263e5232..be7e3acda 100644 --- a/platform/consensus/execution/geo_transaction_executor_test.cpp +++ b/platform/consensus/execution/geo_transaction_executor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/execution/geo_transaction_executor.h" diff --git a/platform/consensus/execution/mock_geo_global_executor.h b/platform/consensus/execution/mock_geo_global_executor.h index c3676ea52..49e409e3d 100644 --- a/platform/consensus/execution/mock_geo_global_executor.h +++ b/platform/consensus/execution/mock_geo_global_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/execution/system_info.cpp b/platform/consensus/execution/system_info.cpp index 38bc502d8..a12740c8e 100644 --- a/platform/consensus/execution/system_info.cpp +++ b/platform/consensus/execution/system_info.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/execution/system_info.h" diff --git a/platform/consensus/execution/system_info.h b/platform/consensus/execution/system_info.h index ecfde2596..069c772f8 100644 --- a/platform/consensus/execution/system_info.h +++ b/platform/consensus/execution/system_info.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/execution/system_info_test.cpp b/platform/consensus/execution/system_info_test.cpp index c2f938167..4ce86c5dc 100644 --- a/platform/consensus/execution/system_info_test.cpp +++ b/platform/consensus/execution/system_info_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/execution/system_info.h" diff --git a/platform/consensus/execution/transaction_executor.cpp b/platform/consensus/execution/transaction_executor.cpp index 55cd6afbc..8c40a9c8f 100644 --- a/platform/consensus/execution/transaction_executor.cpp +++ b/platform/consensus/execution/transaction_executor.cpp @@ -1,31 +1,26 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/execution/transaction_executor.h" #include +#include "common/utils/utils.h" namespace resdb { @@ -41,30 +36,86 @@ TransactionExecutor::TransactionExecutor( execute_queue_("execute"), stop_(false), duplicate_manager_(nullptr) { + + memset(blucket_, 0, sizeof(blucket_)); global_stats_ = Stats::GetGlobalStats(); ordering_thread_ = std::thread(&TransactionExecutor::OrderMessage, this); - execute_thread_ = std::thread(&TransactionExecutor::ExecuteMessage, this); + for (int i = 0; i < execute_thread_num_; ++i) { + execute_thread_.push_back( + std::thread(&TransactionExecutor::ExecuteMessage, this)); + } + + for (int i = 0; i < 1; ++i) { + prepare_thread_.push_back( + std::thread(&TransactionExecutor::PrepareMessage, this)); + } if (transaction_manager_ && transaction_manager_->IsOutOfOrder()) { execute_OOO_thread_ = std::thread(&TransactionExecutor::ExecuteMessageOutOfOrder, this); LOG(ERROR) << " is out of order:" << transaction_manager_->IsOutOfOrder(); } + gc_thread_ = std::thread(&TransactionExecutor::GCProcess, this); } TransactionExecutor::~TransactionExecutor() { Stop(); } +void TransactionExecutor::RegisterExecute(int64_t seq) { + if (execute_thread_num_ == 1) return; + int idx = seq % blucket_num_; + std::unique_lock lk(mutex_); + // LOG(ERROR)<<"register seq:"< lk(mutex_); + cv_.wait_for(lk, std::chrono::milliseconds(10000), [&] { + return ((blucket_[pre_idx] & 2) || !blucket_[pre_idx]); + }); + if ((blucket_[pre_idx] & 2) || !blucket_[pre_idx]) { + break; + } + } + // LOG(ERROR)<<"wait for :"< lk(mutex_); + // LOG(ERROR)<<"finish :"< message) { + global_stats_->IncCommit(); + message->set_commit_time(GetCurrentTime()); + execute_queue_.Push(std::move(message)); +} + void TransactionExecutor::ExecuteMessage() { while (!IsStop()) { auto message = execute_queue_.Pop(); @@ -160,7 +217,11 @@ void TransactionExecutor::ExecuteMessage() { if (transaction_manager_ && transaction_manager_->IsOutOfOrder()) { need_execute = false; } + int64_t start_time = GetCurrentTime(); + global_stats_->AddExecuteQueuingLatency(start_time - message->commit_time()); Execute(std::move(message), need_execute); + int64_t end_time = GetCurrentTime(); + global_stats_->AddExecuteLatency(end_time-start_time); } } @@ -178,7 +239,7 @@ void TransactionExecutor::OnlyExecute(std::unique_ptr request) { // Only Execute the request. BatchUserRequest batch_request; if (!batch_request.ParseFromString(request->data())) { - LOG(ERROR) << "parse data fail"; + LOG(ERROR) << "parse data fail in TransactionExecutor!"; } batch_request.set_seq(request->seq()); batch_request.set_hash(request->hash()); @@ -190,9 +251,6 @@ void TransactionExecutor::OnlyExecute(std::unique_ptr request) { // LOG(INFO) << " get request batch size:" // << batch_request.user_requests_size()<<" proxy // id:"<proxy_id(); - // std::unique_ptr batch_response = - // std::make_unique(); - std::unique_ptr response; if (transaction_manager_) { response = transaction_manager_->ExecuteBatch(batch_request); @@ -204,49 +262,330 @@ void TransactionExecutor::OnlyExecute(std::unique_ptr request) { void TransactionExecutor::Execute(std::unique_ptr request, bool need_execute) { - // Execute the request, then send the response back to the user. - BatchUserRequest batch_request; - if (!batch_request.ParseFromString(request->data())) { - LOG(ERROR) << "parse data fail"; + uint64_t uid = request->uid(); + int64_t seq = request->seq(); + RegisterExecute(request->seq()); + //LOG(ERROR)<<"EXECUTE seq:"< batch_request = nullptr; + std::unique_ptr>> data; + std::vector> * data_p = nullptr; + BatchUserRequest* batch_request_p = nullptr; + + bool need_gc = false; + + if (request->uid() > 0) { + bool current_f = SetFlag(uid, Start_Execute); + if (!current_f) { + global_stats_->ConsumeTransactions(1); + std::unique_ptr> data_f = GetFuture(uid); + //LOG(ERROR)<<"wait prepare:"<get(); + } + //LOG(ERROR)<<"wait prepare done:"< lk(fd_mutex_[uid % mod]); + if(req_[uid % mod][uid] == nullptr){ + LOG(ERROR)<<"data is empty:"<second!=nullptr); + data_p = it->second.get(); + //data = std::move(it->second); + } + int64_t end_time = GetCurrentTime(); + if (end_time - start_time > 1000) { + LOG(ERROR) << "get data done:" << uid + << " wait time:" << (end_time - start_time); + } + } + ClearPromise(uid); + need_gc = true; + } else { + global_stats_->AddNewTransactions(1); + //LOG(ERROR)<<"commit start:"<seq()); - batch_request.set_hash(request->hash()); - batch_request.set_proxy_id(request->proxy_id()); - if (request->has_committed_certs()) { - *batch_request.mutable_committed_certs() = request->committed_certs(); + + // Execute the request, then send the response back to the user. + if (batch_request_p == nullptr) { + batch_request = std::make_unique(); + if (!batch_request->ParseFromString(request->data())) { + LOG(ERROR) << "parse data fail in TransactionExecutor!"; + } + batch_request->set_hash(request->hash()); + if (request->has_committed_certs()) { + *batch_request->mutable_committed_certs() = request->committed_certs(); + } + batch_request->set_seq(request->seq()); + batch_request->set_proxy_id(request->proxy_id()); + batch_request_p = batch_request.get(); + // LOG(ERROR)<<"get data from req:"; + } else { + assert(batch_request_p); + batch_request_p->set_seq(request->seq()); + batch_request_p->set_proxy_id(request->proxy_id()); + // LOG(ERROR)<<" get from cache:"<seq()<<" proxy + // id:"<proxy_id()<<" local id:"<local_id(); // LOG(INFO) << " get request batch size:" - // << batch_request.user_requests_size()<<" proxy - // id:"<proxy_id()<<" need execute:"< batch_response = - // std::make_unique(); + // << batch_request.user_requests_size()<<" proxy id:" + // <proxy_id()<<" need execute:"< response; + // need_execute = false; if (transaction_manager_ && need_execute) { - response = transaction_manager_->ExecuteBatch(batch_request); - } + if (execute_thread_num_ == 1) { + response = transaction_manager_->ExecuteBatch(*batch_request_p); + } else { + std::vector> response_v; + + /* + if (data == nullptr) { + int64_t start_time = GetCurrentTime(); + data = std::move(transaction_manager_->Prepare(*batch_request)); + int64_t end_time = GetCurrentTime(); + if (end_time - start_time > 10) { + // LOG(ERROR)<<"exec data done:"<Prepare(*batch_request_p)); + int64_t end_time = GetCurrentTime(); + if (end_time - start_time > 10) { + // LOG(ERROR)<<"exec data done:"<seq()); + response_v = transaction_manager_->ExecuteBatchData(*data_p); + FinishExecute(request->seq()); - if (duplicate_manager_) { - duplicate_manager_->AddExecuted(batch_request.hash(), batch_request.seq()); + response = std::make_unique(); + for (auto& s : response_v) { + response->add_response()->swap(*s); + } + } } + // LOG(ERROR)<<" CF = :"<<(cf==1)<<" uid:"<IncTotalRequest(batch_request.user_requests_size()); if (response == nullptr) { response = std::make_unique(); } + global_stats_->IncTotalRequest(batch_request_p->user_requests_size()); + response->set_proxy_id(batch_request_p->proxy_id()); + response->set_createtime(batch_request_p->createtime() + request->queuing_time()); + response->set_local_id(batch_request_p->local_id()); + global_stats_->AddCommitDelay(GetCurrentTime()- response->createtime()); + //LOG(ERROR)<<" proxy id:"<proxy_id()<<" local id:"<local_id()<<" latency:"<createtime(); - response->set_createtime(batch_request.createtime()); - response->set_local_id(batch_request.local_id()); - response->set_hash(batch_request.hash()); + response->set_seq(request->seq()); - post_exec_func_(std::move(request), std::move(response)); + if (post_exec_func_) { + post_exec_func_(std::move(request), std::move(response)); + } global_stats_->IncExecuteDone(); + if(need_gc){ + gc_queue_.Push(std::make_unique(uid)); + } } void TransactionExecutor::SetDuplicateManager(DuplicateManager* manager) { duplicate_manager_ = manager; } + +bool TransactionExecutor::SetFlag(uint64_t uid, int f) { + std::unique_lock lk(f_mutex_[uid % mod]); + auto it = flag_[uid % mod].find(uid); + if (it == flag_[uid % mod].end()) { + flag_[uid % mod][uid] |= f; + // LOG(ERROR)<<"NO FUTURE uid:"< lk(f_mutex_[uid % mod]); + auto it = pre_[uid % mod].find(uid); + if (it == pre_[uid % mod].end()) { + return; + } + // LOG(ERROR)<<"CLEAR UID:"<* TransactionExecutor::GetPromise(uint64_t uid) { + std::unique_lock lk(f_mutex_[uid % mod]); + auto it = pre_[uid % mod].find(uid); + if (it == pre_[uid % mod].end()) { + return nullptr; + } + return it->second.get(); +} + +std::unique_ptr> TransactionExecutor::GetFuture(uint64_t uid) { + std::unique_lock lk(f_mutex_[uid % mod]); + auto it = pre_[uid % mod].find(uid); + if (it == pre_[uid % mod].end()) { + return nullptr; + } + //return std::move(it->second); + // LOG(ERROR)<<"add future:"<>(it->second->get_future()); +} + +bool TransactionExecutor::AddFuture(uint64_t uid) { + std::unique_lock lk(f_mutex_[uid % mod]); + auto it = pre_[uid % mod].find(uid); + if (it == pre_[uid % mod].end()) { + // LOG(ERROR)<<"add future:"<> p = + std::make_unique>(); + //auto f = std::make_unique>(p->get_future()); + pre_[uid % mod][uid] = std::move(p); + //pre_f_[uid % mod][uid] = std::move(f); + flag_[uid % mod][uid] = 0; + return true; + } + return false; +} + +void TransactionExecutor::Prepare(std::unique_ptr request) { + if (AddFuture(request->uid())) { + prepare_queue_.Push(std::move(request)); + } +} + +void TransactionExecutor::GCProcess() { + while (!IsStop()) { + std::unique_ptr uid_or = gc_queue_.Pop(); + if (uid_or== nullptr) { + continue; + } + int64_t uid = *uid_or; + + std::vector> * data_p = nullptr; + { + std::unique_lock lk(fd_mutex_[uid % mod]); + assert(data_[uid%mod].find(uid) != data_[uid%mod].end()); + data_p = data_[uid%mod][uid].get(); + } + + for(int i = 0; i < data_p->size(); ++i){ + (*data_p)[i].release(); + } + (*data_p).clear(); + { + std::unique_lock lk(fd_mutex_[uid % mod]); + assert(req_[uid%mod].find(uid) != req_[uid%mod].end()); + assert(data_[uid%mod].find(uid) != data_[uid%mod].end()); + data_[uid%mod].erase(data_[uid%mod].find(uid)); + req_[uid%mod].erase(req_[uid%mod].find(uid)); + } + } +} + +void TransactionExecutor::PrepareMessage() { + while (!IsStop()) { + std::unique_ptr request = prepare_queue_.Pop(); + if (request == nullptr) { + continue; + } + + uint64_t uid = request->uid(); + int current_f = SetFlag(uid, Start_Prepare); + if (current_f == 0) { + // commit has done + // LOG(ERROR)<<" want prepare, commit started:"<* p = GetPromise(uid) ; + assert(p); + //LOG(ERROR)<<" prepare started:"< batch_request = + std::make_unique(); + if (!batch_request->ParseFromString(request->data())) { + LOG(ERROR) << "parse data fail in TransactionExecutor!"; + } + // batch_request = std::make_unique(); + batch_request->set_seq(request->seq()); + batch_request->set_hash(request->hash()); + batch_request->set_proxy_id(request->proxy_id()); + if (request->has_committed_certs()) { + *batch_request->mutable_committed_certs() = request->committed_certs(); + } + + // LOG(ERROR)<<"prepare seq:"<seq()<<" proxy + // id:"<proxy_id()<<" local id:"<local_id(); + + std::unique_ptr>> + request_v = transaction_manager_->Prepare(*batch_request); + { + std::unique_lock lk(fd_mutex_[uid % mod]); + // assert(request_v); + // assert(data_[uid%mod].find(uid) == data_[uid%mod].end()); + data_[uid%mod][uid] = std::move(request_v); + req_[uid % mod][uid] = std::move(batch_request); + } + //LOG(ERROR)<<"set promise:"<set_value(1); + { + int set_ret = SetFlag(uid, End_Prepare); + if (set_ret == 0) { + // LOG(ERROR)<<"commit interrupt:"< message); + Storage* GetStorage(); + void RegisterExecute(int64_t seq); + void WaitForExecute(int64_t seq); + void FinishExecute(int64_t seq); + + void Prepare(std::unique_ptr request); + private: void Execute(std::unique_ptr request, bool need_execute = true); void OnlyExecute(std::unique_ptr request); @@ -86,6 +88,15 @@ class TransactionExecutor { void UpdateMaxExecutedSeq(uint64_t seq); + bool SetFlag(uint64_t uid, int f); + void ClearPromise(uint64_t uid); + void PrepareMessage(); + void GCProcess(); + + bool AddFuture(uint64_t uid); + std::unique_ptr> GetFuture(uint64_t uid); + std::promise* GetPromise(uint64_t uid); + protected: ResDBConfig config_; @@ -97,11 +108,43 @@ class TransactionExecutor { SystemInfo* system_info_ = nullptr; std::unique_ptr transaction_manager_ = nullptr; std::map> candidates_; - std::thread ordering_thread_, execute_thread_, execute_OOO_thread_; + std::thread ordering_thread_, execute_OOO_thread_; + std::vector execute_thread_; LockFreeQueue commit_queue_, execute_queue_, execute_OOO_queue_; std::atomic stop_; Stats* global_stats_ = nullptr; DuplicateManager* duplicate_manager_; + int execute_thread_num_ = 10; + static const int blucket_num_ = 1024; + int blucket_[blucket_num_]; + std::condition_variable cv_; + std::mutex mutex_; + + enum PrepareType { + Start_Prepare = 1, + Start_Execute = 2, + End_Prepare = 4, + }; + + + std::vector prepare_thread_; + std::thread gc_thread_; + static const int mod = 2048; + std::mutex f_mutex_[mod], fd_mutex_[mod]; + LockFreeQueue prepare_queue_; + LockFreeQueue gc_queue_; + typedef std::unique_ptr> PromiseType; + std::map pre_[mod]; + + std::map>> pre_f_[mod]; + std::map flag_[mod]; + + std::map> req_[mod]; + std::unordered_map< + uint64_t, + std::unique_ptr>>> + data_[mod]; + }; } // namespace resdb diff --git a/platform/consensus/execution/transaction_executor_test.cpp b/platform/consensus/execution/transaction_executor_test.cpp index a48aaf6cc..9abb9ac7f 100644 --- a/platform/consensus/execution/transaction_executor_test.cpp +++ b/platform/consensus/execution/transaction_executor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/execution/transaction_executor.h" diff --git a/platform/consensus/ordering/common/algorithm/BUILD b/platform/consensus/ordering/common/algorithm/BUILD new file mode 100644 index 000000000..9abd8715e --- /dev/null +++ b/platform/consensus/ordering/common/algorithm/BUILD @@ -0,0 +1,12 @@ +package(default_visibility = ["//platform/consensus/ordering:__subpackages__"]) + +cc_library( + name = "protocol_base", + srcs = ["protocol_base.cpp"], + hdrs = ["protocol_base.h"], + deps = [ + "//common:comm", + "//common/crypto:signature_verifier", + ], +) + diff --git a/platform/consensus/ordering/common/algorithm/protocol_base.cpp b/platform/consensus/ordering/common/algorithm/protocol_base.cpp new file mode 100644 index 000000000..3c6c2fc3b --- /dev/null +++ b/platform/consensus/ordering/common/algorithm/protocol_base.cpp @@ -0,0 +1,53 @@ +#include "platform/consensus/ordering/common/algorithm/protocol_base.h" + +#include + +namespace resdb { +namespace common { + +ProtocolBase::ProtocolBase( + int id, + int f, + int total_num, + SingleCallFuncType single_call, + BroadcastCallFuncType broadcast_call, + CommitFuncType commit) : + id_(id), + f_(f), + total_num_(total_num), + single_call_(single_call), + broadcast_call_(broadcast_call), + commit_(commit) { + stop_ = false; +} + +ProtocolBase::ProtocolBase( int id, int f, int total_num) : ProtocolBase(id, f, total_num, nullptr, nullptr, nullptr){ + +} + +ProtocolBase::~ProtocolBase() { + Stop(); +} + +void ProtocolBase::Stop(){ + stop_ = true; +} + +bool ProtocolBase::IsStop(){ + return stop_; +} + +int ProtocolBase::SendMessage(int msg_type, const google::protobuf::Message& msg, int node_id) { + return single_call_(msg_type, msg, node_id); +} + +int ProtocolBase::Broadcast(int msg_type, const google::protobuf::Message& msg) { + return broadcast_call_(msg_type, msg); +} + +int ProtocolBase::Commit(const google::protobuf::Message& msg) { + return commit_(msg); +} + +} // namespace protocol +} // namespace resdb diff --git a/platform/consensus/ordering/common/algorithm/protocol_base.h b/platform/consensus/ordering/common/algorithm/protocol_base.h new file mode 100644 index 000000000..a93be8223 --- /dev/null +++ b/platform/consensus/ordering/common/algorithm/protocol_base.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include +#include "common/crypto/signature_verifier.h" + +namespace resdb { +namespace common { + +class ProtocolBase { + public: + typedef std::function SingleCallFuncType; + typedef std::function BroadcastCallFuncType; + typedef std::function CommitFuncType; + + ProtocolBase( + int id, + int f, + int total_num, + SingleCallFuncType single_call, + BroadcastCallFuncType broadcast_call, + CommitFuncType commit + ); + + ProtocolBase( int id, int f, int total_num); + + + virtual ~ProtocolBase(); + + void Stop(); + + inline + void SetSingleCallFunc(SingleCallFuncType single_call) { single_call_ = single_call; } + + inline + void SetBroadcastCallFunc(BroadcastCallFuncType broadcast_call) { broadcast_call_ = broadcast_call; } + + inline + void SetCommitFunc(CommitFuncType commit_func) { commit_ = commit_func; } + + inline + void SetSignatureVerifier(SignatureVerifier* verifier) { verifier_ = verifier;} + + protected: + int SendMessage(int msg_type, const google::protobuf::Message& msg, int node_id); + int Broadcast(int msg_type, const google::protobuf::Message& msg); + int Commit(const google::protobuf::Message& msg); + + bool IsStop(); + + protected: + int id_; + int f_; + int total_num_; + std::function single_call_; + std::function broadcast_call_; + std::function commit_; + std::atomic stop_; + + SignatureVerifier* verifier_; +}; + +} // namespace protocol +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/BUILD b/platform/consensus/ordering/common/framework/BUILD new file mode 100644 index 000000000..82e03a0fb --- /dev/null +++ b/platform/consensus/ordering/common/framework/BUILD @@ -0,0 +1,49 @@ +package(default_visibility = ["//platform/consensus/ordering:__subpackages__"]) + +cc_library( + name = "consensus", + srcs = ["consensus.cpp"], + hdrs = ["consensus.h"], + deps = [ + ":performance_manager", + ":response_manager", + "//common/utils", + "//executor/common:transaction_manager", + "//platform/consensus/execution:transaction_executor", + "//platform/consensus/ordering/common/algorithm:protocol_base", + "//platform/networkstrate:consensus_manager", + ], +) + +cc_library( + name = "performance_manager", + srcs = ["performance_manager.cpp"], + hdrs = ["performance_manager.h"], + deps = [ + ":transaction_utils", + "//platform/networkstrate:replica_communicator", + "//platform/networkstrate:server_comm", + ], +) + + +cc_library( + name = "response_manager", + srcs = ["response_manager.cpp"], + hdrs = ["response_manager.h"], + deps = [ + ":transaction_utils", + "//platform/networkstrate:replica_communicator", + "//platform/networkstrate:server_comm", + ], +) + +cc_library( + name = "transaction_utils", + srcs = ["transaction_utils.cpp"], + hdrs = ["transaction_utils.h"], + visibility = ["//visibility:public"], + deps = [ + "//platform/proto:resdb_cc_proto", + ], +) diff --git a/platform/consensus/ordering/common/framework/consensus.cpp b/platform/consensus/ordering/common/framework/consensus.cpp new file mode 100644 index 000000000..2566daeb5 --- /dev/null +++ b/platform/consensus/ordering/common/framework/consensus.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "platform/consensus/ordering/common/framework/consensus.h" + +#include +#include + +#include "common/utils/utils.h" + +namespace resdb { +namespace common { + +Consensus::Consensus(const ResDBConfig& config, + std::unique_ptr executor) + : ConsensusManager(config), + replica_communicator_(GetBroadCastClient()), + transaction_executor_(std::make_unique( + config, + [&](std::unique_ptr request, + std::unique_ptr resp_msg) { + ResponseMsg(*resp_msg); + }, + nullptr, std::move(executor))) { + LOG(INFO) << "is running is performance mode:" + << config_.IsPerformanceRunning(); + is_stop_ = false; + global_stats_ = Stats::GetGlobalStats(); + /* + for(int i = 0; i< 4; ++i){ + send_thread_.push_back(std::thread(&Consensus::AsyncSend, this)); + } + */ +} + +void Consensus::Init(){ + if(performance_manager_ == nullptr){ + performance_manager_ = + config_.IsPerformanceRunning() + ? std::make_unique( + config_, GetBroadCastClient(), GetSignatureVerifier()) + : nullptr; + } + + if(response_manager_ == nullptr){ + response_manager_ = + !config_.IsPerformanceRunning() + ? std::make_unique(config_, GetBroadCastClient(), + GetSignatureVerifier()) + : nullptr; + } +} + +void Consensus::InitProtocol(ProtocolBase * protocol){ + //protocol->SetSignatureVerifier(GetSignatureVerifier()); + + protocol->SetSingleCallFunc( + [&](int type, const google::protobuf::Message& msg, int node_id) { + return SendMsg(type, msg, node_id); + }); + + protocol->SetBroadcastCallFunc( + [&](int type, const google::protobuf::Message& msg) { + return Broadcast(type, msg); + }); + + protocol->SetCommitFunc( + [&](const google::protobuf::Message& msg) { + return CommitMsg(msg); + }); +} + +Consensus::~Consensus(){ + is_stop_ = true; +} + +void Consensus::SetPerformanceManager(std::unique_ptr performance_manager){ + performance_manager_ = std::move(performance_manager); +} + +bool Consensus::IsStop(){ + return is_stop_; +} + +void Consensus::SetupPerformanceDataFunc(std::function func) { + performance_manager_->SetDataFunc(func); +} + +void Consensus::SetCommunicator(ReplicaCommunicator* replica_communicator) { + replica_communicator_ = replica_communicator; +} + +int Consensus::Broadcast(int type, const google::protobuf::Message& msg) { + Request request; + msg.SerializeToString(request.mutable_data()); + request.set_type(Request::TYPE_CUSTOM_CONSENSUS); + request.set_user_type(type); + request.set_sender_id(config_.GetSelfInfo().id()); + + replica_communicator_->BroadCast(request); + return 0; +} + +int Consensus::SendMsg(int type, const google::protobuf::Message& msg, + int node_id) { + Request request; + msg.SerializeToString(request.mutable_data()); + request.set_type(Request::TYPE_CUSTOM_CONSENSUS); + request.set_user_type(type); + request.set_sender_id(config_.GetSelfInfo().id()); + replica_communicator_->SendMessage(request, node_id); + return 0; +} + +std::vector Consensus::GetReplicas() { + return config_.GetReplicaInfos(); +} + +int Consensus::CommitMsg(const google::protobuf::Message &txn) { + return 0; +} + +// The implementation of PBFT. +int Consensus::ConsensusCommit(std::unique_ptr context, + std::unique_ptr request) { + //LOG(ERROR)<<"receive commit:"<type()<<" "<type()); + switch (request->type()) { + case Request::TYPE_CLIENT_REQUEST: + if (config_.IsPerformanceRunning()) { + return performance_manager_->StartEval(); + } + case Request::TYPE_RESPONSE: + if (config_.IsPerformanceRunning()) { + return performance_manager_->ProcessResponseMsg(std::move(context), + std::move(request)); + } + case Request::TYPE_NEW_TXNS: { + return ProcessNewTransaction(std::move(request)); + } + case Request::TYPE_CUSTOM_CONSENSUS: { + return ProcessCustomConsensus(std::move(request)); + } + } + return 0; +} + +int Consensus::ProcessCustomConsensus(std::unique_ptr request) { + return 0; +} + +int Consensus::ProcessNewTransaction(std::unique_ptr request) { + return 0; +} + +int Consensus::ResponseMsg(const BatchUserResponse& batch_resp) { + Request request; + request.set_seq(batch_resp.seq()); + request.set_type(Request::TYPE_RESPONSE); + request.set_sender_id(config_.GetSelfInfo().id()); + request.set_proxy_id(batch_resp.proxy_id()); + batch_resp.SerializeToString(request.mutable_data()); + //global_stats_->AddResponseDelay(GetCurrentTime()- batch_resp.createtime()); + replica_communicator_->SendMessage(request, request.proxy_id()); + return 0; +} +/* +int Consensus::ResponseMsg(const BatchUserResponse& batch_resp) { + if (batch_resp.proxy_id() == 0) { + return 0; + } + resp_queue_.Push(std::make_unique(batch_resp)); + return 0; +} + +void Consensus::AsyncSend() { + while(!IsStop()){ + auto batch_resp = resp_queue_.Pop(); + if(batch_resp == nullptr) { + continue; + } + + //LOG(ERROR)<<"send response:"<seq()); + request.set_type(Request::TYPE_RESPONSE); + request.set_sender_id(config_.GetSelfInfo().id()); + request.set_proxy_id(batch_resp->proxy_id()); + batch_resp->SerializeToString(request.mutable_data()); + global_stats_->AddCommitDelay(GetCurrentTime()- batch_resp->createtime()); + replica_communicator_->SendMessage(request, request.proxy_id()); + } + return ; +} +*/ + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/consensus.h b/platform/consensus/ordering/common/framework/consensus.h new file mode 100644 index 000000000..881dc72bb --- /dev/null +++ b/platform/consensus/ordering/common/framework/consensus.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "executor/common/transaction_manager.h" +#include "platform/consensus/execution/transaction_executor.h" +#include "platform/consensus/ordering/common/algorithm/protocol_base.h" +#include "platform/consensus/ordering/common/framework/performance_manager.h" +#include "platform/consensus/ordering/common/framework/response_manager.h" +#include "platform/networkstrate/consensus_manager.h" + +namespace resdb { +namespace common { + +class Consensus : public ConsensusManager { + public: + Consensus(const ResDBConfig& config, + std::unique_ptr transaction_manager); + virtual ~Consensus(); + + int ConsensusCommit(std::unique_ptr context, + std::unique_ptr request) override; + std::vector GetReplicas() override; + + void SetupPerformanceDataFunc(std::function func); + + void SetCommunicator(ReplicaCommunicator* replica_communicator); + + void InitProtocol(ProtocolBase * protocol); + + protected: + virtual int ProcessCustomConsensus(std::unique_ptr request); + virtual int ProcessNewTransaction(std::unique_ptr request); + virtual int CommitMsg(const google::protobuf::Message& msg); + + protected: + int SendMsg(int type, const google::protobuf::Message& msg, int node_id); + int Broadcast(int type, const google::protobuf::Message& msg); + int ResponseMsg(const BatchUserResponse& batch_resp); + void AsyncSend(); + bool IsStop(); + + protected: + void Init(); + void SetPerformanceManager(std::unique_ptr performance_manger); + + protected: + ReplicaCommunicator* replica_communicator_; + std::unique_ptr performance_manager_; + std::unique_ptr response_manager_; + std::unique_ptr transaction_executor_; + Stats* global_stats_; + + LockFreeQueue resp_queue_; + std::vector send_thread_; + bool is_stop_; +}; + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/performance_manager.cpp b/platform/consensus/ordering/common/framework/performance_manager.cpp new file mode 100644 index 000000000..dd09dea7d --- /dev/null +++ b/platform/consensus/ordering/common/framework/performance_manager.cpp @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "platform/consensus/ordering/common/framework/performance_manager.h" + +#include + +#include "common/utils/utils.h" + +namespace resdb { +namespace common { + +using comm::CollectorResultCode; + +PerformanceManager::PerformanceManager( + const ResDBConfig& config, ReplicaCommunicator* replica_communicator, + SignatureVerifier* verifier) + : config_(config), + replica_communicator_(replica_communicator), + batch_queue_("user request"), + verifier_(verifier) { + stop_ = false; + eval_started_ = false; + eval_ready_future_ = eval_ready_promise_.get_future(); + if (config_.GetPublicKeyCertificateInfo() + .public_key() + .public_key_info() + .type() == CertificateKeyInfo::CLIENT) { + for (int i = 0; i < 1; ++i) { + user_req_thread_[i] = + std::thread(&PerformanceManager::BatchProposeMsg, this); + } + } + global_stats_ = Stats::GetGlobalStats(); + send_num_ = 0; + total_num_ = 0; + replica_num_ = config_.GetReplicaNum(); + id_ = config_.GetSelfInfo().id(); + primary_ = id_ % replica_num_; + if (primary_ == 0) primary_ = replica_num_; + local_id_ = 1; + sum_ = 0; +} + +PerformanceManager::~PerformanceManager() { + stop_ = true; + for (int i = 0; i < 16; ++i) { + if (user_req_thread_[i].joinable()) { + user_req_thread_[i].join(); + } + } +} + +int PerformanceManager::GetPrimary() { return primary_; } + +std::unique_ptr PerformanceManager::GenerateUserRequest() { + std::unique_ptr request = std::make_unique(); + /* // For transaction decryption + std::string test_data = data_func_(); + request->set_encrypted_data(test_data); + */ + request->set_data(data_func_()); + return request; +} + +void PerformanceManager::SetDataFunc(std::function func) { + data_func_ = std::move(func); +} + +int PerformanceManager::StartEval() { + if (eval_started_) { + return 0; + } + eval_started_ = true; + for (int i = 0; i < 5000000; ++i) { + // if (i%1000000 == 0) { + // LOG(ERROR) << "i: " << i; + // } + + // for (int i = 0; i < 60000000000; ++i) { + std::unique_ptr queue_item = std::make_unique(); + queue_item->context = nullptr; + queue_item->user_request = GenerateUserRequest(); + batch_queue_.Push(std::move(queue_item)); + if (i == 200000) { + eval_ready_promise_.set_value(true); + } + } + LOG(WARNING) << "start eval done"; + return 0; +} + +// =================== response ======================== +// handle the response message. If receive f+1 commit messages, send back to the +// user. +int PerformanceManager::ProcessResponseMsg(std::unique_ptr context, + std::unique_ptr request) { + std::unique_ptr response; + // Add the response message, and use the call back to collect the received + // messages. + // The callback will be triggered if it received f+1 messages. + if (request->ret() == -2) { + // LOG(INFO) << "get response fail:" << request->ret(); + send_num_--; + return 0; + } + + //LOG(INFO) << "get response:" << request->seq() << " sender:"<sender_id(); + std::unique_ptr batch_response = nullptr; + CollectorResultCode ret = + AddResponseMsg(std::move(request), [&](std::unique_ptr request) { + batch_response = std::move(request); + return; + }); + + if (ret == CollectorResultCode::STATE_CHANGED) { + assert(batch_response); + SendResponseToClient(*batch_response); + } + return ret == CollectorResultCode::INVALID ? -2 : 0; +} + +CollectorResultCode PerformanceManager::AddResponseMsg( + std::unique_ptr request, + std::function)> response_call_back) { + if (request == nullptr) { + return CollectorResultCode::INVALID; + } + + //uint64_t seq = request->seq(); + + std::unique_ptr batch_response = std::make_unique(); + if (!batch_response->ParseFromString(request->data())) { + LOG(ERROR) << "parse response fail:"<data().size() + <<" seq:"<seq(); return CollectorResultCode::INVALID; + } + + uint64_t seq = batch_response->local_id(); + //LOG(ERROR)<<"receive seq:"< lk(response_lock_[idx]); + if (response_[idx].find(seq) == response_[idx].end()) { + //LOG(ERROR)<<"has done local seq:"<seq(); + return CollectorResultCode::OK; + } + response_[idx][seq]++; + //LOG(ERROR)<<"get seq :"<seq()<<" local id:"<= config_.GetMinClientReceiveNum()) { + //LOG(ERROR)<<"get seq :"<seq()<<" local id:"< 0) { + uint64_t run_time = GetCurrentTime() - create_time; + //LOG(ERROR)<<"receive current:"<AddLatency(run_time); + } else { + } + //send_num_-=10; + send_num_--; +} + +// =================== request ======================== +int PerformanceManager::BatchProposeMsg() { + LOG(WARNING) << "batch wait time:" << config_.ClientBatchWaitTimeMS() + << " batch num:" << config_.ClientBatchNum() + << " max txn:" << config_.GetMaxProcessTxn(); + std::vector> batch_req; + eval_ready_future_.get(); + bool start = false; + while (!stop_) { + if (send_num_ > config_.GetMaxProcessTxn()) { + // LOG(ERROR)<<"wait send num:"< item = + batch_queue_.Pop(config_.ClientBatchWaitTimeMS()); + if (item == nullptr) { + if(start){ + LOG(ERROR)<<"no data"; + } + continue; + } + batch_req.push_back(std::move(item)); + if (batch_req.size() < config_.ClientBatchNum()) { + continue; + } + } + start = true; + for(int i = 0; i < 1;++i){ + int ret = DoBatch(batch_req); + } + batch_req.clear(); + } + return 0; +} + +int PerformanceManager::DoBatch( + const std::vector>& batch_req) { + auto new_request = comm::NewRequest(Request::TYPE_NEW_TXNS, Request(), + config_.GetSelfInfo().id()); + if (new_request == nullptr) { + return -2; + } + + BatchUserRequest batch_request; + for (size_t i = 0; i < batch_req.size(); ++i) { + BatchUserRequest::UserRequest* req = batch_request.add_user_requests(); + *req->mutable_request() = *batch_req[i]->user_request.get(); + req->set_id(i); + } + + batch_request.set_local_id(local_id_++); + + { + int idx = batch_request.local_id() % response_set_size_; + std::unique_lock lk(response_lock_[idx]); + response_[idx][batch_request.local_id()]++; + } + + batch_request.set_proxy_id(config_.GetSelfInfo().id()); + batch_request.set_createtime(GetCurrentTime()); + batch_request.SerializeToString(new_request->mutable_data()); + if (verifier_) { + auto signature_or = verifier_->SignMessage(new_request->data()); + if (!signature_or.ok()) { + LOG(ERROR) << "Sign message fail"; + return -2; + } + *new_request->mutable_data_signature() = *signature_or; + } + + new_request->set_hash(SignatureVerifier::CalculateHash(new_request->data())); + new_request->set_proxy_id(config_.GetSelfInfo().id()); + new_request->set_user_seq(batch_request.local_id()); + + SendMessage(*new_request); + + global_stats_->BroadCastMsg(); + send_num_++; + sum_ += batch_req.size(); + //LOG(ERROR)<<"send num:"<IncClientCall(); + return 0; +} + +void PerformanceManager::SendMessage(const Request& request){ + replica_communicator_->SendMessage(request, GetPrimary()); +} + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/performance_manager.h b/platform/consensus/ordering/common/framework/performance_manager.h new file mode 100644 index 000000000..5a874baa9 --- /dev/null +++ b/platform/consensus/ordering/common/framework/performance_manager.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include + +#include "platform/config/resdb_config.h" +#include "platform/consensus/ordering/common/framework/transaction_utils.h" +#include "platform/networkstrate/replica_communicator.h" +#include "platform/networkstrate/server_comm.h" +#include "platform/statistic/stats.h" + +namespace resdb { +namespace common { + +class PerformanceManager { + public: + PerformanceManager(const ResDBConfig& config, + ReplicaCommunicator* replica_communicator, + SignatureVerifier* verifier); + + virtual ~PerformanceManager(); + + int StartEval(); + + int ProcessResponseMsg(std::unique_ptr context, + std::unique_ptr request); + void SetDataFunc(std::function func); + + protected: + virtual void SendMessage(const Request& request); + + private: + // Add response messages which will be sent back to the caller + // if there are f+1 same messages. + comm::CollectorResultCode AddResponseMsg( + std::unique_ptr request, + std::function)> call_back); + void SendResponseToClient(const BatchUserResponse& batch_response); + + struct QueueItem { + std::unique_ptr context; + std::unique_ptr user_request; + }; + int DoBatch(const std::vector>& batch_req); + int BatchProposeMsg(); + int GetPrimary(); + std::unique_ptr GenerateUserRequest(); + + protected: + ResDBConfig config_; + ReplicaCommunicator* replica_communicator_; + + private: + LockFreeQueue batch_queue_; + std::thread user_req_thread_[16]; + std::atomic stop_; + Stats* global_stats_; + std::atomic send_num_; + std::mutex mutex_; + std::atomic total_num_; + SignatureVerifier* verifier_; + SignatureInfo sig_; + std::function data_func_; + std::future eval_ready_future_; + std::promise eval_ready_promise_; + std::atomic eval_started_; + std::atomic fail_num_; + static const int response_set_size_ = 6000000; + std::map response_[response_set_size_]; + std::mutex response_lock_[response_set_size_]; + int replica_num_; + int id_; + int primary_; + std::atomic local_id_; + std::atomic sum_; +}; + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/response_manager.cpp b/platform/consensus/ordering/common/framework/response_manager.cpp new file mode 100644 index 000000000..ae6b55cc0 --- /dev/null +++ b/platform/consensus/ordering/common/framework/response_manager.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "platform/consensus/ordering/common/framework/response_manager.h" + +#include + +#include "common/utils/utils.h" + +namespace resdb { +namespace common { + +using namespace resdb::comm; + +ResponseManager::ResponseManager(const ResDBConfig& config, + ReplicaCommunicator* replica_communicator, + SignatureVerifier* verifier) + : config_(config), + replica_communicator_(replica_communicator), + batch_queue_("user request"), + verifier_(verifier) { + stop_ = false; + local_id_ = 1; + + if (config_.GetPublicKeyCertificateInfo() + .public_key() + .public_key_info() + .type() == CertificateKeyInfo::CLIENT || + config_.IsTestMode()) { + user_req_thread_ = std::thread(&ResponseManager::BatchProposeMsg, this); + } + global_stats_ = Stats::GetGlobalStats(); + send_num_ = 0; +} + +ResponseManager::~ResponseManager() { + stop_ = true; + if (user_req_thread_.joinable()) { + user_req_thread_.join(); + } +} + +// use system info +int ResponseManager::GetPrimary() { return 1; } + +int ResponseManager::NewUserRequest(std::unique_ptr context, + std::unique_ptr user_request) { + context->client = nullptr; + + std::unique_ptr queue_item = std::make_unique(); + queue_item->context = std::move(context); + queue_item->user_request = std::move(user_request); + + batch_queue_.Push(std::move(queue_item)); + return 0; +} + +// =================== response ======================== +// handle the response message. If receive f+1 commit messages, send back to the +// caller. +int ResponseManager::ProcessResponseMsg(std::unique_ptr context, + std::unique_ptr request) { + std::unique_ptr response; + // Add the response message, and use the call back to collect the received + // messages. + // The callback will be triggered if it received f+1 messages. + if (request->ret() == -2) { + LOG(ERROR) << "get response fail:" << request->ret(); + send_num_--; + return 0; + } + CollectorResultCode ret = + AddResponseMsg(std::move(request), [&](const Request& request) { + response = std::make_unique(request); + return; + }); + + if (ret == CollectorResultCode::STATE_CHANGED) { + BatchUserResponse batch_response; + if (batch_response.ParseFromString(response->data())) { + SendResponseToClient(batch_response); + } else { + LOG(ERROR) << "parse response fail:"; + } + } + return ret == CollectorResultCode::INVALID ? -2 : 0; +} + +CollectorResultCode ResponseManager::AddResponseMsg( + std::unique_ptr request, + std::function response_call_back) { + if (request == nullptr) { + return CollectorResultCode::INVALID; + } + + int type = request->type(); + uint64_t seq = request->seq(); + bool done = false; + { + int idx = seq % response_set_size_; + std::unique_lock lk(response_lock_[idx]); + if (response_[idx][seq] == -1) { + return CollectorResultCode::OK; + } + response_[idx][seq]++; + if (response_[idx][seq] >= config_.GetMinClientReceiveNum()) { + response_[idx][seq] = -1; + done = true; + } + } + if (done) { + response_call_back(*request); + return CollectorResultCode::STATE_CHANGED; + } + return CollectorResultCode::OK; +} + +void ResponseManager::SendResponseToClient( + const BatchUserResponse& batch_response) { + uint64_t create_time = batch_response.createtime(); + uint64_t local_id = batch_response.local_id(); + if (create_time > 0) { + uint64_t run_time = GetCurrentTime() - create_time; + global_stats_->AddLatency(run_time); + } else { + LOG(ERROR) << "seq:" << local_id << " no resp"; + } + send_num_--; +} + +// =================== request ======================== +int ResponseManager::BatchProposeMsg() { + LOG(INFO) << "batch wait time:" << config_.ClientBatchWaitTimeMS() + << " batch num:" << config_.ClientBatchNum(); + std::vector> batch_req; + while (!stop_) { + if (send_num_ > config_.GetMaxProcessTxn()) { + LOG(ERROR) << "send num too high, wait:" << send_num_; + usleep(100); + continue; + } + if (batch_req.size() < config_.ClientBatchNum()) { + std::unique_ptr item = + batch_queue_.Pop(config_.ClientBatchWaitTimeMS()); + if (item != nullptr) { + batch_req.push_back(std::move(item)); + if (batch_req.size() < config_.ClientBatchNum()) { + continue; + } + } + } + if (batch_req.empty()) { + continue; + } + int ret = DoBatch(batch_req); + batch_req.clear(); + if (ret != 0) { + Response response; + response.set_result(Response::ERROR); + for (size_t i = 0; i < batch_req.size(); ++i) { + if (batch_req[i]->context && batch_req[i]->context->client) { + int ret = batch_req[i]->context->client->SendRawMessage(response); + if (ret) { + LOG(ERROR) << "send resp" << response.DebugString() + << " fail ret:" << ret; + } + } + } + } + } + return 0; +} + +int ResponseManager::DoBatch( + const std::vector>& batch_req) { + auto new_request = + NewRequest(Request::TYPE_NEW_TXNS, Request(), config_.GetSelfInfo().id()); + if (new_request == nullptr) { + return -2; + } + std::vector> context_list; + + BatchUserRequest batch_request; + for (size_t i = 0; i < batch_req.size(); ++i) { + BatchUserRequest::UserRequest* req = batch_request.add_user_requests(); + *req->mutable_request() = *batch_req[i]->user_request.get(); + *req->mutable_signature() = batch_req[i]->context->signature; + req->set_id(i); + context_list.push_back(std::move(batch_req[i]->context)); + } + + if (!config_.IsPerformanceRunning()) { + LOG(ERROR) << "add context list:" << new_request->seq() + << " list size:" << context_list.size(); + batch_request.set_local_id(local_id_); + } + batch_request.set_createtime(GetCurrentTime()); + std::string data; + batch_request.SerializeToString(&data); + if (verifier_) { + auto signature_or = verifier_->SignMessage(data); + if (!signature_or.ok()) { + LOG(ERROR) << "Sign message fail"; + return -2; + } + *new_request->mutable_data_signature() = *signature_or; + } + + batch_request.SerializeToString(new_request->mutable_data()); + new_request->set_hash(SignatureVerifier::CalculateHash(new_request->data())); + new_request->set_proxy_id(config_.GetSelfInfo().id()); + replica_communicator_->SendMessage(*new_request, GetPrimary()); + send_num_++; + LOG(INFO) << "send msg to primary:" << GetPrimary() + << " batch size:" << batch_req.size(); + return 0; +} + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/response_manager.h b/platform/consensus/ordering/common/framework/response_manager.h new file mode 100644 index 000000000..1c7043964 --- /dev/null +++ b/platform/consensus/ordering/common/framework/response_manager.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "platform/config/resdb_config.h" +#include "platform/consensus/ordering/common/framework/transaction_utils.h" +#include "platform/networkstrate/replica_communicator.h" +#include "platform/networkstrate/server_comm.h" +#include "platform/statistic/stats.h" + +namespace resdb { +namespace common { + +class ResponseManager { + public: + ResponseManager(const ResDBConfig& config, + ReplicaCommunicator* replica_communicator, + SignatureVerifier* verifier); + + ~ResponseManager(); + + std::vector> FetchContextList(uint64_t id); + + int NewUserRequest(std::unique_ptr context, + std::unique_ptr user_request); + + int ProcessResponseMsg(std::unique_ptr context, + std::unique_ptr request); + + private: + // Add response messages which will be sent back to the caller + // if there are f+1 same messages. + comm::CollectorResultCode AddResponseMsg( + std::unique_ptr request, + std::function call_back); + void SendResponseToClient(const BatchUserResponse& batch_response); + + struct QueueItem { + std::unique_ptr context; + std::unique_ptr user_request; + }; + int DoBatch(const std::vector>& batch_req); + int BatchProposeMsg(); + int GetPrimary(); + + private: + ResDBConfig config_; + ReplicaCommunicator* replica_communicator_; + LockFreeQueue batch_queue_; + std::thread user_req_thread_; + std::atomic stop_; + uint64_t local_id_ = 0; + Stats* global_stats_; + std::atomic send_num_; + SignatureVerifier* verifier_; + static const int response_set_size_ = 6000000; + std::map response_[response_set_size_]; + std::mutex response_lock_[response_set_size_]; +}; + +} // common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/transaction_utils.cpp b/platform/consensus/ordering/common/framework/transaction_utils.cpp new file mode 100644 index 000000000..08a8e5444 --- /dev/null +++ b/platform/consensus/ordering/common/framework/transaction_utils.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "platform/consensus/ordering/common/framework/transaction_utils.h" + +namespace resdb { +namespace comm { + +std::unique_ptr NewRequest(Request::Type type, const Request& request, + int sender_id) { + auto new_request = std::make_unique(request); + new_request->set_type(type); + new_request->set_sender_id(sender_id); + return new_request; +} + +std::unique_ptr NewRequest(Request::Type type, const Request& request, + int sender_id, int region_id) { + auto new_request = std::make_unique(request); + new_request->set_type(type); + new_request->set_sender_id(sender_id); + new_request->mutable_region_info()->set_region_id(region_id); + return new_request; +} + +} // namespace comm +} // namespace resdb diff --git a/chain/storage/res_rocksdb.h b/platform/consensus/ordering/common/framework/transaction_utils.h similarity index 57% rename from chain/storage/res_rocksdb.h rename to platform/consensus/ordering/common/framework/transaction_utils.h index 706957c2f..3055cf44c 100644 --- a/chain/storage/res_rocksdb.h +++ b/platform/consensus/ordering/common/framework/transaction_utils.h @@ -24,38 +24,22 @@ */ #pragma once - -#include -#include - -#include "chain/storage/storage.h" #include "platform/proto/replica_info.pb.h" -#include "rocksdb/db.h" -#include "rocksdb/write_batch.h" +#include "platform/proto/resdb.pb.h" namespace resdb { +namespace comm { -std::unique_ptr NewResRocksDB( - const char* cert_file, std::optional config_data); - -class ResRocksDB : public Storage { - public: - ResRocksDB(const char* cert_file, std::optional config_data); - virtual ~ResRocksDB(); - int SetValue(const std::string& key, const std::string& value) override; - std::string GetValue(const std::string& key) override; - std::string GetAllValues(void) override; - std::string GetRange(const std::string& min_key, - const std::string& max_key) override; - - bool Flush() override; - - private: - std::unique_ptr db_ = nullptr; - rocksdb::WriteBatch batch_; - unsigned int num_threads_ = 1; - unsigned int write_buffer_size_ = 64 << 20; - unsigned int write_batch_size_ = 1; +enum CollectorResultCode { + INVALID = -2, + OK = 0, + STATE_CHANGED = 1, }; +std::unique_ptr NewRequest(Request::Type type, const Request& request, + int sender_id); + +std::unique_ptr NewRequest(Request::Type type, const Request& request, + int sender_id, int region_info); +} // namespace comm } // namespace resdb diff --git a/platform/consensus/ordering/common/transaction_utils.cpp b/platform/consensus/ordering/common/transaction_utils.cpp index e560cfc9c..fea180a0b 100644 --- a/platform/consensus/ordering/common/transaction_utils.cpp +++ b/platform/consensus/ordering/common/transaction_utils.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/common/transaction_utils.h" diff --git a/platform/consensus/ordering/common/transaction_utils.h b/platform/consensus/ordering/common/transaction_utils.h index b0d6aab29..151b431c3 100644 --- a/platform/consensus/ordering/common/transaction_utils.h +++ b/platform/consensus/ordering/common/transaction_utils.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/fides/algorithm/BUILD b/platform/consensus/ordering/fides/algorithm/BUILD new file mode 100644 index 000000000..adf568035 --- /dev/null +++ b/platform/consensus/ordering/fides/algorithm/BUILD @@ -0,0 +1,42 @@ +package(default_visibility = ["//platform/consensus/ordering/fides:__subpackages__"]) + +cc_library( + name = "proposal_manager", + srcs = ["proposal_manager.cpp"], + hdrs = ["proposal_manager.h"], + copts = ["-Iexternal/openenclave"], + deps = [ + "//common:comm", + "//common/crypto:signature_verifier", + "//common/utils", + "//platform/consensus/ordering/fides/proto:proposal_cc_proto", + "//enclave:headers", + ], +) + +cc_library( + name = "fides", + srcs = ["fides.cpp"], + hdrs = ["fides.h"], + copts = ["-Iexternal/openenclave"], + deps = [ + ":proposal_manager", + "//common:comm", + "//common/crypto:signature_verifier", + "//platform/common/queue:lock_free_queue", + "//platform/consensus/ordering/common/algorithm:protocol_base", + "//platform/statistic:stats", + "//enclave:headers", + "//platform/proto:resdb_cc_proto", + "//executor/kv:kv_executor", + ], +) + +cc_library( + name = "transaction_collector", + srcs = ["transaction_collector.cpp"], + hdrs = ["transaction_collector.h"], + deps = [ + "//platform/statistic:stats", + ], +) diff --git a/platform/consensus/ordering/fides/algorithm/fides.cpp b/platform/consensus/ordering/fides/algorithm/fides.cpp new file mode 100644 index 000000000..c28dea0da --- /dev/null +++ b/platform/consensus/ordering/fides/algorithm/fides.cpp @@ -0,0 +1,703 @@ +#include "platform/consensus/ordering/fides/algorithm/fides.h" + +#include + +#include "common/utils/utils.h" + +namespace resdb { +namespace fides { + +Fides::Fides(int id, int f, int total_num, SignatureVerifier* verifier, const ResDBConfig& config, oe_enclave_t* enclave) + : ProtocolBase(id, f, total_num), verifier_(verifier), config_(config), enclave_(enclave) { + // TODO: 5.Quorum to f+1 - Done + limit_count_ = f + 1; + batch_size_ = 5; + proposal_manager_ = std::make_unique(id, limit_count_, enclave); + + execute_id_ = 1; + start_ = 0; + queue_size_ = 0; + + send_thread_ = std::thread(&Fides::AsyncSend, this); + commit_thread_ = std::thread(&Fides::AsyncCommit, this); + execute_thread_ = std::thread(&Fides::AsyncExecute, this); + cert_thread_ = std::thread(&Fides::AsyncProcessCert, this); + + global_stats_ = Stats::GetGlobalStats(); + + LOG(ERROR) << "id:" << id << " f:" << f << " failureNum:" << config_.GetFailureNum() << " total:" << total_num; +} + +Fides::~Fides() { + if (send_thread_.joinable()) { + send_thread_.join(); + } + if (commit_thread_.joinable()) { + commit_thread_.join(); + } + if(cert_thread_.joinable()){ + cert_thread_.join(); + } +} + +// TODO: 1.Change this to Using trusted global random +// TODO: Not every round has a different leader +int Fides::GetLeader(int r) { + // return r / 2 % total_num_ + 1; + { + std::unique_lock lk(leader_list_mutex_); + if (leader_list_.count(r) != 0) { + return leader_list_[r]; + } + if (r % 3 != 0) { + leader_list_[r] = leader_list_[r-1]; + return leader_list_[r]; + } + } + + int ret; + uint32_t randNum; + + // Send f+1 counter value and attestation to proof can obtain new random number + std::vector counters; + if(r > 0) { + // LOG(ERROR)<<"In GetLeader. round:"<GetCounterFromRound(r - 1); + assert(counters.size()>=limit_count_); + } + + size_t previous_cert_size = counters.size(); + unsigned char** attestation_array = new unsigned char*[previous_cert_size]; + size_t* attestation_size_array = new size_t[previous_cert_size]; + uint32_t* counter_value_array = new uint32_t[previous_cert_size]; + int i = 0; + + std::string serialized_data; + for (size_t i = 0; i < counters.size(); ++i) { + // LOG(ERROR)<<"attestation is: "< lk(leader_list_mutex_); + leader_list_[r] = randNum + 1; + return leader_list_[r]; +} + + +void Fides::AsyncSend() { + + uint64_t last_time = 0; + while (!IsStop()) { + auto txn = txns_.Pop(); + if (txn == nullptr) { + if(start_){ + //LOG(ERROR)<<"not enough txn"; + //break; + } + continue; + } + + queue_size_--; + //LOG(ERROR)<<"txn before waiting time:"<create_time()<<" queue size:"<CurrentRound(); + std::unique_lock lk(mutex_); + vote_cv_.wait_for(lk, std::chrono::microseconds(10000), + [&] { return proposal_manager_->Ready(); }); + + if (proposal_manager_->Ready()) { + start_ = 1; + break; + } + } + + //LOG(ERROR)<<"txn waiting time:"<create_time(); + txn->set_queuing_time(GetCurrentTime() - txn->create_time()); + global_stats_->AddQueuingLatency(GetCurrentTime() - txn->create_time()); + global_stats_->AddRoundLatency(GetCurrentTime() - last_time); + last_time = GetCurrentTime(); + + std::vector> txns; + txns.push_back(std::move(txn)); + for (int i = 1; i < batch_size_; ++i) { + auto txn = txns_.Pop(10); + if (txn == nullptr) { + continue; + break; + } + txn->set_queuing_time(GetCurrentTime() - txn->create_time()); + queue_size_--; + global_stats_->AddQueuingLatency(GetCurrentTime() - txn->create_time()); + txns.push_back(std::move(txn)); + } + + global_stats_->ConsumeTransactions(queue_size_); + + auto proposal = proposal_manager_->GenerateProposal(txns); + Broadcast(MessageType::NewBlock, *proposal); + + std::string block_data; + proposal->SerializeToString(&block_data); + global_stats_->AddBlockSize(block_data.size()); + + proposal_manager_->AddLocalBlock(std::move(proposal)); + + int round = proposal_manager_->CurrentRound() - 1; + //LOG(ERROR) << "bc txn:" << txns.size() << " round:" << round; + // TODO: change commit rule here + if (round > 1) { + if (round % 3 == 0) { + CommitRound(round - 3); + } + } + } +} + +// TODO: Change commit rule here. +void Fides::AsyncCommit() { + int previous_round = -3; + while (!IsStop()) { + std::unique_ptr round_or = commit_queue_.Pop(); + if (round_or == nullptr) { + continue; + } + + int round = *round_or; + //int64_t start_time = GetCurrentTime(); + //LOG(ERROR) << "commit round:" << round; + + int new_round = previous_round; + for (int r = previous_round + 3; r <= round; r += 3) { + int leader = GetLeader(r); + const Proposal * req = nullptr; + while(!IsStop()){ + req = proposal_manager_->GetRequest(r, leader); + // req:"<<(req==nullptr); + if (req == nullptr) { + //LOG(ERROR)<<" get leader:"< lk(mutex_); + vote_cv_.wait_for(lk, std::chrono::microseconds(100), + [&] { return true; }); + + continue; + } + break; + } + //LOG(ERROR)<<" get leader:"<header().create_time()); + int reference_num = proposal_manager_->GetReferenceNum(*req); + //LOG(ERROR)<<" get leader:"<GetRequest(j, pre_leader); + if (req == nullptr) { + continue; + } + int reference_num = proposal_manager_->GetReferenceNum(*req); + if (reference_num < limit_count_) { + continue; + } + + CommitProposal(j, pre_leader); + } + } + new_round = r; + } + //int64_t end_time = GetCurrentTime(); + //global_stats_->AddCommitRuntime(end_time-commit_time); + previous_round = new_round; + } +} + +// TODO: 3.Decrypt the request before executing. +void Fides::AsyncExecute() { +int64_t last_commit_time = 0; +int last_round = 0; + while (!IsStop()) { + std::unique_ptr proposal = execute_queue_.Pop(); + if (proposal == nullptr) { + continue; + } + + int commit_round = proposal->header().round(); + int64_t commit_time = GetCurrentTime(); + int64_t waiting_time = commit_time - proposal->queuing_time(); + global_stats_->AddCommitQueuingLatency(waiting_time); + //global_stats_->AddCommitInterval(commit_time - last_commit_time); + //last_commit_time = commit_time; + std::map>> ps; + std::queue> q; + q.push(std::move(proposal)); + + //LOG(ERROR)<<" commit round:"<SetCommittedRound(commit_round); + + //global_stats_->AddCommitRoundLatency(commit_round - last_round); + //last_round = commit_round; + + //int64_t start_time = GetCurrentTime(); + while (!q.empty()) { + std::unique_ptr p = std::move(q.front()); + q.pop(); + + for (auto& link : p->header().strong_cert().cert()) { + int link_round = link.round(); + int link_proposer = link.proposer(); + auto next_p = + proposal_manager_->FetchRequest(link_round, link_proposer); + if (next_p == nullptr) { + continue; + } + q.push(std::move(next_p)); + } + + + for (auto& link : p->header().weak_cert().cert()) { + int link_round = link.round(); + int link_proposer = link.proposer(); + auto next_p = + proposal_manager_->FetchRequest(link_round, link_proposer); + if (next_p == nullptr) { + // LOG(ERROR)<<"no data round:"<header().round()].push_back(std::move(p)); + } + + int num = 0; + int pro = 0; + for (auto& it : ps) { + for (auto& p : it.second) { + //LOG(ERROR) << "=============== commit proposal round :" + // << p->header().round() + // << " header round:"<header().round() + // << " commit round:"<header().proposer_id() + // << " transaction size:" << p->transactions_size() + // << " commit time:" + // << (GetCurrentTime() - p->header().create_time()) + // << " create time:" << p->header().create_time() + // <<" execute id:"<header().round()); + + global_stats_->AddCommitLatency(commit_time - p->header().create_time() - waiting_time); + global_stats_->AddCommitRoundLatency(commit_round - p->header().round()); + + // BatchUserRequest batch_request; // For transaction decryption + for (auto& tx : *p->mutable_transactions()) { + tx.set_id(execute_id_++); + num++; + // LOG(ERROR)<<" commit txn create time 1:"<(const_cast(encrypted_data.c_str())); + + // result = decrypt(enclave_, &ret, request_data, &decrypted_data, encrypted_data.size(), &decrypted_len); + // if (result != OE_OK || ret != 0) { + // LOG(ERROR) << "Host: decrypt failed with " << ret; + // LOG(ERROR) << "encrypted_data: "<mutable_request()->set_encrypted_data(""); + batch_request.mutable_user_requests(i)->mutable_request()->set_data(decrypted_request); + // user_request->set_data(decrypted_request); + // usleep(2000); + } + std::string new_tx_data; + batch_request.SerializeToString(&new_tx_data); + tx.set_data(new_tx_data); + */ + Commit(tx); + } + pro++; + } + } + int64_t end_time = GetCurrentTime(); + global_stats_->AddCommitRuntime(end_time-commit_time); + global_stats_->AddCommitTxn(num); + global_stats_->AddCommitBlock(pro); + } +} + +void Fides::CommitProposal(int round, int proposer) { + //LOG(ERROR) << "commit round:" << round << " proposer:" << proposer; + + //int64_t last_commit_time = 0; + int64_t commit_time = GetCurrentTime(); + global_stats_->AddCommitInterval(commit_time - last_commit_time_); + last_commit_time_ = commit_time; + + std::unique_ptr p = + proposal_manager_->FetchRequest(round, proposer); + if(p==nullptr){ + LOG(ERROR)<<"commit round:"<set_queuing_time(GetCurrentTime()); + execute_queue_.Push(std::move(p)); +} + +void Fides::CommitRound(int round) { + //LOG(ERROR)<<" commit round:"<(round)); +} + +bool Fides::ReceiveTransaction(std::unique_ptr txn) { + // LOG(ERROR)<<"recv txn"; + txn->set_create_time(GetCurrentTime()); + txns_.Push(std::move(txn)); + queue_size_++; + if (start_ == 0) { + std::unique_lock lk(mutex_); + vote_cv_.notify_all(); + } + return true; +} + +bool Fides::ReceiveBlock(std::unique_ptr proposal) { + //LOG(ERROR) << "recv block from " << proposal->header().proposer_id() + // << " round:" << proposal->header().round(); + int proposer_id = proposal->header().proposer_id(); + int round = proposal->header().round(); + std::string hash = proposal->hash(); + + { + std::unique_lock lk(check_block_mutex_); + proposal->set_queuing_time(GetCurrentTime()); + //std::unique_lock lk(check_block_mutex_); + // Verify the block, including the counter + if(!CheckBlock(*proposal)){ + std::unique_lock lk(future_block_mutex_); + //LOG(ERROR)<<"add future block:"<header().round()<<" sender:"<header().proposer_id(); + future_block_[proposal->header().round()][proposal->hash()] = std::move(proposal); + return false; + } + } + + // Generate certificate + auto cert = std::make_unique(); + global_stats_->AddExecutePrepareDelay(GetCurrentTime() - proposal->header().create_time()); + //global_stats_->AddCommitLatency(GetCurrentTime() - proposal->header().create_time()); + + cert->set_hash(hash); + cert->set_round(round); + cert->set_proposer(proposer_id); + *cert->mutable_strong_cert() = proposal->header().strong_cert(); + *cert->mutable_counter() = proposal->header().counter(); + + { + std::unique_lock lk(txn_mutex_); + //LOG(ERROR) << "recv block from " << proposal->header().proposer_id() + // << " round:" << proposal->header().round(); + global_stats_->AddCommitWaitingLatency(GetCurrentTime() - proposal->queuing_time()); + proposal->set_queuing_time(0); + { + // std::unique_lock lk(check_block_mutex_); + proposal_manager_->AddBlock(std::move(proposal)); + // CheckFutureCert(round, hash, proposer); + } + } + + ReceiveBlockCert(std::move(cert)); + + return true; + // return SendBlockAck(std::move(proposal)); +} + +/* +void Fides::ReceiveBlockACK(std::unique_ptr metadata) { + std::string hash = metadata->hash(); + int round = metadata->round(); + int sender = metadata->sender(); + std::unique_lock lk(txn_mutex_); + received_num_[hash][sender] = std::move(metadata); + //LOG(ERROR) << "recv block ack from:" << sender << " num:" << received_num_[hash].size()<<" round:"<GetLocalBlock(hash); + assert(p != nullptr); + assert(p->header().proposer_id() == id_); + assert(p->header().round() == round); + global_stats_->AddExecutePrepareDelay(GetCurrentTime() - p->header().create_time()); + //global_stats_->AddCommitLatency(GetCurrentTime() - p->header().create_time()); + *cert.mutable_strong_cert() = p->header().strong_cert(); + //LOG(ERROR)<<"send cert, round:"<header().round(); + Broadcast(MessageType::Cert, cert); + } +} +*/ + +bool Fides::VerifyCert(const Certificate & cert){ + // std::map hash_num; + // bool vote_num = false; + // for(auto& metadata: cert.metadata()){ + // bool valid = verifier_->VerifyMessage(metadata.hash(), metadata.sign()); + // if(!valid){ + // return false; + // } + // hash_num[metadata.hash()]++; + // if(hash_num[metadata.hash()]>=2*f_+1){ + // vote_num = true; + // } + // } + // return vote_num; + // TODO: change quorum here + return true; +} + +bool Fides::VerifyCounter(int round, const CounterInfo& counter) { + std::string attestation = counter.attestation(); + int counter_value = counter.value(); + if (attestation != "Fake Attestation" || counter_value != round) { + return false; + } + return true; +} + +bool Fides::CheckBlock(const Proposal& p){ + for(auto& link : p.header().strong_cert().cert()){ + int link_round = link.round(); + int link_proposer = link.proposer(); + if(!proposal_manager_->CheckCert(link_round, link_proposer)){ + //LOG(ERROR)<<" check block round:"<CheckCert(link_round, link_proposer)){ + //LOG(ERROR)<<" check block round:"<CheckBlock(cert.hash())){ + //future_cert_[cert->round()][cert->hash()] = std::move(cert); + return false; + } + return true; +} + +/* +bool Fides::SendBlockAck(std::unique_ptr proposal) { + + Metadata metadata; + metadata.set_sender(id_); + metadata.set_hash(proposal->hash()); + metadata.set_round(proposal->header().round()); + metadata.set_proposer(proposal->header().proposer_id()); + + std::string data_str = proposal->hash(); + auto hash_signature_or = verifier_->SignMessage(data_str); + if (!hash_signature_or.ok()) { + LOG(ERROR) << "Sign message fail"; + return false; + } + *metadata.mutable_sign()=*hash_signature_or; + metadata.set_sender(id_); + + { + //std::unique_lock lk(txn_mutex_); + //LOG(ERROR) << "recv block from " << proposal->header().proposer_id() + // << " round:" << proposal->header().round(); + int round = proposal->header().round(); + std::string hash = proposal->hash(); + int proposer = proposal->header().proposer_id(); + global_stats_->AddCommitWaitingLatency(GetCurrentTime() - proposal->queuing_time()); + proposal->set_queuing_time(0); + { + //std::unique_lock lk(check_block_mutex_); + proposal_manager_->AddBlock(std::move(proposal)); + CheckFutureCert(round, hash, proposer); + } + } + // SendMessage(MessageType::BlockACK, metadata, metadata.proposer()); + return true; +} +*/ + + +void Fides::CheckFutureBlock(int round){ + //LOG(ERROR)<<" check block round from cert:"<> hashs; + { + std::unique_lock clk(check_block_mutex_); + + { + std::unique_lock lk(future_block_mutex_); + if(future_block_.find(round) == future_block_.end()){ + return; + } + for(auto& it : future_block_[round]){ + if(CheckBlock(*it.second)){ + LOG(ERROR)<<" add new block round:"<header().round(); + hashs[it.first] = std::move(it.second); + } + } + + LOG(ERROR)<<" check round:"<header().round()<<" proposer:"<header().proposer_id(); + int block_round = it.second->header().round(); + //std::unique_lock lk(check_block_mutex_); + { + std::unique_lock lk(future_cert_mutex_); + if(future_cert_[block_round].find(it.first) != future_cert_[block_round].end()){ + std::unique_ptr cert = std::move(future_cert_[block_round][it.first]); + //LOG(ERROR)<<" add new cert:"<proposer(); + cert_queue_.Push(std::move(cert)); + future_cert_[block_round].erase(future_cert_[block_round].find(it.first)); + if(future_cert_[block_round].size() == 0){ + future_cert_.erase(future_cert_.find(block_round)); + } + } + } + + //LOG(ERROR)<<" Redo the proposal again, round: "< lk(future_cert_mutex_); + auto it = future_cert_[round].find(hash); + if(it != future_cert_[round].end()){ + //LOG(ERROR)<<" add back future cert, round:"<second)); + future_cert_[round].erase(it); + if(future_cert_[round].empty()){ + future_cert_.erase(future_cert_.find(round)); + } + } +} +*/ + +void Fides::AsyncProcessCert(){ + while(!IsStop()){ + std::unique_ptr cert = cert_queue_.Pop(); + if(cert == nullptr){ + continue; + } + + int round = cert->round(); + int cert_sender = cert->proposer(); + + //LOG(ERROR)<<" add cert, round:"< clk(check_block_mutex_); + proposal_manager_->AddCert(std::move(cert)); + { + std::unique_lock lk(mutex_); + vote_cv_.notify_all(); + } + } + CheckFutureBlock(round+1); + } +} + +void Fides::ReceiveBlockCert(std::unique_ptr cert) { + int64_t start_time = GetCurrentTime(); + if(!VerifyCert(*cert)){ + assert(1==0); + return; + } + + { + std::unique_lock lk(check_block_mutex_); + if(!CheckCert(*cert)){ + //LOG(ERROR)<<" add future cert round:"<round()<<" proposer:"<proposer(); + std::unique_lock lk(future_cert_mutex_); + future_cert_[cert->round()][cert->hash()] = std::move(cert); + return; + } + } + + int64_t end_time = GetCurrentTime(); + global_stats_->AddVerifyLatency(end_time-start_time); + + cert_queue_.Push(std::move(cert)); +} + +} // namespace fides +} // namespace resdb diff --git a/platform/consensus/ordering/fides/algorithm/fides.h b/platform/consensus/ordering/fides/algorithm/fides.h new file mode 100644 index 000000000..c9265084e --- /dev/null +++ b/platform/consensus/ordering/fides/algorithm/fides.h @@ -0,0 +1,95 @@ +#pragma once + +#include +#include +#include +#include + +#include "common/crypto/signature_verifier.h" +#include "platform/statistic/stats.h" +#include "platform/common/queue/lock_free_queue.h" +#include "platform/consensus/ordering/common/algorithm/protocol_base.h" +#include "platform/consensus/ordering/fides/proto/proposal.pb.h" +#include "platform/consensus/ordering/fides/algorithm/proposal_manager.h" +#include "enclave/sgx_cpp_u.h" +#include "platform/config/resdb_config.h" +/* // For transaction decryption +// #include "platform/proto/resdb.pb.h" +// #include "platform/proto/resdb.pb.h" +// #include "proto/kv/kv.pb.h" +*/ + +namespace resdb { +namespace fides { + +class Fides : public common::ProtocolBase { + public: + Fides(int id, int f, int total_num, SignatureVerifier* verifier, + const ResDBConfig& config, oe_enclave_t* enclave); + ~Fides(); + + bool ReceiveTransaction(std::unique_ptr txn); + bool ReceiveBlock(std::unique_ptr proposal); + void ReceiveBlockACK(std::unique_ptr metadata); + void ReceiveBlockCert(std::unique_ptr cert); + + + private: + void CommitProposal(int round, int proposer); + void CommitRound(int round); + void AsyncCommit(); + void AsyncSend(); + void AsyncExecute(); + + bool VerifyCert(const Certificate& cert); + bool VerifyCounter(int round, const CounterInfo& counter); + + bool CheckBlock(const Proposal& p); + void CheckFutureBlock(int round); + void CheckFutureCert(const Proposal& proposal); + void CheckFutureCert(int round, const std::string& hash, int proposer); + bool CheckCert(const Certificate& cert); + bool SendBlockAck(std::unique_ptr proposal); + + void AsyncProcessCert(); + + int GetLeader(int r); + + private: + LockFreeQueue execute_queue_, pending_block_; + LockFreeQueue commit_queue_; + LockFreeQueue txns_; + + std::unique_ptr proposal_manager_; + SignatureVerifier* verifier_; + oe_enclave_t* enclave_; + oe_result_t result; + + std::thread send_thread_; + std::thread commit_thread_, execute_thread_; + std::mutex txn_mutex_, mutex_; + int limit_count_; + std::map>> received_num_; + std::condition_variable vote_cv_; + int start_ = 0; + int batch_size_ = 0; + int execute_id_ = 1; + std::atomic queue_size_; + + Stats* global_stats_; + + std::thread cert_thread_; + LockFreeQueue cert_queue_; + std::mutex future_block_mutex_, future_cert_mutex_, check_block_mutex_; + std::map>> future_block_; + std::map>> future_cert_; + int64_t last_commit_time_ = 0; + + std::mutex leader_list_mutex_; + std::unordered_map leader_list_; + + ResDBConfig config_; +}; + +} // namespace fides +} // namespace resdb diff --git a/platform/consensus/ordering/fides/algorithm/proposal_manager.cpp b/platform/consensus/ordering/fides/algorithm/proposal_manager.cpp new file mode 100644 index 000000000..59963305f --- /dev/null +++ b/platform/consensus/ordering/fides/algorithm/proposal_manager.cpp @@ -0,0 +1,310 @@ +#include "platform/consensus/ordering/fides/algorithm/proposal_manager.h" + +#include + +#include "common/crypto/signature_verifier.h" +#include "common/utils/utils.h" + +namespace resdb { +namespace fides { + +ProposalManager::ProposalManager(int32_t id, int limit_count, oe_enclave_t* enclave) + : id_(id), limit_count_(limit_count), enclave_(enclave) { + round_ = 0; +} + +bool ProposalManager::VerifyHash(const Proposal &proposal){ + std::string data; + for (const auto& txn : proposal.transactions()) { + std::string tmp; + txn.SerializeToString(&tmp); + data += tmp; + } + + std::string header_data; + proposal.header().SerializeToString(&header_data); + data += header_data; + + std::string hash = SignatureVerifier::CalculateHash(data); + return hash == proposal.hash(); +} + +// TODO: 4.Add counter value into block +std::unique_ptr ProposalManager::GenerateProposal( + const std::vector>& txns) { + std::unique_ptr proposal = std::make_unique(); + std::string data; + { + std::unique_lock lk(txn_mutex_); + for (const auto& txn : txns) { + *proposal->add_transactions() = *txn; + std::string tmp; + txn->SerializeToString(&tmp); + data += tmp; + } + proposal->mutable_header()->set_proposer_id(id_); + proposal->mutable_header()->set_create_time(GetCurrentTime()); + proposal->mutable_header()->set_round(round_); + proposal->set_sender(id_); + + GetMetaData(proposal.get()); + } + + std::string header_data; + proposal->header().SerializeToString(&header_data); + data += header_data; + + std::string hash = SignatureVerifier::CalculateHash(data); + proposal->set_hash(hash); + + // Send counter value and attestation to enclave + size_t previous_cert_size = proposal->header().strong_cert().cert().size(); + unsigned char** attestation_array = new unsigned char*[previous_cert_size]; + size_t* attestation_size_array = new size_t[previous_cert_size]; + uint32_t* counter_value_array = new uint32_t[previous_cert_size]; + int i = 0; + + std::string serialized_data; + for(auto& link : proposal->header().strong_cert().cert()) { + // LOG(ERROR)<<"attestation is: "< counter = std::make_unique(); + CounterInfo* counter = proposal->mutable_header()->mutable_counter(); + counter->set_value(counter_value); + counter->set_attestation("Fake Attestation"); + // proposal->set_allocated_counter(counter.get()); + + // LOG(ERROR)<<"round: "< proposal) { + std::unique_lock lk(local_mutex_); + local_block_[proposal->hash()] = std::move(proposal); +} + +const Proposal* ProposalManager::GetLocalBlock(const std::string& hash) { + std::unique_lock lk(local_mutex_); + auto bit = local_block_.find(hash); + if (bit == local_block_.end()) { + LOG(ERROR) << " block not exist:" << hash.size(); + return nullptr; + } + return bit->second.get(); +} + +std::unique_ptr ProposalManager::FetchLocalBlock( + const std::string& hash) { + std::unique_lock lk(local_mutex_); + auto bit = local_block_.find(hash); + if (bit == local_block_.end()) { + //LOG(ERROR) << " block not exist:" << hash.size(); + return nullptr; + } + auto tmp = std::move(bit->second); + local_block_.erase(bit); + return tmp; +} + +void ProposalManager::AddBlock(std::unique_ptr proposal) { + std::unique_lock lk(txn_mutex_); + //LOG(ERROR) << "add block hash :" << proposal->hash().size() + // << " round:" << proposal->header().round() + // << " proposer:" << proposal->header().proposer_id(); + block_[proposal->hash()] = std::move(proposal); +} + +bool ProposalManager::CheckBlock(const std::string& hash){ + std::unique_lock lk(txn_mutex_); + //LOG(ERROR)<<"add block hash :"<hash().size()<<" round:"<header().round()<<" proposer:"<header().proposer_id(); + return block_.find(hash) != block_.end(); +} + +int ProposalManager::GetReferenceNum(const Proposal& req) { + int round = req.header().round(); + int round_1 = round + 1; + int proposer = req.header().proposer_id(); + std::unique_lock lk(txn_mutex_); + // return reference_[std::make_pair(round, proposer)]; + std::unordered_set reference_proposer; + for (auto& proposer_1 : reference_[std::make_pair(round, proposer)]) { + for (auto& proposer_2 : reference_[std::make_pair(round_1, proposer_1)]) { + if (reference_proposer.count(proposer_2) == 0) + reference_proposer.insert(proposer_2); + } + } + return reference_proposer.size(); +} + +std::unique_ptr ProposalManager::FetchRequest(int round, int sender) { + std::unique_lock lk(txn_mutex_); + auto it = cert_list_[round].find(sender); + if (it == cert_list_[round].end()) { + // LOG(ERROR)<<" cert from sender:"<second->hash(); + auto bit = block_.find(hash); + if (bit == block_.end()) { + LOG(ERROR) << " block from sender:" << sender << " round:" << round + << " not exist"; + assert(1 == 0); + return nullptr; + } + auto tmp = std::move(bit->second); + //cert_list_[round].erase(sender); + //LOG(ERROR)<<" featch sender done, round:"< lk(txn_mutex_); + auto it = cert_list_[round].find(sender); + if (it == cert_list_[round].end()) { + //LOG(ERROR) << " cert from sender:" << sender << " round:" << round + // << " not exist"; + return nullptr; + } + std::string hash = it->second->hash(); + auto bit = block_.find(hash); + if (bit == block_.end()) { + LOG(ERROR) << " block from sender:" << sender << " round:" << round + << " not exist"; + return nullptr; + } + return bit->second.get(); +} + + +// TODO: 6.Remove Cert Check counter value instead. +void ProposalManager::AddCert(std::unique_ptr cert) { + int proposer = cert->proposer(); + int round = cert->round(); + std::string hash = cert->hash(); + + // LOG(ERROR)<<"add cert sender:"< lk(txn_mutex_); + + // LOG(ERROR)<<"strong cert size:"<strong_cert().cert_size(); + std::unordered_set refered_proposer; + for (auto& link : cert->strong_cert().cert()) { + int link_round = link.round(); + int link_proposer = link.proposer(); + reference_[std::make_pair(link_round, link_proposer)].push_back(cert->proposer()); + } + + cert->mutable_strong_cert()->Clear(); + cert->mutable_metadata()->Clear(); + + auto tmp = std::make_unique(*cert); + cert_list_[round][proposer] = std::move(cert); + latest_cert_from_sender_[proposer] = std::move(tmp); +} + +bool ProposalManager::CheckCert(int round, int sender) { + std::unique_lock lk(txn_mutex_); + return cert_list_[round].find(sender) != cert_list_[round].end(); +} + +void ProposalManager::GetMetaData(Proposal* proposal) { + if (round_ == 0) { + return; + } + assert(cert_list_[round_ - 1].size() >= limit_count_); + assert(cert_list_[round_ - 1].find(id_) != cert_list_[round_ - 1].end()); + + //LOG(ERROR)<<"get metadata:"<<" proposal round:"<header().round(); + std::set meta_ids; + for (const auto& preview_cert : cert_list_[round_ - 1]) { + *proposal->mutable_header()->mutable_strong_cert()->add_cert() = + *preview_cert.second; + meta_ids.insert(preview_cert.first); + //LOG(ERROR)<<"add strong round:"<round() + //<<" id:"<proposer()<<" first:"<header().round(); + if (meta_ids.size() == limit_count_) { + break; + } + } + //LOG(ERROR)<<"strong link:"<header().strong_cert().cert_size()<<" round:"<header().round(); + + for (const auto& meta : latest_cert_from_sender_) { + // LOG(ERROR)<<"check:"<header().round(); + if (meta_ids.find(meta.first) != meta_ids.end()) { + continue; + } + if (meta.second->round() >= round_) { + for (int j = round_-1; j >= 0; --j) { + if (cert_list_[j].find(meta.first) != cert_list_[j].end()) { + //LOG(ERROR) << " add weak cert from his:" << j + // << " proposer:" << meta.first<< " cert round:"<round()<< " proposal round:"<header().round(); + *proposal->mutable_header()->mutable_weak_cert()->add_cert() = + *cert_list_[j][meta.first]; + break; + } + } + } else { + assert(meta.second->round() <= round_); + //LOG(ERROR)<<"add weak cert:"<round()<<" proposer:"<proposer()<<" proposal round:"<header().round(); + *proposal->mutable_header()->mutable_weak_cert()->add_cert() = + *meta.second; + } + } + //LOG(ERROR)<<"weak link:"<header().weak_cert().cert_size()<<" round:"<header().round(); +} + +bool ProposalManager::Ready() { + std::unique_lock lk(txn_mutex_); + if (round_ == 0) { + return true; + } + if (cert_list_[round_ - 1].size() < limit_count_) { + return false; + } + if (cert_list_[round_ - 1].find(id_) == cert_list_[round_ - 1].end()) { + return false; + } + return true; +} + +std::vector ProposalManager::GetCounterFromRound(int round) { + std::vector counters; + for (const auto& preview_cert : cert_list_[round]) { + counters.push_back(preview_cert.second->counter()); + if (counters.size() == limit_count_) { + break; + } + } + return counters; +} + +} // namespace fides +} // namespace resdb diff --git a/platform/consensus/ordering/fides/algorithm/proposal_manager.h b/platform/consensus/ordering/fides/algorithm/proposal_manager.h new file mode 100644 index 000000000..2d61661ec --- /dev/null +++ b/platform/consensus/ordering/fides/algorithm/proposal_manager.h @@ -0,0 +1,60 @@ +#pragma once + +#include "platform/consensus/ordering/fides/proto/proposal.pb.h" +#include "enclave/sgx_cpp_u.h" + +namespace resdb { +namespace fides { + +class ProposalManager { + public: + ProposalManager(int32_t id, int limit_count, oe_enclave_t* enclave); + + std::unique_ptr GenerateProposal( + const std::vector>& txns); + + int CurrentRound(); + void AddLocalBlock(std::unique_ptr proposal); + const Proposal* GetLocalBlock(const std::string& hash); + std::unique_ptr FetchLocalBlock(const std::string& hash); + + void AddBlock(std::unique_ptr proposal); + void AddCert(std::unique_ptr cert); + bool Ready(); + + const Proposal* GetRequest(int round, int sender); + std::unique_ptr FetchRequest(int round, int sender); + int GetReferenceNum(const Proposal& req); + + bool VerifyHash(const Proposal &proposal); + + bool CheckCert(int round, int sender); + bool CheckBlock(const std::string& hash); + + void SetCommittedRound(int r); + + std::vector GetCounterFromRound(int round); + + protected: + void GetMetaData(Proposal* proposal); + + private: + int32_t id_; + int round_; + int limit_count_; + std::map> block_, local_block_; + + std::map>> cert_list_; + std::map> latest_cert_from_sender_; + + std::mutex txn_mutex_, local_mutex_; + std::map, std::vector> reference_; + + std::atomic committed_round_ = 0; + + oe_enclave_t* enclave_; + oe_result_t result; +}; + +} // namespace fides +} // namespace resdb diff --git a/platform/consensus/ordering/fides/algorithm/transaction_collector.cpp b/platform/consensus/ordering/fides/algorithm/transaction_collector.cpp new file mode 100644 index 000000000..19c000377 --- /dev/null +++ b/platform/consensus/ordering/fides/algorithm/transaction_collector.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "platform/consensus/ordering/rcc/protocol/transaction_collector.h" + +#include + +namespace resdb { + +TransactionStatue TransactionCollector::GetStatus() const { return status_; } + +// TODO: 2.Encrypt the request from the client +int TransactionCollector::AddRequest( + std::unique_ptr request, int sender_id, int type, + std::function* status)> + call_back) { + if (status_.load() == EXECUTED) { + return -2; + } + + if (request) { + request_ = std::move(request); + call_back(*request, 1, &status_); + } else { + senders_[type].insert(sender_id); + if (request_) { + call_back(*request_, senders_[type].size(), &status_); + } + } + return 0; +} + +} // namespace resdb diff --git a/chain/storage/res_leveldb.h b/platform/consensus/ordering/fides/algorithm/transaction_collector.h similarity index 55% rename from chain/storage/res_leveldb.h rename to platform/consensus/ordering/fides/algorithm/transaction_collector.h index f2c526319..b38a41f62 100644 --- a/chain/storage/res_leveldb.h +++ b/platform/consensus/ordering/fides/algorithm/transaction_collector.h @@ -25,41 +25,47 @@ #pragma once -#include -#include -#include +#include -#include "chain/storage/storage.h" -#include "leveldb/db.h" -#include "leveldb/write_batch.h" -#include "platform/proto/replica_info.pb.h" +#include "platform/statistic/stats.h" namespace resdb { -std::unique_ptr NewResLevelDB(const char* cert_file, - resdb::ResConfigData config_data); +enum TransactionStatue { + None = 0, + Prepare = -999, + READY_PREPARE = 1, + READY_COMMIT = 2, + READY_EXECUTE = 3, + EXECUTED = 4, +}; -class ResLevelDB : public Storage { +class TransactionCollector { public: - ResLevelDB(const char* cert_file, std::optional config_data); + TransactionCollector(int64_t seq) + : seq_(seq), status_(TransactionStatue::None) {} - virtual ~ResLevelDB(); - int SetValue(const std::string& key, const std::string& value) override; - std::string GetValue(const std::string& key) override; - std::string GetAllValues(void) override; - std::string GetRange(const std::string& min_key, - const std::string& max_key) override; + ~TransactionCollector() = default; - bool Flush() override; + int AddRequest( + std::unique_ptr request, int sender_id, + int type, + std::function* status)> + call_back); - private: - void CreateDB(const std::string& path); + TransactionStatue GetStatus() const; + int64_t GetSeq() { return seq_; } + + std::unique_ptr GetData() { + return std::move(request_); + } private: - std::unique_ptr db_ = nullptr; - ::leveldb::WriteBatch batch_; - unsigned int write_buffer_size_ = 64 << 20; - unsigned int write_batch_size_ = 1; + int64_t seq_; + std::unique_ptr request_; + std::atomic status_ = TransactionStatue::None; + std::set senders_[10]; }; } // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/common/BUILD b/platform/consensus/ordering/fides/executor/common/BUILD new file mode 100644 index 000000000..7fecf8700 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/common/BUILD @@ -0,0 +1,19 @@ +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "utils", + hdrs = ["utils.h"], + deps = [ + "//third_party:evm_lib", + ], +) + +cc_library( + name = "contract_execute_info", + hdrs = ["contract_execute_info.h"], + deps = [ + ":utils", + "//service/contract/proto:func_params_cc_proto", + ], +) + diff --git a/platform/consensus/ordering/fides/executor/common/contract_execute_info.h b/platform/consensus/ordering/fides/executor/common/contract_execute_info.h new file mode 100644 index 000000000..f7de8b48e --- /dev/null +++ b/platform/consensus/ordering/fides/executor/common/contract_execute_info.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "service/contract/proto/func_params.pb.h" + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "eEVM/address.h" + +#include "service/contract/executor/common/utils.h" + +namespace resdb { +namespace contract { + +struct ContractExecuteInfo { + eevm::Address caller_address; + eevm::Address contract_address; + std::string func_addr; + Params func_params; + int64_t commit_id; + uint64_t user_id; + bool is_only; + ContractExecuteInfo(){} + ContractExecuteInfo( + eevm::Address caller_address, + eevm::Address contract_address, + std::string func_addr, + Params func_params, + int64_t commit_id): caller_address(caller_address), contract_address(contract_address), func_addr(func_addr), func_params(func_params), commit_id(commit_id), is_only(false){} +}; + +struct ExecuteResp { + int ret; + absl::Status state; + int64_t commit_id; + Address contract_address; + //ConcurrencyController :: ModifyMap rws; + std::string result; + int retry_time = 0; + uint64_t user_id = 0; + double runtime = 0; + double delay = 0; +}; + + +} // namespace contract +} // namespace resdb diff --git a/chain/storage/txn_memory_db.h b/platform/consensus/ordering/fides/executor/common/utils.h similarity index 76% rename from chain/storage/txn_memory_db.h rename to platform/consensus/ordering/fides/executor/common/utils.h index de69d70cb..2d243d66f 100644 --- a/chain/storage/txn_memory_db.h +++ b/platform/consensus/ordering/fides/executor/common/utils.h @@ -25,24 +25,12 @@ #pragma once -#include -#include - -#include "platform/proto/resdb.pb.h" +#include "eEVM/address.h" namespace resdb { +namespace contract { -class TxnMemoryDB { - public: - TxnMemoryDB(); - Request* Get(uint64_t seq); - void Put(std::unique_ptr request); - uint64_t GetMaxSeq(); - - private: - std::mutex mutex_; - std::unordered_map > data_; - std::atomic max_seq_; -}; +typedef eevm::Address Address; +} } // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/common/x_verifier.cpp b/platform/consensus/ordering/fides/executor/common/x_verifier.cpp new file mode 100644 index 000000000..b859690ca --- /dev/null +++ b/platform/consensus/ordering/fides/executor/common/x_verifier.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/x_verifier.h" + +#include + +#include "service/contract/executor/manager/local_state.h" +#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { + + +XVerifier:: XVerifier( + DataStorage * storage, + GlobalState * global_state, int worker_num):storage_(storage), gs_(global_state),worker_num_(worker_num) { + + controller_ = std::make_unique(storage); + is_stop_ = false; + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request = request_queue_.Pop(); + if (request == nullptr) { + continue; + } + + LocalState local_state(controller_.get()); + local_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &local_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time++; + } + local_state.Flesh(request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->commit_id); + } + else { + resp->ret = -1; + } + resp_queue_.Push(std::move(resp)); + } + })); + } +} + +XVerifier::~XVerifier(){ + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + + +bool XVerifier::VerifyContract( + const std::vector& request_list, + const std::vector& rws_list) { + std::vector d; + std::map > g; + std::map id; + + for(int i = 0; i < rws_list.size();++i){ + d.push_back(0); + for(auto it : rws_list[i]){ + const Address& address = it.first; + //LOG(ERROR)<<"i ="< q; + for(int i = 0; i < request_list.size();++i){ + if(d[i]==0){ + auto context = std::make_unique(request_list[i]); + context->GetContractExecuteInfo()->commit_id = i; + request_queue_.Push(std::move(context)); + //LOG(ERROR)<<"add:"<0){ + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + process_num--; + int resp_commit_id = resp->commit_id; + bool ret = controller_->Commit(resp_commit_id); + if(!ret){ + return false; + } + //LOG(ERROR)<<"verify:"<GetChangeList(resp_commit_id); + if(!RWSEqual(*rws, rws_list[resp_commit_id])){ + LOG(ERROR)<<"rws not equal"; + return false; + } + for(int n_id : g[resp_commit_id]){ + //LOG(ERROR)<<"next id:"<(request_list[n_id]); + context->GetContractExecuteInfo()->commit_id = n_id; + request_queue_.Push(std::move(context)); + //LOG(ERROR)<<"add next:"<first != it2->first){ + LOG(ERROR)<<"address not equal:"<first<<" "<first; + return false; + } + if(it1->second.size() != it2->second.size()){ + LOG(ERROR)<<"item size not equal:"<second.size()<<" "<second.size(); + return false; + } + for(int i = 0; i < it1->second.size(); i++){ + if(it1->second[i] != it2->second[i]){ + LOG(ERROR)<<"data not equal"; + return false; + } + } + } + return true; +} + + +} // namespace contract +} // namespace resdb + diff --git a/platform/consensus/ordering/fides/executor/common/x_verifier.h b/platform/consensus/ordering/fides/executor/common/x_verifier.h new file mode 100644 index 000000000..d93482af2 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/common/x_verifier.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/v_controller.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/committer_context.h" +#include "service/contract/executor/manager/contract_verifier.h" +#include "service/contract/executor/manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { + +class XVerifier : public ContractVerifier { + public: + XVerifier( + DataStorage * storage, + GlobalState * global_state, int worker_num = 2); + + ~XVerifier(); + + bool VerifyContract( + const std::vector& request_list, + const std::vector& rws_list); + + bool RWSEqual(const ConcurrencyController :: ModifyMap&a, const ConcurrencyController :: ModifyMap&b); + + private: + DataStorage * storage_; + GlobalState* gs_; + std::vector workers_; + std::unique_ptr controller_; + std::atomic is_stop_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + const int worker_num_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/eo_service/BUILD b/platform/consensus/ordering/fides/executor/eo_service/BUILD new file mode 100644 index 000000000..46776a78a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/eo_service/BUILD @@ -0,0 +1,26 @@ +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "contract_transaction_manager", + srcs = ["contract_transaction_manager.cpp"], + hdrs = ["contract_transaction_manager.h"], + deps = [ + "//platform/config:resdb_config_utils", + "//service/contract/executor/manager:address_manager", + "//service/contract/executor/manager:contract_manager", + "//service/contract/proto:rpc_cc_proto", + "//service/utils:server_factory", + ], +) + +cc_test( + name = "contract_transaction_manager_test", + srcs = ["contract_transaction_manager_test.cpp"], + data = [ + "//service/contract/executor/service/test_data:contract.json", + ], + deps = [ + ":contract_transaction_manager", + "//common/test:test_main", + ], +) diff --git a/platform/consensus/ordering/fides/executor/eo_service/contract_transaction_manager.cpp b/platform/consensus/ordering/fides/executor/eo_service/contract_transaction_manager.cpp new file mode 100644 index 000000000..9010b69f3 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/eo_service/contract_transaction_manager.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/service/contract_transaction_manager.h" + +#include + +namespace resdb { +namespace contract { + +ContractTransactionManager::ContractTransactionManager(void) + : contract_manager_(std::make_unique(std::make_unique())), + address_manager_(std::make_unique()) {} + +std::unique_ptr ContractTransactionManager::ExecuteData( + const std::string& client_request) { + Request request; + Response response; + + if (!request.ParseFromString(client_request)) { + LOG(ERROR) << "parse data fail"; + return nullptr; + } + + int ret = 0; + if (request.cmd() == Request::CREATE_ACCOUNT) { + absl::StatusOr account_or = CreateAccount(); + if (account_or.ok()) { + response.mutable_account()->Swap(&(*account_or)); + } else { + ret = -1; + } + } else if (request.cmd() == Request::DEPLOY) { + absl::StatusOr contract_or = Deploy(request); + if (contract_or.ok()) { + response.mutable_contract()->Swap(&(*contract_or)); + } else { + ret = -1; + } + } else if (request.cmd() == Request::EXECUTE) { + auto res_or = Execute(request); + if (res_or.ok()) { + response.set_res(*res_or); + } else { + ret = -1; + } + } + + response.set_ret(ret); + + std::unique_ptr resp_str = std::make_unique(); + if (!response.SerializeToString(resp_str.get())) { + return nullptr; + } + + return resp_str; +} + +absl::StatusOr ContractTransactionManager::CreateAccount() { + std::string address = + AddressManager::AddressToHex(address_manager_->CreateRandomAddress()); + Account account; + account.set_address(address); + return account; +} + +absl::StatusOr ContractTransactionManager::Deploy( + const Request& request) { + Address caller_address = + AddressManager::HexToAddress(request.caller_address()); + if (!address_manager_->Exist(caller_address)) { + LOG(ERROR) << "caller doesn't have an account"; + return absl::InvalidArgumentError("Account not exist."); + } + + Address contract_address = + contract_manager_->DeployContract(caller_address, request.deploy_info()); + + if (contract_address > 0) { + Contract contract; + contract.set_owner_address(request.caller_address()); + contract.set_contract_address( + AddressManager::AddressToHex(contract_address)); + contract.set_contract_name(request.deploy_info().contract_name()); + return contract; + } + return absl::InternalError("Deploy Contract fail."); +} + +absl::StatusOr ContractTransactionManager::Execute( + const Request& request) { + Address caller_address = + AddressManager::HexToAddress(request.caller_address()); + if (!address_manager_->Exist(caller_address)) { + LOG(ERROR) << "caller doesn't have an account"; + return absl::InvalidArgumentError("Account not exist."); + } + + return contract_manager_->ExecContract( + caller_address, AddressManager::HexToAddress(request.contract_address()), + request.func_params()); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/eo_service/contract_transaction_manager.h b/platform/consensus/ordering/fides/executor/eo_service/contract_transaction_manager.h new file mode 100644 index 000000000..33638c2f4 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/eo_service/contract_transaction_manager.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "platform/config/resdb_config_utils.h" +#include "platform/consensus/execution/transaction_manager.h" +#include "service/contract/executor/manager/address_manager.h" +#include "service/contract/executor/manager/contract_manager.h" +#include "service/contract/proto/func_params.pb.h" +#include "service/contract/proto/rpc.pb.h" + +namespace resdb { +namespace contract { + +class ContractTransactionManager : public TransactionManager { + public: + ContractTransactionManager(void); + virtual ~ContractTransactionManager() = default; + + std::unique_ptr ExecuteData(const std::string& request) override; + + private: + absl::StatusOr CreateAccount(); + absl::StatusOr Deploy(const Request& request); + absl::StatusOr Execute(const Request& request); + + private: + std::unique_ptr contract_manager_; + std::unique_ptr address_manager_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/eo_service/contract_transaction_manager_test.cpp b/platform/consensus/ordering/fides/executor/eo_service/contract_transaction_manager_test.cpp new file mode 100644 index 000000000..e0d59e186 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/eo_service/contract_transaction_manager_test.cpp @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/service/contract_transaction_manager.h" + +#include +#include + +#include + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/service/"; + +std::string ToString(const Request& request) { + std::string ret; + request.SerializeToString(&ret); + return ret; +} + +class ContractTransactionManagerTest : public Test { + public: + ContractTransactionManagerTest() { + std::string contract_path = test_dir + "test_data/contract.json"; + + std::ifstream contract_fstream(contract_path); + if (!contract_fstream) { + throw std::runtime_error(fmt::format( + "Unable to open contract definition file {}", contract_path)); + } + + nlohmann::json definition = nlohmann::json::parse(contract_fstream); + contracts_json_ = definition["contracts"]; + } + + Account CreateAccount() { + Request request; + Response response; + + request.set_cmd(Request::CREATE_ACCOUNT); + std::unique_ptr ret = executor_.ExecuteData(ToString(request)); + EXPECT_TRUE(ret != nullptr); + response.ParseFromString(*ret); + return response.account(); + } + + absl::StatusOr Deploy(const Account& account, + DeployInfo deploy_info) { + Request request; + Response response; + + request.set_caller_address(account.address()); + *request.mutable_deploy_info() = deploy_info; + request.set_cmd(Request::DEPLOY); + + std::unique_ptr ret = executor_.ExecuteData(ToString(request)); + EXPECT_TRUE(ret != nullptr); + + response.ParseFromString(*ret); + if (response.ret() == 0) { + return response.contract(); + } else { + return absl::InternalError("DeployFail."); + } + } + + absl::StatusOr Execute(const std::string& caller_address, + const std::string& contract_address, + const Params& params) { + Request request; + Response response; + + request.set_caller_address(caller_address); + request.set_contract_address(contract_address); + request.set_cmd(Request::EXECUTE); + *request.mutable_func_params() = params; + + std::unique_ptr ret = executor_.ExecuteData(ToString(request)); + EXPECT_TRUE(ret != nullptr); + + response.ParseFromString(*ret); + + if (response.ret() == 0) { + return eevm::to_uint256(response.res()); + } else { + return absl::InternalError("DeployFail."); + } + } + + protected: + nlohmann::json contracts_json_; + ContractTransactionManager executor_; +}; + +TEST_F(ContractTransactionManagerTest, ExecContract) { + // create an account. + Account account = CreateAccount(); + EXPECT_FALSE(account.address().empty()); + + std::string contract_name = "ERC20.sol:ERC20Token"; + std::string contract_code = contracts_json_[contract_name]["bin"]; + nlohmann::json func_hashes = contracts_json_[contract_name]["hashes"]; + + // deploy + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_code); + deploy_info.set_contract_name(contract_name); + + for (auto& func : func_hashes.items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + deploy_info.add_init_param("1000"); + + absl::StatusOr contract_or = Deploy(account, deploy_info); + EXPECT_TRUE(contract_or.ok()); + Contract contract = *contract_or; + + // query owner should return 1000 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(account.address()); + + auto result = + Execute(account.address(), contract.contract_address(), func_params); + EXPECT_EQ(*result, 0x3e8); + } + + Account transfer_receiver = CreateAccount(); + EXPECT_FALSE(account.address().empty()); + // receiver 0 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(transfer_receiver.address()); + + auto result = + Execute(account.address(), contract.contract_address(), func_params); + EXPECT_EQ(*result, 0); + } + + // transfer 400 to receiver + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(transfer_receiver.address()); + func_params.add_param("400"); + + auto result = + Execute(account.address(), contract.contract_address(), func_params); + EXPECT_EQ(*result, 1); + } + + // query owner should return 600 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(account.address()); + + auto result = + Execute(account.address(), contract.contract_address(), func_params); + EXPECT_EQ(*result, 600); + } + + // receiver 400 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(transfer_receiver.address()); + + auto result = + Execute(account.address(), contract.contract_address(), func_params); + EXPECT_EQ(*result, 400); + } +} + +TEST_F(ContractTransactionManagerTest, DeployFail) { + // create an account. + Account account = CreateAccount(); + EXPECT_FALSE(account.address().empty()); + + std::string contract_name = "ERC20.sol:ERC20Token"; + std::string contract_code = contracts_json_[contract_name]["bin"]; + nlohmann::json func_hashes = contracts_json_[contract_name]["hashes"]; + + // deploy + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_code); + deploy_info.set_contract_name(contract_name); + + for (auto& func : func_hashes.items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + // deploy_info.add_init_param("1000"); + + absl::StatusOr contract_or = Deploy(account, deploy_info); + EXPECT_FALSE(contract_or.ok()); +} + +TEST_F(ContractTransactionManagerTest, NoFunc) { + // create an account. + Account account = CreateAccount(); + EXPECT_FALSE(account.address().empty()); + + std::string contract_name = "ERC20.sol:ERC20Token"; + std::string contract_code = contracts_json_[contract_name]["bin"]; + nlohmann::json func_hashes = contracts_json_[contract_name]["hashes"]; + + // deploy + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_code); + deploy_info.set_contract_name(contract_name); + + for (auto& func : func_hashes.items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + deploy_info.add_init_param("1000"); + + absl::StatusOr contract_or = Deploy(account, deploy_info); + EXPECT_TRUE(contract_or.ok()); + Contract contract = *contract_or; + + { + Params func_params; + func_params.set_func_name("balanceOf()"); + func_params.add_param(account.address()); + + auto result = + Execute(account.address(), contract.contract_address(), func_params); + EXPECT_FALSE(result.ok()); + } +} + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/eo_service/test_data/BUILD b/platform/consensus/ordering/fides/executor/eo_service/test_data/BUILD new file mode 100644 index 000000000..65e3dc3d9 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/eo_service/test_data/BUILD @@ -0,0 +1 @@ +exports_files(["contract.json"]) diff --git a/platform/consensus/ordering/fides/executor/eo_service/test_data/contract.json b/platform/consensus/ordering/fides/executor/eo_service/test_data/contract.json new file mode 100644 index 000000000..e9c0d972f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/eo_service/test_data/contract.json @@ -0,0 +1,19 @@ +{ + "contracts": + { + "ERC20.sol:ERC20Token": + { + "bin": "608060405234801561001057600080fd5b506040516104423803806104428339818101604052602081101561003357600080fd5b50516000818155338152600160205260409020556103ec806100566000396000f3fe608060405234801561001057600080fd5b506004361061007e577c01000000000000000000000000000000000000000000000000000000006000350463095ea7b3811461008357806318160ddd146100c357806323b872dd146100dd57806370a0823114610113578063a9059cbb14610139578063dd62ed3e14610165575b600080fd5b6100af6004803603604081101561009957600080fd5b50600160a060020a038135169060200135610193565b604080519115158252519081900360200190f35b6100cb6101fa565b60408051918252519081900360200190f35b6100af600480360360608110156100f357600080fd5b50600160a060020a03813581169160208101359091169060400135610200565b6100cb6004803603602081101561012957600080fd5b5035600160a060020a03166102e6565b6100af6004803603604081101561014f57600080fd5b50600160a060020a038135169060200135610301565b6100cb6004803603604081101561017b57600080fd5b50600160a060020a038135811691602001351661038c565b336000818152600260209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b60005490565b600160a060020a038316600090815260016020526040812054821180159061024b5750600160a060020a03841660009081526002602090815260408083203384529091529020548211155b156102db57600160a060020a038085166000818152600160209081526040808320805488900390559387168083528483208054880190559282526002815283822033808452908252918490208054879003905583518681529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35060016102df565b5060005b9392505050565b600160a060020a031660009081526001602052604090205490565b3360009081526001602052604081205482116103845733600081815260016020908152604080832080548790039055600160a060020a03871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35060016101f4565b5060006101f4565b600160a060020a0391821660009081526002602090815260408083209390941682529190915220549056fea265627a7a72315820e4ae92c4517e475d9f77ac0bfcd10463a09239f34734fc0ab4d7966450fb428464736f6c63430005100032", + "hashes": + { + "allowance(address,address)": "dd62ed3e", + "approve(address,uint256)": "095ea7b3", + "balanceOf(address)": "70a08231", + "totalSupply()": "18160ddd", + "transfer(address,uint256)": "a9059cbb", + "transferFrom(address,address,uint256)": "23b872dd" + } + } + }, + "version": "0.5.16+commit.9c3226ce.Linux.g++" +} diff --git a/platform/consensus/ordering/fides/executor/manager/BUILD b/platform/consensus/ordering/fides/executor/manager/BUILD new file mode 100644 index 000000000..2da517eb4 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/BUILD @@ -0,0 +1,632 @@ +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "address_manager", + srcs = ["address_manager.cpp"], + hdrs = ["address_manager.h"], + deps = [ + "//service/contract/executor/common:utils", + "//common:comm", + ], +) + +cc_test( + name = "address_manager_test", + srcs = ["address_manager_test.cpp"], + deps = [ + ":address_manager", + "//common/test:test_main", + ], +) + +cc_library( + name = "data_storage", + srcs = ["data_storage.cpp"], + hdrs = ["data_storage.h"], + deps = [ + "//service/contract/executor/common:utils", + "//common:comm", + ], +) + +cc_library( + name = "leveldb_storage", + srcs = ["leveldb_storage.cpp"], + hdrs = ["leveldb_storage.h"], + deps = [ + ":data_storage", + "//storage:res_leveldb", + "//common:comm", + ], +) + + + +cc_library( + name = "mock_data_storage", + hdrs = ["mock_data_storage.h"], + deps = [ + ":data_storage", + "//common/test:test" + ], +) + +cc_library( + name = "mock_d_storage", + hdrs = ["mock_d_storage.h"], + deps = [ + ":d_storage", + "//common/test:test" + ], +) + + +cc_library( + name = "d_storage", + srcs = ["d_storage.cpp"], + hdrs = ["d_storage.h"], + deps = [ + ":data_storage", + "//common:comm", + ], +) + +cc_library( + name = "leveldb_d_storage", + srcs = ["leveldb_d_storage.cpp"], + hdrs = ["leveldb_d_storage.h"], + deps = [ + ":data_storage", + "//storage:res_leveldb", + "//common:comm", + ], +) + + + +cc_library( + name = "leveldb", + srcs = ["leveldb.cpp"], + hdrs = ["leveldb.h"], + deps = [ + ":data_storage", + "//common:comm", + "//storage:res_leveldb" + ], +) + +cc_library( + name = "global_view", + srcs = ["global_view.cpp"], + hdrs = ["global_view.h"], + deps = [ + ":data_storage", + "//common:comm", + ], +) + +cc_library( + name = "local_view", + srcs = ["local_view.cpp"], + hdrs = ["local_view.h"], + deps = [ + ":concurrency_controller", + "//common:comm", + ], +) + +cc_test( + name = "local_view_test", + srcs = ["local_view_test.cpp"], + deps = [ + ":local_view", + ":two_phase_controller", + "//common/test:test_main", + ], +) + +cc_library( + name = "evm_state", + hdrs = ["evm_state.h"], + deps = [ + "//service/contract/executor/common:utils", + "//common:comm", + ], +) + +cc_library( + name = "global_state", + srcs = ["global_state.cpp"], + hdrs = ["global_state.h"], + deps = [ + ":evm_state", + "//service/contract/executor/common:utils", + ":global_view", + "//common:comm", + ], +) + +cc_library( + name = "local_state", + srcs = ["local_state.cpp"], + hdrs = ["local_state.h"], + deps = [ + ":evm_state", + "//service/contract/executor/common:utils", + ":local_view", + "//common:comm", + ], +) + +cc_library( + name = "concurrency_controller", + srcs = ["concurrency_controller.cpp"], + hdrs = ["concurrency_controller.h"], + deps = [ + ":data_storage", + ], +) + +cc_library( + name = "two_phase_ooo_controller", + srcs = ["two_phase_ooo_controller.cpp"], + hdrs = ["two_phase_ooo_controller.h"], + deps = [ + ":concurrency_controller", + "//common:comm", + ], +) + +cc_library( + name = "two_phase_ooo_committer", + srcs = ["two_phase_ooo_committer.cpp"], + hdrs = ["two_phase_ooo_committer.h"], + deps = [ + ":contract_committer", + ":two_phase_ooo_controller", + ":contract_executor", + ":local_state", + ":global_state", + "//common:comm", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + + +cc_library( + name = "two_phase_controller", + srcs = ["two_phase_controller.cpp"], + hdrs = ["two_phase_controller.h"], + deps = [ + ":concurrency_controller", + "//common:comm", + ], +) + +cc_test( + name = "two_phase_controller_test", + srcs = ["two_phase_controller_test.cpp"], + deps = [ + ":two_phase_controller", + "//common/test:test_main", + ], +) + +cc_library( + name = "ooo_controller", + srcs = ["ooo_controller.cpp"], + hdrs = ["ooo_controller.h"], + deps = [ + ":concurrency_controller", + "//common:comm", + ], +) + +cc_library( + name = "sequential_cc_controller", + srcs = ["sequential_cc_controller.cpp"], + hdrs = ["sequential_cc_controller.h"], + deps = [ + ":concurrency_controller", + "//platform/common/queue:lock_free_queue", + "//common:comm", + ], +) + +cc_test( + name = "sequential_cc_controller_test", + srcs = ["sequential_cc_controller_test.cpp"], + deps = [ + ":sequential_cc_controller", + "//common/test:test_main", + ], +) + +cc_library( + name = "streaming_dq_controller", + srcs = ["streaming_dq_controller.cpp"], + hdrs = ["streaming_dq_controller.h"], + deps = [ + ":concurrency_controller", + ":d_storage", + "//platform/common/queue:lock_free_queue", + "//common:comm", + ], +) + + +cc_library( + name = "test_controller", + srcs = ["test_controller.cpp"], + hdrs = ["test_controller.h"], + testonly = True, + deps = [ + ":concurrency_controller", + "//platform/common/queue:lock_free_queue", + "//common:comm", + ], +) + + +cc_library( + name = "contract_executor", + srcs = ["contract_executor.cpp"], + hdrs = ["contract_executor.h"], + deps = [ + ":evm_state", + ":concurrency_controller", + "//common:comm", + "//service/contract/proto:func_params_cc_proto", + "//service/contract/executor/common:contract_execute_info", + ], +) + +cc_library( + name = "committer_context", + srcs = ["committer_context.cpp"], + hdrs = ["committer_context.h"], + deps = [ + ":contract_committer", + ], +) + +cc_library( + name = "contract_committer", + hdrs = ["contract_committer.h"], + deps = [ + ":contract_executor", + "//service/contract/proto:func_params_cc_proto", + "//service/contract/executor/common:contract_execute_info", + ], +) + +cc_library( + name = "contract_verifier", + hdrs = ["contract_verifier.h"], + srcs = ["contract_verifier.cpp"], + deps = [ + ":contract_executor", + ":contract_committer", + ":committer_context", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "ooo_committer", + srcs = ["ooo_committer.cpp"], + hdrs = ["ooo_committer.h"], + deps = [ + ":contract_committer", + ":ooo_controller", + ":contract_executor", + ":local_state", + ":global_state", + "//common:comm", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "two_phase_committer", + srcs = ["two_phase_committer.cpp"], + hdrs = ["two_phase_committer.h"], + deps = [ + ":contract_committer", + ":two_phase_controller", + ":contract_executor", + ":local_state", + ":global_state", + "//common:comm", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_test( + name = "two_phase_committer_test", + srcs = ["two_phase_committer_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + ], + deps = [ + ":contract_deployer", + ":two_phase_committer", + ":address_manager", + "//common/test:test_main", + ], +) + + +cc_library( + name = "sequential_concurrency_committer", + srcs = ["sequential_concurrency_committer.cpp"], + hdrs = ["sequential_concurrency_committer.h"], + deps = [ + ":contract_committer", + ":contract_executor", + ":sequential_cc_controller", + ":local_state", + ":global_state", + ":committer_context", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "x_committer", + srcs = ["x_committer.cpp"], + hdrs = ["x_committer.h"], + deps = [ + ":contract_committer", + ":contract_executor", + ":x_controller", + ":streaming_dq_controller", + ":local_state", + ":global_state", + ":committer_context", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "x_controller", + srcs = ["x_controller.cpp"], + hdrs = ["x_controller.h"], + deps = [ + ":concurrency_controller", + "//platform/common/queue:lock_free_queue", + "//common:comm", + ], +) + +cc_library( + name = "v_controller", + srcs = ["v_controller.cpp"], + hdrs = ["v_controller.h"], + deps = [ + ":concurrency_controller", + "//platform/common/queue:lock_free_queue", + "//common:comm", + ], +) + + +cc_library( + name = "x_verifier", + srcs = ["x_verifier.cpp"], + hdrs = ["x_verifier.h"], + deps = [ + ":contract_verifier", + ":local_state", + ":global_state", + ":v_controller", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_test( + name = "x_committer_test", + srcs = ["x_committer_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + ], + deps = [ + ":contract_deployer", + ":x_committer", + ":address_manager", + ":mock_data_storage", + "//common/test:test_main", + ], +) + +cc_test( + name = "x_verifier_test", + srcs = ["x_verifier_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + "//service/contract/executor/manager/test_data:kv.json", + ], + deps = [ + ":contract_deployer", + ":x_verifier", + ":x_committer", + ":address_manager", + ":mock_data_storage", + "//common/test:test_main", + ], +) + +cc_library( + name = "streaming_single_committer", + srcs = ["streaming_single_committer.cpp"], + hdrs = ["streaming_single_committer.h"], + deps = [ + ":committer_context", + ":contract_committer", + ":contract_executor", + ":global_state", + "//common/utils:utils", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "streaming_dq_committer", + srcs = ["streaming_dq_committer.cpp"], + hdrs = ["streaming_dq_committer.h"], + deps = [ + ":committer_context", + ":contract_committer", + ":contract_executor", + ":streaming_dq_controller", + ":local_state", + ":global_state", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_test( + name = "streaming_dq_committer_test", + srcs = ["streaming_dq_committer_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + "//service/contract/executor/manager/test_data:kv.json", + ], + deps = [ + ":contract_deployer", + ":address_manager", + ":mock_d_storage", + ":streaming_dq_committer", + "//common/test:test_main", + ], +) + + +cc_test( + name = "sequential_concurrency_committer_test", + srcs = ["sequential_concurrency_committer_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + ], + deps = [ + ":contract_deployer", + ":address_manager", + ":mock_data_storage", + ":sequential_concurrency_committer", + "//common/test:test_main", + ], +) + +cc_library( + name = "streaming_controller", + srcs = ["streaming_controller.cpp"], + hdrs = ["streaming_controller.h"], + deps = [ + ":concurrency_controller", + "//platform/common/queue:lock_free_queue", + "//common:comm", + ], +) + +cc_library( + name = "streaming_committer", + srcs = ["streaming_committer.cpp"], + hdrs = ["streaming_committer.h"], + deps = [ + ":contract_committer", + ":contract_executor", + ":streaming_controller", + ":local_state", + ":global_state", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "test_committer", + hdrs = ["test_committer.h"], + srcs = ["test_committer.cpp"], + testonly = True, + deps = [ + ":test_controller", + ":contract_committer", + ":contract_executor", + ":global_state", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "contract_deployer", + srcs = ["contract_deployer.cpp"], + hdrs = ["contract_deployer.h"], + deps = [ + ":concurrency_controller", + ":contract_committer", + ":global_state", + ":address_manager", + ], +) + +cc_test( + name = "contract_deployer_test", + srcs = ["contract_deployer_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + ], + deps = [ + ":test_committer", + ":contract_deployer", + "//common/test:test_main", + ], +) + +cc_library( + name = "contract_manager", + srcs = ["contract_manager.cpp"], + hdrs = ["contract_manager.h"], + deps = [ + ":contract_deployer", + ":two_phase_committer", + ":sequential_concurrency_committer", + ":ooo_committer", + ":two_phase_ooo_committer", + ":x_committer", + ":x_verifier", + ":streaming_committer", + ":concurrency_controller", + ":streaming_single_committer", + ":streaming_dq_committer", + ":global_state", + ":address_manager", + "//service/contract/executor/common:utils", + "//common:comm", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_test( + name = "contract_manager_test", + srcs = ["contract_manager_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + ], + deps = [ + ":contract_manager", + "//common/test:test_main", + ], +) + diff --git a/platform/consensus/ordering/fides/executor/manager/address_manager.cpp b/platform/consensus/ordering/fides/executor/manager/address_manager.cpp new file mode 100644 index 000000000..f62fc53e8 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/address_manager.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/address_manager.h" + +#include + +#include "eEVM/util.h" + +namespace resdb { +namespace contract { + +Address AddressManager::CreateRandomAddress() { + std::vector raw(20); + std::generate(raw.begin(), raw.end(), []() { return rand(); }); + Address address = eevm::from_big_endian(raw.data(), raw.size()); + users_.insert(address); + return address; +} + +bool AddressManager::CreateAddress(const Address& address) { + if(users_.find(address) != users_.end()){ + return false; + } + users_.insert(address); + return true; +} + + +bool AddressManager::Exist(const Address& address) { + return users_.find(address) != users_.end(); +} + +Address AddressManager::CreateContractAddress(const Address& owner) { + return eevm::generate_address(owner, 0u); +} + +std::string AddressManager::AddressToHex(const Address& address) { + return eevm::to_hex_string(address); +} + +Address AddressManager::HexToAddress(const std::string& address) { + return eevm::to_uint256(address); +} + +uint256_t AddressManager::AddressToSHAKey(const Address& address) { + std::vectorcode; + code.resize(64u); + eevm::to_big_endian(address, code.data()); + //code[63]=1; + //LOG(ERROR)<<"code size:"<(code.size()), h); + //LOG(ERROR)<<"get h:"< + +#include "service/contract/executor/common/utils.h" + +namespace resdb { +namespace contract { + +class AddressManager { + public: + AddressManager() {} + + // Create an address holding a 20 byte value + Address CreateRandomAddress(); + bool CreateAddress(const Address& address); + bool Exist(const Address& address); + + static Address CreateContractAddress(const Address& owner); + + static std::string AddressToHex(const Address& address); + static Address HexToAddress(const std::string& address); + + static uint256_t AddressToSHAKey(const Address& address); + + private: + std::set
users_; +}; + +} // namespace contract +} // namespace resdb diff --git a/chain/storage/txn_memory_db_test.cpp b/platform/consensus/ordering/fides/executor/manager/address_manager_test.cpp similarity index 60% rename from chain/storage/txn_memory_db_test.cpp rename to platform/consensus/ordering/fides/executor/manager/address_manager_test.cpp index 1ff726dcd..cb7d7454c 100644 --- a/chain/storage/txn_memory_db_test.cpp +++ b/platform/consensus/ordering/fides/executor/manager/address_manager_test.cpp @@ -23,49 +23,36 @@ * */ -#include "database/txn_memory_db.h" +#include "service/contract/executor/manager/address_manager.h" -#include +#include #include -#include "common/test/test_macros.h" +#include "eEVM/util.h" namespace resdb { +namespace contract { namespace { -using ::resdb::testing::EqualsProto; -using ::testing::Pointee; - -TEST(TxnMemoryDBTest, GetEmptyValue) { - TxnMemoryDB db; - EXPECT_EQ(db.Get(1), nullptr); -} - -TEST(TxnMemoryDBTest, GetValue) { - Request request; - request.set_seq(1); - request.set_data("test"); - - TxnMemoryDB db; - db.Put(std::make_unique(request)); - EXPECT_THAT(db.Get(1), Pointee(EqualsProto(request))); +TEST(AddressManagerTest, CreateAddress) { + Address address = AddressManager().CreateRandomAddress(); + std::array raw; + eevm::to_big_endian(address, raw.data()); + Address m = eevm::from_big_endian(raw.data() + 12, raw.size() - 12); + EXPECT_EQ(m, address); } -TEST(TxnMemoryDBTest, GetSecondValue) { - Request request; - request.set_seq(1); - request.set_data("test"); - - TxnMemoryDB db; - db.Put(std::make_unique(request)); +TEST(AddressManagerTest, CreateContractAddress) { + Address address = AddressManager().CreateRandomAddress(); - request.set_seq(1); - request.set_data("test_1"); - db.Put(std::make_unique(request)); + Address contract_address = AddressManager::CreateContractAddress(address); - EXPECT_THAT(db.Get(1), Pointee(EqualsProto(request))); + std::array raw; + eevm::to_big_endian(contract_address, raw.data()); + Address m = eevm::from_big_endian(raw.data() + 12, raw.size() - 12); + EXPECT_EQ(m, contract_address); } } // namespace - +} // namespace contract } // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/committer_context.cpp b/platform/consensus/ordering/fides/executor/manager/committer_context.cpp new file mode 100644 index 000000000..7d124aaf8 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/committer_context.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/committer_context.h" + +#include "glog/logging.h" + +namespace resdb { +namespace contract { + +ExecutionContext::ExecutionContext(const ContractExecuteInfo & info ) { + info_ = std::make_unique(info); +} + +const ContractExecuteInfo * ExecutionContext::GetContractExecuteInfo() const { + return info_.get(); +} + +ContractExecuteInfo * ExecutionContext::GetContractExecuteInfo() { + return info_.get(); +} + +void ExecutionContext::SetResult(std::unique_ptr result) { + result_ = std::move(result); +} + +bool ExecutionContext::IsRedo() { + return is_redo_; +} + +void ExecutionContext::SetRedo(){ + is_redo_++; +} + +int ExecutionContext::RedoTime() { + return is_redo_; +} + + +std::unique_ptr ExecutionContext::FetchResult() { + return std::move(result_); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/committer_context.h b/platform/consensus/ordering/fides/executor/manager/committer_context.h new file mode 100644 index 000000000..2a693338e --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/committer_context.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "service/contract/executor/manager/contract_committer.h" + +namespace resdb { +namespace contract { + +class ExecutionContext { +public: + ExecutionContext(const ContractExecuteInfo & info ) ; + const ContractExecuteInfo * GetContractExecuteInfo() const; + ContractExecuteInfo * GetContractExecuteInfo(); + + void SetRedo(); + bool IsRedo(); + int RedoTime(); + + void SetResult(std::unique_ptr result); + std::unique_ptr FetchResult(); + + private: + int is_redo_ = 0; + std::unique_ptr result_; + std::unique_ptr info_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/concurrency_controller.cpp b/platform/consensus/ordering/fides/executor/manager/concurrency_controller.cpp new file mode 100644 index 000000000..db4aa9efe --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/concurrency_controller.cpp @@ -0,0 +1,17 @@ +#include "service/contract/executor/manager/concurrency_controller.h" + +#include + +namespace resdb { +namespace contract { + +ConcurrencyController::ConcurrencyController(DataStorage * storage) : storage_(storage){} + +const DataStorage * ConcurrencyController::GetStorage() const { + return storage_; +} + + + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/concurrency_controller.h b/platform/consensus/ordering/fides/executor/manager/concurrency_controller.h new file mode 100644 index 000000000..c0b84c247 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/concurrency_controller.h @@ -0,0 +1,48 @@ +#pragma once + +#include "service/contract/executor/manager/data_storage.h" + +#include +#include + +namespace resdb { +namespace contract { + +enum State{ + LOAD = 0, + STORE = 1, + REMOVE = 2, +}; + +struct Data{ + State state; + uint256_t data; + int64_t version; + uint256_t old_data; + Data(){} + Data(const State& state):state(state){} + Data(const State& state, const uint256_t& data, int64_t version = 0) + :state(state), data(data), version(version){} + Data(const State& state, const uint256_t& data, int64_t version, const uint256_t& old_data) + :state(state), data(data), version(version), old_data(old_data){} + bool operator != (const Data& d) const{ + return d.state != this->state || d.data != this->data || d.version != this->version; + } +}; + +class ConcurrencyController { + public: + ConcurrencyController(DataStorage * storage); + + typedef std::map> ModifyMap; + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_) = 0; + + const DataStorage * GetStorage() const; + + protected: + DataStorage * storage_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/contract_committer.h b/platform/consensus/ordering/fides/executor/manager/contract_committer.h new file mode 100644 index 000000000..221789664 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/contract_committer.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include + +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/common/contract_execute_info.h" +#include "service/contract/proto/func_params.pb.h" + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "eEVM/address.h" + +namespace resdb { +namespace contract { + +/* +struct ContractExecuteInfo { + eevm::Address caller_address; + eevm::Address contract_address; + std::string func_addr; + Params func_params; + int64_t commit_id; + uint64_t user_id; + ContractExecuteInfo(){} + ContractExecuteInfo( + eevm::Address caller_address, + eevm::Address contract_address, + std::string func_addr, + Params func_params, + int64_t commit_id): caller_address(caller_address), contract_address(contract_address), func_addr(func_addr), func_params(func_params), commit_id(commit_id){} +}; +*/ + +class ContractCommitter { + public: + ContractCommitter() = default; + virtual ~ContractCommitter() = default; + + virtual std::vector> ExecContract(std::vector& request) = 0; + + virtual void AsyncExecContract(std::vector& request){}; + + virtual absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) = 0; + + virtual void SetExecuteCallBack(std::function)> ){}; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/contract_deployer.cpp b/platform/consensus/ordering/fides/executor/manager/contract_deployer.cpp new file mode 100644 index 000000000..a866329a3 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/contract_deployer.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/contract_deployer.h" + +#include "service/contract/executor/manager/address_manager.h" + +#include +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { +namespace { + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } + +void AppendArgToInput(std::vector& code, const uint256_t& arg) { + const auto pre_size = code.size(); + code.resize(pre_size + 32u); + eevm::to_big_endian(arg, code.data() + pre_size); + // LOG(ERROR)<<"add arg:"<& code, const std::string& arg) { + AppendArgToInput(code, eevm::to_uint256(arg)); +} + +} + +ContractDeployer::ContractDeployer(ContractCommitter * committer, GlobalState * gs) + : committer_(committer), gs_(gs){} + +std::string ContractDeployer::GetFuncAddress(const Address& contract_address, + const std::string& func_name) { + return func_address_[contract_address][func_name]; +} + +void ContractDeployer::SetFuncAddress(const Address& contract_address, + const FuncInfo& func) { + func_address_[contract_address][func.func_name()] = func.hash(); +} + +Address ContractDeployer::DeployContract(const Address& owner_address, + const DeployInfo& deploy_info) { + const auto contract_address = + AddressManager::CreateContractAddress(owner_address); + + auto contract_constructor = eevm::to_bytes(deploy_info.contract_bin()); + for (const std::string& param : deploy_info.init_param()) { + AppendArgToInput(contract_constructor, param); + } + + try { + auto contract = gs_->create(contract_address, 0u, contract_constructor); + absl::StatusOr result = committer_->ExecContract( + owner_address, contract_address, + "", + {}, gs_); + + if(result.ok()){ + // set the initialized class context code. + contract.acc.set_code(eevm::to_bytes(*result)); + + for (const auto& info : deploy_info.func_info()) { + SetFuncAddress(contract_address, info); + } + //LOG(ERROR)<<"contract create:"<remove(contract_address); + return 0; + } + } catch (...) { + LOG(ERROR) << "Deploy throw expection"; + return 0; + } +} + + +bool ContractDeployer::DeployContract(const Address& owner_address, + const DeployInfo& deploy_info, const Address& contract_address) { + LOG(ERROR)<<"deploy address:"<create(contract_address, 0u, contract_constructor); + + LOG(ERROR)<<"create:"; + absl::StatusOr result = committer_->ExecContract( + owner_address, contract_address, + "", + {}, gs_); + + LOG(ERROR)<<"deploy result:"<remove(contract_address); + return false; + } + } catch (...) { + LOG(ERROR) << "Deploy throw expection"; + return false; + } +} + +Address ContractDeployer::DeployContract(const Address& owner_address, + const nlohmann::json& contract_json, const std::vector& init_params){ + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json["bin"]); + + for (auto& func : contract_json["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + for(const uint256_t& param : init_params){ + deploy_info.add_init_param(U256ToString(param)); + } + + return DeployContract(owner_address, deploy_info); +} + +bool ContractDeployer::DeployContract(const Address& owner_address, + const nlohmann::json& contract_json, const std::vector& init_params, const Address& contract_address){ + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json["bin"]); + + for (auto& func : contract_json["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + for(const uint256_t& param : init_params){ + deploy_info.add_init_param(U256ToString(param)); + } + + return DeployContract(owner_address, deploy_info, contract_address); +} + + +absl::StatusOr ContractDeployer::GetContract( + const Address& address) { + if (!gs_->Exists(address)) { + return absl::InvalidArgumentError("Contract not exist."); + } + + return gs_->get(address); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/contract_deployer.h b/platform/consensus/ordering/fides/executor/manager/contract_deployer.h new file mode 100644 index 000000000..0a74e7501 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/contract_deployer.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { + +class ContractDeployer { + public: + ContractDeployer(ContractCommitter * committer, GlobalState * gs); + + public: + Address DeployContract(const Address& owner_address, + const DeployInfo& deploy_info); + bool DeployContract(const Address& owner_address, + const DeployInfo& deploy_info, const Address& contract_address); + + Address DeployContract(const Address& owner_address, + const nlohmann::json& contract_json, const std::vector& init_params); + bool DeployContract(const Address& owner_address, + const nlohmann::json& contract_json, const std::vector& init_params, const Address& contract_address); + + absl::StatusOr GetContract(const Address& address); + std::string GetFuncAddress(const Address& contract_address, + const std::string& func_name); + + private: + void SetFuncAddress(const Address& contract_address, const FuncInfo& func); + + private: + ContractCommitter* committer_; + GlobalState* gs_; + std::map> func_address_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/contract_deployer_test.cpp b/platform/consensus/ordering/fides/executor/manager/contract_deployer_test.cpp new file mode 100644 index 000000000..41be4ae2c --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/contract_deployer_test.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/contract_deployer.h" + +#include +#include + +#include + +#include "service/contract/executor/manager/address_manager.h" +#include "service/contract/executor/manager/test_committer.h" + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } + +class ContractDeployerTest : public Test { + public: + ContractDeployerTest() : owner_address_(get_random_address()) { + + storage_ = std::make_unique(); + gs_ = std::make_unique(storage_.get()); + execotor_ = std::make_unique(storage_.get(), gs_.get()); + + + + LOG(ERROR)<<"owner:"< storage_; + std::unique_ptr gs_; + std::unique_ptrexecotor_; +}; + +TEST_F(ContractDeployerTest, NoContract) { + ContractDeployer deployer(execotor_.get(), gs_.get()); + auto account = deployer.GetContract(1234); + EXPECT_FALSE(account.ok()); +} + +TEST_F(ContractDeployerTest, DeployContract) { + ContractDeployer deployer(execotor_.get(), gs_.get()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + deployer.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = deployer.GetContract(contract_address); + EXPECT_TRUE(account.ok()); +} + +TEST_F(ContractDeployerTest, DeployContractFromJson) { + ContractDeployer deployer(execotor_.get(), gs_.get()); + + Address contract_address = + deployer.DeployContract(owner_address_, contract_json_, {1000}); + EXPECT_GT(contract_address, 0); + auto account = deployer.GetContract(contract_address); + EXPECT_TRUE(account.ok()); +} + + + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/contract_executor.cpp b/platform/consensus/ordering/fides/executor/manager/contract_executor.cpp new file mode 100644 index 000000000..2b8a4609e --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/contract_executor.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/contract_executor.h" + +//#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { + +void AppendArgToInput(std::vector& code, const uint256_t& arg) { + const auto pre_size = code.size(); + code.resize(pre_size + 32u); + eevm::to_big_endian(arg, code.data() + pre_size); +} + +void AppendArgToInput(std::vector& code, const std::string& arg) { + AppendArgToInput(code, eevm::to_uint256(arg)); +} + +absl::StatusOr ContractExecutor::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + + std::vector inputs; + if(!func_addr.empty()){ + inputs = eevm::to_bytes(func_addr); + } + for (const std::string& param : func_param.param()) { + AppendArgToInput(inputs, param); + } + + auto result = Execute(caller_address, contract_address, inputs, state); + + if (result.ok()) { + return eevm::to_hex_string(*result); + } + else { + LOG(ERROR)<<"execute fail:"<> ContractExecutor::Execute( + const Address& caller_address, const Address& contract_address, + const std::vector& input, + EVMState * state) { + // Ignore any logs produced by this transaction + eevm::NullLogHandler ignore; + eevm::Transaction tx(caller_address, ignore); + + + // Record a trace to aid debugging + eevm::Trace tr; + eevm::Processor p(*state); + + // Run the transaction + try { + const auto exec_result = + p.run(tx, caller_address, state->get(contract_address), input, 0u, &tr); + + if (exec_result.er != eevm::ExitReason::returned) { + // Print the trace if nothing was returned + if (exec_result.er == eevm::ExitReason::threw) { + return absl::InternalError( + fmt::format("Execution error: {}", exec_result.exmsg)); + } + return absl::InternalError("Deployment did not return"); + } + return exec_result.output; + } catch (...) { + return absl::InternalError(fmt::format("Execution error:")); + } +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/contract_executor.h b/platform/consensus/ordering/fides/executor/manager/contract_executor.h new file mode 100644 index 000000000..eed37c969 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/contract_executor.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "service/contract/executor/common/utils.h" +#include "service/contract/executor/manager/evm_state.h" +#include "service/contract/executor/manager/concurrency_controller.h" +#include "service/contract/executor/common/contract_execute_info.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { + +/* +struct ExecuteResp { + int ret; + absl::Status state; + int64_t commit_id; + Address contract_address; + ConcurrencyController :: ModifyMap rws; + std::string result; + int retry_time = 0; + uint64_t user_id = 0; + double runtime = 0; +}; +*/ + +class ContractExecutor { + public: + ContractExecutor() = default; + + ~ContractExecutor() = default; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + absl::StatusOr> Execute( + const Address& owner_address, const Address& contract_address, + const std::vector& func_params, EVMState * state); +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/contract_executor_test.cpp b/platform/consensus/ordering/fides/executor/manager/contract_executor_test.cpp new file mode 100644 index 000000000..3c14e08c5 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/contract_executor_test.cpp @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/multi_contract_executor.h" +#include "service/contract/executor/manager/contract_manager.h" + +#include +#include + +#include + +#include "service/contract/executor/manager/address_manager.h" + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +uint256_t GetAddressHash(uint256_t address){ + std::vectorcode; + code.resize(64u); + eevm::to_big_endian(address, code.data()); + code[63]=1; + + uint8_t h[32]; + eevm::keccak_256(code.data(), static_cast(code.size()), h); + return eevm::from_big_endian(h, sizeof(h)); +} + + +class MultiContractExecutorTest : public Test { + public: + MultiContractExecutorTest() : owner_address_(get_random_address()) { + std::string contract_path = test_dir + "test_data/contract.json"; + LOG(ERROR)<<"test dir:"< storage = std::make_unique(); + DataStorage * storage_ptr = storage.get(); + ContractManager manager(std::move(storage)); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + LOG(ERROR)<<"owner address:"<Load(owner_key).first, 1000); + } + +/* + // receiver 0 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(transfer_receiver)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 0); + + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 0); + } + + // transfer 400 to receiver + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(400)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 400); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + + // owner 600 + { + Address caller = get_random_address(); + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = manager.ExecContract(caller, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 600); + + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 400); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + + // transfer 200 to receiver2 from receiver + { + Params func_params; + func_params.set_func_name("approve(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_ptr->Load(transfer2_key).first, 0); + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 400); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + { + Params func_params; + func_params.set_func_name("transferFrom(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_ptr->Load(transfer2_key).first, 100); + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 300); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + */ +} +/* + +TEST_F(MultiContractExecutorTest, ExecMultiContractNoConflict) { + + std::unique_ptr storage = std::make_unique(); + DataStorage * storage_ptr = storage.get(); + ContractManager manager(std::move(storage)); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + uint256_t owner_key = GetAddressHash(owner_address_); + uint256_t transfer_key = GetAddressHash(transfer_receiver); + uint256_t transfer2_key = GetAddressHash(transfer_receiver2); + uint256_t transfer3_key = GetAddressHash(transfer_receiver3); + + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(400)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 400); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + + // transfer 200 to receiver2 from receiver + { + Params func_params; + func_params.set_func_name("approve(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(200)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } + + std::vector info; + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver3)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("transferFrom(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(200)); + + info.push_back(ContractExecuteInfo(transfer_receiver, contract_address, "", func_params, 0)); + } + std::vector> resp = manager.ExecContract(info); + EXPECT_EQ(storage_ptr->Load(transfer2_key).first, 200); + EXPECT_EQ(storage_ptr->Load(transfer3_key).first, 100); + + LOG(ERROR)<<"resp size:"<ret, 0); + EXPECT_EQ(resp[1]->ret, 0); + + EXPECT_EQ(HexToInt(resp[0]->result), 1); + EXPECT_EQ(HexToInt(resp[1]->result), 1); +} + +TEST_F(MultiContractExecutorTest, ExecMultiContractHaveConflict) { + + std::unique_ptr storage = std::make_unique(); + DataStorage * storage_ptr = storage.get(); + ContractManager manager(std::move(storage)); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + uint256_t owner_key = GetAddressHash(owner_address_); + uint256_t transfer_key = GetAddressHash(transfer_receiver); + uint256_t transfer2_key = GetAddressHash(transfer_receiver2); + uint256_t transfer3_key = GetAddressHash(transfer_receiver3); + + std::vector info; + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address, "", func_params, 0)); + } + + std::vector> resp = manager.ExecContract(info); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 800); + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 100); + EXPECT_EQ(storage_ptr->Load(transfer2_key).first, 100); + + LOG(ERROR)<<"resp size:"<ret, 0); + EXPECT_EQ(resp[1]->ret, 0); + + EXPECT_EQ(HexToInt(resp[0]->result), 1); + EXPECT_EQ(HexToInt(resp[1]->result), 1); +} +*/ + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/contract_manager.cpp b/platform/consensus/ordering/fides/executor/manager/contract_manager.cpp new file mode 100644 index 000000000..f53aa9041 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/contract_manager.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/contract_manager.h" + +#include "service/contract/executor/manager/address_manager.h" +#include "service/contract/executor/manager/two_phase_committer.h" +//#include "service/contract/executor/manager/sequential_concurrency_committer.h" +#include "service/contract/executor/manager/ooo_committer.h" +#include "service/contract/executor/manager/two_phase_ooo_committer.h" +#include "service/contract/executor/manager/streaming_committer.h" +#include "service/contract/executor/manager/streaming_single_committer.h" +#include "service/contract/executor/manager/streaming_dq_committer.h" +#include "service/contract/executor/manager/x_committer.h" +#include "service/contract/executor/manager/x_verifier.h" + +#include +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { + +ContractManager::ContractManager(std::unique_ptr storage, + int worker_num, Options op){ + storage_ = std::move(storage); + gs_ = std::make_unique(storage_.get()); + + switch(op){ + case TwoPL: + committer_ = std::make_unique(storage_.get(), gs_.get(), worker_num); + break; + case TwoPLOOO: + committer_ = std::make_unique(storage_.get(), gs_.get(), worker_num); + break; + case OOO: + committer_ = std::make_unique(storage_.get(), gs_.get(), worker_num); + break; + case Streaming: + committer_ = std::make_unique(storage_.get(), gs_.get(), 500, nullptr, worker_num); + break; + case SCC: + //committer_ = std::make_unique(storage_.get(), gs_.get(), worker_num); + break; + case SingleStreaming: + committer_ = std::make_unique(storage_.get(), gs_.get(), worker_num); + break; + case MultiStreaming: + committer_ = std::make_unique(storage_.get(), gs_.get(), 1500, nullptr, worker_num); + break; + case XE: + committer_ = std::make_unique(storage_.get(), gs_.get(), worker_num); + break; + case XEO: + committer_ = std::make_unique(storage_.get(), gs_.get(), worker_num); + //((XCommitter*)committer_.get())->UseOCC(); + break; + } + + deployer_ = std::make_unique(committer_.get(), gs_.get()); + + verifier_ = std::make_unique(storage_.get(), gs_.get(), worker_num); +} + +void ContractManager::SetExecuteCallBack(std::function resp)> func) { + committer_->SetExecuteCallBack(std::move(func)); +} + +Address ContractManager::DeployContract(const Address& owner_address, + const DeployInfo& deploy_info) { + return deployer_->DeployContract(owner_address, deploy_info); +} + +bool ContractManager::DeployContract(const Address& owner_address, + const DeployInfo& deploy_info, + const Address& contract_address) { + return deployer_->DeployContract(owner_address, deploy_info, contract_address); +} + +absl::StatusOr ContractManager::GetContract(const Address& address) { + return deployer_->GetContract(address); +} + +std::vector> ContractManager::ExecContract(std::vector& execute_info) { + std::map> ct; + std::map cct; + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i+1; + } + + return committer_->ExecContract(execute_info); +} + +void ContractManager::AsyncExecContract(std::vector& execute_info) { + std::map> ct; + std::map cct; + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i+1; + + /* + cct[i]=0; + if(execute_info[i].func_params.param_size()>0){ + for(int j = 0; j < execute_info[i].func_params.param_size()-1; j++){ + auto& p = execute_info[i].func_params.param(j); + //LOG(ERROR)<<"get idx:"<2){ + for(auto id : it.second){ + cct[id]=1; + } + } + } + + int tot = 0, num = 0; + for(auto x : cct){ + if(x.second==1)num++; + tot++; + } + LOG(ERROR)<<"tot:"<AsyncExecContract(execute_info); +} + + +absl::StatusOr ContractManager::ExecContract( + const Address& caller_address, const Address& contract_address, + const Params& func_param) { + std::string func_addr = + deployer_->GetFuncAddress(contract_address, func_param.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << func_param.func_name(); + return absl::InvalidArgumentError("Func not exist."); + } + + + absl::StatusOr result = committer_->ExecContract( + caller_address, contract_address, + func_addr, + func_param, gs_.get()); + if(result.ok()){ + return *result; + } + return result.status(); +} + +bool ContractManager::VerifyContract( + std::vector& ordered_info, + std::vector rws_list) { + return true; + for(int i = 0; i < ordered_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(ordered_info[i].contract_address, ordered_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << ordered_info[i].func_params.func_name(); + ordered_info[i].contract_address = 0; + continue; + } + ordered_info[i].func_addr = func_addr; + } + return verifier_->VerifyContract(ordered_info, rws_list); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/contract_manager.h b/platform/consensus/ordering/fides/executor/manager/contract_manager.h new file mode 100644 index 000000000..7e9c4035d --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/contract_manager.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/contract_verifier.h" +#include "service/contract/executor/manager/contract_deployer.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/common/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { + +class ContractManager { + public: + enum Options { + TwoPL = 1, + SCC = 2, + OOO = 3, + TwoPLOOO = 4, + Streaming = 5, + SingleStreaming = 6, + MultiStreaming = 7, + XE = 8, + XEO = 9, + }; + ContractManager(std::unique_ptr storage, + int worker_num = 2, Options op = TwoPL ); + + public: + Address DeployContract(const Address& owner_address, + const DeployInfo& deploy_info); + + bool DeployContract(const Address& owner_address, + const DeployInfo& deploy_info, + const Address& contract_address); + + absl::StatusOr GetContract(const Address& address); + + absl::StatusOr ExecContract(const Address& caller_address, + const Address& contract_address, + const Params& func_param); + + std::vector> ExecContract( + std::vector& execute_info); + + void AsyncExecContract(std::vector& execute_info); + + void SetExecuteCallBack(std::function resp)> func); + + bool VerifyContract( + std::vector& ordered_info, + std::vector rws_list); + + private: + std::string GetFuncAddress(const Address& contract_address, + const std::string& func_name); + void SetFuncAddress(const Address& contract_address, const FuncInfo& func); + + private: + std::unique_ptr storage_; + std::unique_ptr gs_; + std::unique_ptr committer_; + std::unique_ptr deployer_; + std::unique_ptr verifier_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/contract_manager_test.cpp b/platform/consensus/ordering/fides/executor/manager/contract_manager_test.cpp new file mode 100644 index 000000000..759a24666 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/contract_manager_test.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/contract_manager.h" + +#include +#include + +#include + +#include "service/contract/executor/manager/address_manager.h" + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +class ContractManagerTest : public Test { + public: + ContractManagerTest() : owner_address_(get_random_address()) { + LOG(ERROR)<<"owner:"<()); + auto account = manager.GetContract(1234); + EXPECT_FALSE(account.ok()); +} + +TEST_F(ContractManagerTest, DeployContract) { + ContractManager manager(std::make_unique()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); +} + +TEST_F(ContractManagerTest, InitContract) { + ContractManager manager(std::make_unique()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + LOG(ERROR)<<" deploy done:"<()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + // owner 1000 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1000); + } + + // receiver 0 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(transfer_receiver)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 0); + } + + // transfer 400 to receiver + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(400)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } + + // receiver 400 + { + Address caller = get_random_address(); + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(transfer_receiver)); + + auto result = manager.ExecContract(caller, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 400); + } + // owner 600 + { + Address caller = get_random_address(); + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = manager.ExecContract(caller, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 600); + } + + // transfer 200 to receiver2 from receiver + { + Params func_params; + func_params.set_func_name("approve(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(200)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } + { + Params func_params; + func_params.set_func_name("transferFrom(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(200)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } +} + +TEST_F(ContractManagerTest, NoFunc) { + ContractManager manager(std::make_unique()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + // owner 1000 + { + Params func_params; + func_params.set_func_name("balanceOf()"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_FALSE(result.ok()); + } +} + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/contract_verifier.cpp b/platform/consensus/ordering/fides/executor/manager/contract_verifier.cpp new file mode 100644 index 000000000..96df4fe89 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/contract_verifier.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/contract_verifier.h" + +namespace resdb { +namespace contract { + + +ContractVerifier:: ContractVerifier(){ + executor_ = std::make_unique(); +} + +ContractVerifier::~ContractVerifier(){ +} + +std::vector> ContractVerifier::ExecContract(std::vector& request ){ + return std::vector>(); +} + +absl::StatusOr ContractVerifier::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + + +} // namespace contract +} // namespace resdb + diff --git a/platform/consensus/ordering/fides/executor/manager/contract_verifier.h b/platform/consensus/ordering/fides/executor/manager/contract_verifier.h new file mode 100644 index 000000000..cb45fbdd7 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/contract_verifier.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "absl/status/statusor.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/committer_context.h" +#include "service/contract/executor/manager/contract_executor.h" + +namespace resdb { +namespace contract { + +class ContractVerifier : public ContractCommitter { + public: + ContractVerifier(); + virtual ~ContractVerifier(); + + virtual bool VerifyContract( + const std::vector& request_list, + const std::vector& rws_list) = 0; + + std::vector> ExecContract( + std::vector& request )override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) override; + + protected: + std::unique_ptr executor_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/d_storage.cpp b/platform/consensus/ordering/fides/executor/manager/d_storage.cpp new file mode 100644 index 000000000..30b9b3a12 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/d_storage.cpp @@ -0,0 +1,164 @@ +#include "service/contract/executor/manager/d_storage.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +namespace { + + int GetHashKey(const uint256_t& address){ + // Get big-endian form + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%1024; + } + +void InternalReset(const uint256_t& key, const uint256_t& value, int64_t version, + std::map > * db, std::shared_mutex * mutex ) { + std::unique_lock lock(*mutex); + (*db)[key] = std::make_pair(value,version); +} + +int64_t InternalStore(const uint256_t& key, const uint256_t& value, + std::map > * db, std::shared_mutex * mutex ) { + + std::unique_lock lock(*mutex); + int64_t v = (*db)[key].second; + (*db)[key] = std::make_pair(value,v+1); + //LOG(ERROR)<<"store key:"< InternalLoad(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex){ + + std::shared_lock lock(*mutex); + auto e = db->find(key); + if (e == db->end()) + return std::make_pair(0,0); + return e->second; +} + +bool InternalRemove(const uint256_t& key, + std::map > * db, + std::shared_mutex * mutex) { + + std::unique_lock lock(*mutex); + auto e = db->find(key); + if (e == db->end()) + return false; + db->erase(e); + return true; +} + +bool InternalExist(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + return db->find(key) != db->end(); +} + +int64_t InternalGetVersion(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + auto it = db->find(key); + if( it == db->end()){ + //LOG(ERROR)<<"get version key:"<second.second; + return it->second.second; +} + +} + +int64_t D_Storage::Store(const uint256_t& key, const uint256_t& value, bool is_to_local_view) { + //LOG(ERROR)<<"store key:"< D_Storage::Load(const uint256_t& key, bool is_local_view) const { + //LOG(ERROR)<<"load key:"< +#include + +#include "service/contract/executor/manager/data_storage.h" + +#include "eEVM/util.h" + +namespace resdb { +namespace contract { + +class D_Storage : public DataStorage { + +public: + virtual int64_t Store(const uint256_t& key, const uint256_t& value, bool is_local); + virtual std::pair Load(const uint256_t& key, bool is_from_local_view) const; + virtual bool Remove(const uint256_t& key, bool is_local); + virtual bool Exist(const uint256_t& key, bool is_local) const; + + virtual int64_t GetVersion(const uint256_t& key, bool is_local) const; + + virtual void Reset(const uint256_t& key, const uint256_t& value, int64_t version, bool is_local); + +protected: + std::map > c_s_[1024]; + mutable std::shared_mutex mutex_[1024]; + + std::map > g_s_[1024]; + mutable std::shared_mutex g_mutex_[1024]; + +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/data_storage.cpp b/platform/consensus/ordering/fides/executor/manager/data_storage.cpp new file mode 100644 index 000000000..43208b61e --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/data_storage.cpp @@ -0,0 +1,74 @@ +#include "service/contract/executor/manager/data_storage.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +namespace { + + int GetHashKey(const uint256_t& address){ + // Get big-endian form + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return 0; + return v%2048; + } +} + +int64_t DataStorage::Store(const uint256_t& key, const uint256_t& value, bool) { + int idx = GetHashKey(key); + std::unique_lock lock(mutex_[idx]); + //LOG(ERROR)<<"store key:"< DataStorage::Load(const uint256_t& key, bool) const { +int idx = GetHashKey(key); + std::shared_lock lock(mutex_[idx]); + //LOG(ERROR)<<"load key:"<second; +} + +bool DataStorage::Remove(const uint256_t& key, bool) { +int idx = GetHashKey(key); + std::unique_lock lock(mutex_[idx]); + auto e = s.find(key); + if (e == s.end()) + return false; + s.erase(e); + return true; +} + +bool DataStorage::Exist(const uint256_t& key, bool) const { +int idx = GetHashKey(key); + std::shared_lock lock(mutex_[idx]); + return s.find(key) != s.end(); +} + +int64_t DataStorage::GetVersion(const uint256_t& key, bool) const{ +int idx = GetHashKey(key); + std::shared_lock lock(mutex_[idx]); + auto it = s.find(key); + if( it == s.end()){ + return 0; + } + return it->second.second; +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/data_storage.h b/platform/consensus/ordering/fides/executor/manager/data_storage.h new file mode 100644 index 000000000..1a52d8717 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/data_storage.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +#include "eEVM/util.h" + +namespace resdb { +namespace contract { + +class DataStorage { + +public: + DataStorage() = default; + virtual ~DataStorage() = default; + + virtual int64_t Store(const uint256_t& key, const uint256_t& value, bool is_local = false); + virtual std::pair Load(const uint256_t& key, bool is_local_view = false) const; + virtual bool Remove(const uint256_t& key, bool is_local = false); + virtual bool Exist(const uint256_t& key, bool is_local = false) const; + + virtual int64_t GetVersion(const uint256_t& key, bool is_local = false) const; + + virtual void Reset(const uint256_t& key, const uint256_t& value, int64_t version, bool is_local = false) {} + virtual void Flush(){}; + +protected: + std::map > s; + //std::map > s[4096]; + mutable std::shared_mutex mutex_[4096]; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/evm_state.h b/platform/consensus/ordering/fides/executor/manager/evm_state.h new file mode 100644 index 000000000..ccd0d9500 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/evm_state.h @@ -0,0 +1,23 @@ +#pragma once + +#include "eEVM/globalstate.h" + +namespace resdb { +namespace contract { + +class EVMState : public eevm::GlobalState { +public: + EVMState() = default; + virtual ~EVMState() = default; + +protected: + const eevm::Block& get_current_block() override { return block_; } + uint256_t get_block_hash(uint8_t offset) override { return 0; } + +private: + // Unused. + eevm::Block block_; +}; + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/global_state.cpp b/platform/consensus/ordering/fides/executor/manager/global_state.cpp new file mode 100644 index 000000000..e10f02e96 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/global_state.cpp @@ -0,0 +1,50 @@ +#include "service/contract/executor/manager/global_state.h" + +#include + +namespace resdb { +namespace contract { + +using eevm::Address; +using eevm::AccountState; +using eevm::Code; +using eevm::SimpleAccount; + + GlobalState::GlobalState(DataStorage * storage) : storage_(storage) { + } + + bool GlobalState::Exists(const eevm::Address& addr) { + return accounts.find(addr) != accounts.cend(); + } + + void GlobalState::remove(const Address& addr) { + accounts.erase(addr); + } + + AccountState GlobalState::get(const Address& addr) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()) + return acc->second; + + return create(addr, 0, {}); + } + + AccountState GlobalState::create( + const Address& addr, const uint256_t& balance, const Code& code) { + Insert({SimpleAccount(addr, balance, code), GlobalView(storage_)}); + + return get(addr); + } + + const eevm::SimpleAccount& GlobalState::GetAccount(const eevm::Address& addr) { + const auto acc = accounts.find(addr); + return acc->second.first; + } + + void GlobalState::Insert(const StateEntry& p) { + const auto ib = accounts.insert(std::make_pair(p.first.get_address(), p)); + + assert(ib.second); + } +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/global_state.h b/platform/consensus/ordering/fides/executor/manager/global_state.h new file mode 100644 index 000000000..99a418966 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/global_state.h @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include "service/contract/executor/manager/global_view.h" +#include "service/contract/executor/manager/evm_state.h" + +#include "eEVM/simple/simpleaccount.h" + +namespace resdb { +namespace contract { + + class GlobalState : public EVMState{ + public: + using StateEntry = std::pair; + + public: + GlobalState(DataStorage* storage); + virtual ~GlobalState() = default; + + virtual void remove(const eevm::Address& addr) override; + + // Get contract by contract address. + eevm::AccountState get(const eevm::Address& addr) override; + + bool Exists(const eevm::Address& addr); + + // Create an account for the contract, which the balance is 0. + eevm::AccountState create( + const eevm::Address& addr, const uint256_t& balance, const eevm::Code& code) override; + + const eevm::SimpleAccount& GetAccount(const eevm::Address& addr) ; + + protected: + void Insert(const StateEntry& p); + + private: + std::map accounts; + DataStorage* storage_; + }; + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/global_view.cpp b/platform/consensus/ordering/fides/executor/manager/global_view.cpp new file mode 100644 index 000000000..1cfbb5b41 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/global_view.cpp @@ -0,0 +1,25 @@ +#include "service/contract/executor/manager/global_view.h" + +#include "eEVM/util.h" + +#include + +namespace resdb { +namespace contract { + +GlobalView::GlobalView(DataStorage* storage) :storage_(storage){ } + +void GlobalView::store(const uint256_t& key, const uint256_t& value) { + storage_->Store(key, value); +} + +uint256_t GlobalView::load(const uint256_t& key) { + return storage_->Load(key).first; +} + +bool GlobalView::remove(const uint256_t& key) { + return storage_->Remove(key); +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/global_view.h b/platform/consensus/ordering/fides/executor/manager/global_view.h new file mode 100644 index 000000000..948ed4ffc --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/global_view.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include "service/contract/executor/manager/data_storage.h" +#include "eEVM/storage.h" + +namespace resdb { +namespace contract { + +class GlobalView : public eevm::Storage { + +public: + GlobalView(DataStorage* storage); + virtual ~GlobalView() = default; + + void store(const uint256_t& key, const uint256_t& value) override; + uint256_t load(const uint256_t& key) override; + bool remove(const uint256_t& key) override; + +private: + DataStorage * storage_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/level_d_storage.cpp b/platform/consensus/ordering/fides/executor/manager/level_d_storage.cpp new file mode 100644 index 000000000..87502f016 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/level_d_storage.cpp @@ -0,0 +1,225 @@ +#include "service/contract/executor/manager/level_d_storage.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +namespace { + +void InternalReset(const uint256_t& key, const uint256_t& value, int64_t version, + std::map > * db, std::shared_mutex * mutex ) { + + std::unique_lock lock(*mutex); + (*db)[key] = std::make_pair(value,version); +} + +int64_t InternalStore(const uint256_t& key, const uint256_t& value, + std::map > * db, std::shared_mutex * mutex ) { + + std::unique_lock lock(*mutex); + int64_t v = (*db)[key].second; + (*db)[key] = std::make_pair(value,v+1); + //LOG(ERROR)<<"store key:"< InternalLoad(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex){ + + std::shared_lock lock(*mutex); + auto e = db->find(key); + if (e == db->end()) + return std::make_pair(0,0); + return e->second; +} + +bool InternalRemove(const uint256_t& key, + std::map > * db, + std::shared_mutex * mutex) { + + std::unique_lock lock(*mutex); + auto e = db->find(key); + if (e == db->end()) + return false; + db->erase(e); + return true; +} + + + + +bool InternalExist(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + return db->find(key) != db->end(); +} + +int64_t InternalGetVersion(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + auto it = db->find(key); + if( it == db->end()){ + //LOG(ERROR)<<"get version key:"<second.second; + return it->second.second; +} + +std::string GetString(const uint256_t& key){ + return ""; +} + +uint256_t GetInt256(const std::string& value){ + return 0; +} + +std::string GetData(const uint256_t& value, int64_t version){ + std::string v_str = GetString(value); + std::string v((const char *)&version, sizeof(value)); + v.append(v_str, v_str.size()); + return v; +} + +int64_t GetVersion(const std::string& value){ + int64_t v; + memcpy(&v, value.c_str(), sizeof(v)); + return v; +} + +uint256_t GetValue(const std::string& value){ + return GetInt256(std::string(value.c_str()+sizeof(int64_t),value.size()-sizeof(int64_t))); +} + +int64_t InternalStore(const uint256_t& key, const uint256_t& value, + ResLevelDB* db, + std::shared_mutex * mutex ) { + + std::unique_lock lock(*mutex); + std::string old_value = db->GetValue(GetString(key)); + int64_t v = GetVersion(old_value); + db->SetValue(GetString(key), GetData(value, v+1)); + //LOG(ERROR)<<"store key:"< InternalLoad(const uint256_t& key, + ResLevelDB* db, + std::shared_mutex * mutex){ + std::shared_lock lock(*mutex); + std::string value = db->GetValue(GetString(key)); + return std::make_pair(GetValue(value), GetVersion(value)); +} + +bool InternalRemove(const uint256_t& key, + ResLevelDB* db, + std::shared_mutex * mutex) { + + std::unique_lock lock(*mutex); + db->SetValue(GetString(key), ""); + return true; +} + +bool InternalExist(const uint256_t& key, + ResLevelDB* db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + std::string value = db->GetValue(GetString(key)); + return value.empty(); +} + +void InternalReset(const uint256_t& key, const uint256_t& value, int64_t version, + ResLevelDB* db, + std::shared_mutex * mutex ) { + + std::unique_lock lock(*mutex); + db->SetValue(GetString(key), GetData(value, version)); +} + +int64_t InternalGetVersion(const uint256_t& key, + ResLevelDB* db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + std::string value = db->GetValue(GetString(key)); + return GetVersion(value); +} + +} + +int64_t D_Storage::Store(const uint256_t& key, const uint256_t& value, bool is_to_local_view) { + //LOG(ERROR)<<"store key:"< D_Storage::Load(const uint256_t& key, bool is_local_view) const { + //LOG(ERROR)<<"load key:"< +#include + +#include "service/contract/executor/manager/data_storage.h" +#include "storage/res_leveldb.h" + +#include "eEVM/util.h" + +namespace resdb { +namespace contract { + +class D_Storage : public DataStorage { + +public: + virtual int64_t Store(const uint256_t& key, const uint256_t& value, bool is_local); + virtual std::pair Load(const uint256_t& key, bool is_from_local_view) const; + virtual bool Remove(const uint256_t& key, bool is_local); + virtual bool Exist(const uint256_t& key, bool is_local) const; + + virtual int64_t GetVersion(const uint256_t& key, bool is_local) const; + + virtual void Reset(const uint256_t& key, const uint256_t& value, int64_t version, bool is_local); + +protected: + std::map > c_s_; + mutable std::shared_mutex mutex_; + + std::unique_ptr g_s_; + mutable std::shared_mutex g_mutex_; + +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/leveldb.cpp b/platform/consensus/ordering/fides/executor/manager/leveldb.cpp new file mode 100644 index 000000000..b540aed45 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/leveldb.cpp @@ -0,0 +1,30 @@ +#include "service/contract/executor/manager/leveldb.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +LevelDB::LevelDB(){ + db_ = std::make_unique("./"); + db_->SetBatchSize(10000); +} + +void LevelDB::Flush(){ + //LOG(ERROR)<<"flush"; + for(const auto& it : s){ + std::string addr = eevm::to_hex_string(it.first); + std::string value = eevm::to_hex_string(it.second.first); + //LOG(ERROR)<<"addr:"<SetValue(addr, std::string(buf, value.size()+sizeof(it.second.second))); + delete buf; + } +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/leveldb.h b/platform/consensus/ordering/fides/executor/manager/leveldb.h new file mode 100644 index 000000000..e76ca274f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/leveldb.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#include "eEVM/util.h" +#include "service/contract/executor/manager/data_storage.h" +#include "storage/res_leveldb.h" + +namespace resdb { +namespace contract { + +class LevelDB : public DataStorage { + +public: + LevelDB(); + virtual ~LevelDB() = default; + + virtual void Flush(); + +private: + std::unique_ptr db_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/leveldb_d_storage.cpp b/platform/consensus/ordering/fides/executor/manager/leveldb_d_storage.cpp new file mode 100644 index 000000000..e486d95fb --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/leveldb_d_storage.cpp @@ -0,0 +1,204 @@ + +#include "service/contract/executor/manager/leveldb_d_storage.h" +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +namespace { + + int GetHashKey(const uint256_t& address){ + // Get big-endian form + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%1024; + } + + +void Write(const uint256_t& key, const uint256_t& value, int version, ResLevelDB * db){ + std::string addr = eevm::to_hex_string(key); + + const uint8_t* bytes = intx::as_bytes(value); + size_t sz = sizeof(value); + db->SetValue(addr, std::string((const char*)bytes, sz)); + return; +} + +uint256_t Read(const uint256_t& key, ResLevelDB * db){ + std::string addr = eevm::to_hex_string(key); + + std::string v = db->GetValue(addr); + if(v.empty()){ + return 0; + } + + uint8_t tmp[32] = {}; + memcpy(tmp, v.c_str(), 32); + return intx::le::load(tmp); +} + + +void InternalReset(const uint256_t& key, const uint256_t& value, int64_t version, + std::map > * db, std::shared_mutex * mutex, ResLevelDB * storage ) { + std::unique_lock lock(*mutex); + (*db)[key] = std::make_pair(value,version); + if(storage) { + Write(key, value, version, storage); + } +} + +int64_t InternalStore(const uint256_t& key, const uint256_t& value, + std::map > * db, std::shared_mutex * mutex, ResLevelDB * storage ) { + + std::unique_lock lock(*mutex); + int64_t v = (*db)[key].second; + (*db)[key] = std::make_pair(value,v+1); + if(storage) { + Write(key, value, v+1, storage); + } + //LOG(ERROR)<<"store key:"< InternalLoad(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex, ResLevelDB * storage){ + + std::shared_lock lock(*mutex); + auto e = db->find(key); + if (e == db->end()){ + if(storage) { + //LOG(ERROR)<<"load from db:"; + return std::make_pair(Read(key, storage), 0); + } + return std::make_pair(0,0); + } + return e->second; +} + +bool InternalRemove(const uint256_t& key, + std::map > * db, + std::shared_mutex * mutex) { + + std::unique_lock lock(*mutex); + auto e = db->find(key); + if (e == db->end()) + return false; + db->erase(e); + return true; +} + +bool InternalExist(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + return db->find(key) != db->end(); +} + +int64_t InternalGetVersion(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + auto it = db->find(key); + if( it == db->end()){ + //LOG(ERROR)<<"get version key:"<second.second; + return it->second.second; +} + +} + +LevelDB_D_Storage :: LevelDB_D_Storage(){ + db_ = std::make_unique("./"); +} + + +int64_t LevelDB_D_Storage::Store(const uint256_t& key, const uint256_t& value, bool is_to_local_view) { + //LOG(ERROR)<<"store key:"< LevelDB_D_Storage::Load(const uint256_t& key, bool is_local_view) const { + //LOG(ERROR)<<"load key:"< +#include + +#include "service/contract/executor/manager/data_storage.h" +#include "storage/res_leveldb.h" + +namespace resdb { +namespace contract { + +class LevelDB_D_Storage : public DataStorage { +public: + LevelDB_D_Storage(); + +public: + virtual int64_t Store(const uint256_t& key, const uint256_t& value, bool is_local); + virtual std::pair Load(const uint256_t& key, bool is_from_local_view) const; + virtual bool Remove(const uint256_t& key, bool is_local); + virtual bool Exist(const uint256_t& key, bool is_local) const; + + virtual int64_t GetVersion(const uint256_t& key, bool is_local) const; + + virtual void Reset(const uint256_t& key, const uint256_t& value, int64_t version, bool is_local); + +protected: + std::map > c_s_[1024]; + mutable std::shared_mutex mutex_[1024]; + + std::map > g_s_[1024]; + mutable std::shared_mutex g_mutex_[1024]; + + std::unique_ptr db_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/leveldb_storage.cpp b/platform/consensus/ordering/fides/executor/manager/leveldb_storage.cpp new file mode 100644 index 000000000..0723fc5b9 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/leveldb_storage.cpp @@ -0,0 +1,113 @@ +#include "service/contract/executor/manager/leveldb_storage.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +namespace { + + int GetHashKey(const uint256_t& address){ + // Get big-endian form + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return 0; + return v%2048; + } +} + +LevelDBStorage :: LevelDBStorage(){ + db_ = std::make_unique("./"); +} + +void LevelDBStorage::Write(const uint256_t& key, const uint256_t& value, int version){ + std::string addr = eevm::to_hex_string(key); + + const uint8_t* bytes = intx::as_bytes(value); + size_t sz = sizeof(value); + db_->SetValue(addr, std::string((const char*)bytes, sz)); + return; + + //LOG(ERROR)<<"addr:"<SetValue(addr, std::string(buf, sz+sizeof(version))); + LOG(ERROR)<<"write db"; + delete buf; +} + +uint256_t LevelDBStorage::Read(const uint256_t& key) const { + std::string addr = eevm::to_hex_string(key); + + std::string v = db_->GetValue(addr); + if(v.empty()){ + return 0; + } + + uint8_t tmp[32] = {}; + memcpy(tmp, v.c_str(), 32); + return intx::le::load(tmp); +} + + +int64_t LevelDBStorage::Store(const uint256_t& key, const uint256_t& value, bool) { + int idx = GetHashKey(key); + std::unique_lock lock(mutex_[idx]); + //LOG(ERROR)<<"store key:"< LevelDBStorage::Load(const uint256_t& key, bool) const { +int idx = GetHashKey(key); + std::shared_lock lock(mutex_[idx]); + //LOG(ERROR)<<"load key:"<second; +} + +bool LevelDBStorage::Remove(const uint256_t& key, bool) { +int idx = GetHashKey(key); + std::unique_lock lock(mutex_[idx]); + auto e = s[idx].find(key); + if (e == s[idx].end()) + return false; + s[idx].erase(e); + return true; +} + +bool LevelDBStorage::Exist(const uint256_t& key, bool) const { +int idx = GetHashKey(key); + std::shared_lock lock(mutex_[idx]); + return s[idx].find(key) != s[idx].end(); +} + +int64_t LevelDBStorage::GetVersion(const uint256_t& key, bool) const{ +int idx = GetHashKey(key); + std::shared_lock lock(mutex_[idx]); + auto it = s[idx].find(key); + if( it == s[idx].end()){ + return 0; + } + return it->second.second; +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/leveldb_storage.h b/platform/consensus/ordering/fides/executor/manager/leveldb_storage.h new file mode 100644 index 000000000..8a1a38df2 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/leveldb_storage.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include + +#include "service/contract/executor/manager/data_storage.h" +#include "storage/res_leveldb.h" + +namespace resdb { +namespace contract { + +class LevelDBStorage : public DataStorage { + +public: + LevelDBStorage(); + virtual ~LevelDBStorage() = default; + + virtual int64_t Store(const uint256_t& key, const uint256_t& value, bool is_local = false); + virtual std::pair Load(const uint256_t& key, bool is_local_view = false) const; + virtual bool Remove(const uint256_t& key, bool is_local = false); + virtual bool Exist(const uint256_t& key, bool is_local = false) const; + + virtual int64_t GetVersion(const uint256_t& key, bool is_local = false) const; + + virtual void Reset(const uint256_t& key, const uint256_t& value, int64_t version, bool is_local = false) {} + virtual void Flush(){}; + +private: + void Write(const uint256_t& key, const uint256_t& value, int version); + uint256_t Read(const uint256_t& key) const; + +protected: + std::map > s[4096]; + mutable std::shared_mutex mutex_[4096]; + std::unique_ptr db_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/local_state.cpp b/platform/consensus/ordering/fides/executor/manager/local_state.cpp new file mode 100644 index 000000000..e9cdc8318 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/local_state.cpp @@ -0,0 +1,73 @@ +#include "service/contract/executor/manager/local_state.h" + +#include + +namespace resdb { +namespace contract { + +using eevm::Address; +using eevm::AccountState; +using eevm::Code; +using eevm::SimpleAccount; + + LocalState::LocalState(ConcurrencyController * controller) : controller_(controller) { + } + + bool LocalState::Exists(const eevm::Address& addr) { + return accounts.find(addr) != accounts.cend(); + } + + void LocalState::remove(const Address& addr) { + accounts.erase(addr); + } + + AccountState LocalState::get(const Address& addr) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()) + return acc->second; + + return create(addr, 0, {}); + } + + AccountState LocalState::create( + const Address& addr, const uint256_t& balance, const Code& code) { + Insert({SimpleAccount(addr, balance, code), LocalView(controller_, 0)}); + return get(addr); + } + + const eevm::SimpleAccount& LocalState::GetAccount(const eevm::Address& addr) { + const auto acc = accounts.find(addr); + return acc->second.first; + } + + void LocalState::Set(const eevm::SimpleAccount& acc, int64_t commit_id) { + Insert({acc, LocalView(controller_, commit_id)}); + } + + void LocalState::Insert(const StateEntry& p) { + const auto ib = accounts.insert(std::make_pair(p.first.get_address(), p)); + + assert(ib.second); + } + + bool LocalState::Flesh(const Address& addr, int commit_id) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()){ + acc->second.second.Flesh(commit_id); + return true; + } + return false; + } + +/* + bool LocalState::Commit(const eevm::Address& addr) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()){ + return acc->second.second.Commit(); + } + return false; + } + */ + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/local_state.h b/platform/consensus/ordering/fides/executor/manager/local_state.h new file mode 100644 index 000000000..510b9fb50 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/local_state.h @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include "service/contract/executor/manager/local_view.h" +#include "service/contract/executor/manager/concurrency_controller.h" +#include "service/contract/executor/manager/evm_state.h" + +#include "eEVM/simple/simpleaccount.h" + +namespace resdb { +namespace contract { + + class LocalState : public EVMState { + public: + using StateEntry = std::pair; + + public: + LocalState(ConcurrencyController * controller); + virtual ~LocalState() = default; + + virtual void remove(const eevm::Address& addr) override; + + // Get contract by contract address. + eevm::AccountState get(const eevm::Address& addr) override; + + bool Exists(const eevm::Address& addr); + + // Flesh the local view to the controller with a commit id. + // Once all the contracts have fleshed their changes, they should call commit. + // Return false if contract not exists. + bool Flesh(const eevm::Address& addr, int commit_id); + // Commit the changes using the commit id from the flesh. + //bool Commit(const eevm::Address& addr); + + // Create an account for the contract, which the balance is 0. + eevm::AccountState create( + const eevm::Address& addr, const uint256_t& balance, const eevm::Code& code) override; + + const eevm::SimpleAccount& GetAccount(const eevm::Address& addr) ; + void Set(const eevm::SimpleAccount& acc, int64_t commit_id); + + protected: + void Insert(const StateEntry& p); + + private: + std::map accounts; + ConcurrencyController * controller_; + }; + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/local_view.cpp b/platform/consensus/ordering/fides/executor/manager/local_view.cpp new file mode 100644 index 000000000..816bfef7a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/local_view.cpp @@ -0,0 +1,78 @@ +#include "service/contract/executor/manager/local_view.h" + +#include "eEVM/util.h" + +#include + +namespace resdb { +namespace contract { + +LocalView::LocalView(ConcurrencyController * controller, int64_t commit_id) + :controller_(controller), + commit_id_(commit_id){ } + +void LocalView::store(const uint256_t& key, const uint256_t& value) { + //LOG(ERROR)<<"========= store key:"< load_value = controller_->GetStorage()->Load(key, /*is_from_local=*/true); + local_changes_[key].push_back(Data(STORE, value, 0, 0)); + } + else { + const Data& data = local_changes_[key].back(); + if(data.state == LOAD){ + local_changes_[key].push_back(Data(STORE, value, data.version+1)); + } + else { + int64_t v = data.version; + local_changes_[key].pop_back(); + local_changes_[key].push_back(Data(STORE, value, v)); + } + } +} + +uint256_t LocalView::load(const uint256_t& key) { + //LOG(ERROR)<<"load key:"< value = controller_->GetStorage()->Load(key, /*is_from_local=*/true); + local_changes_[key].push_back(Data(LOAD, value.first, value.second)); + return value.first; + } + return it->second.back().data; +} + +bool LocalView::remove(const uint256_t& key) { + store(key, 0); + return true; + + //local_changes_[key].push_back(Data(REMOVE)); + auto it = local_changes_.find(key); + if (it == local_changes_.end()){ + std::pair load_value = controller_->GetStorage()->Load(key, /*is_from_local=*/true); + local_changes_[key].push_back(Data(REMOVE, 0, load_value.second, load_value.first)); + } + else { + const Data& data = local_changes_[key].back(); + if(data.state == LOAD){ + local_changes_[key].push_back(Data(REMOVE, 0, data.version+1)); + } + else { + int64_t v = data.version; + local_changes_[key].pop_back(); + local_changes_[key].push_back(Data(REMOVE, 0, v)); + } + } + + return true; +} + +void LocalView::Flesh(int64_t commit_id) { + commit_id_ = commit_id; + //LOG(ERROR)<<"commit push:"<PushCommit(commit_id, local_changes_); + local_changes_.clear(); +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/local_view.h b/platform/consensus/ordering/fides/executor/manager/local_view.h new file mode 100644 index 000000000..9a4731976 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/local_view.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +#include "service/contract/executor/manager/concurrency_controller.h" +#include "eEVM/storage.h" + +namespace resdb { +namespace contract { + +class LocalView : public eevm::Storage { + +public: + LocalView(ConcurrencyController * controller, int64_t commit_id); + virtual ~LocalView() = default; + + void store(const uint256_t& key, const uint256_t& value) override; + uint256_t load(const uint256_t& key) override; + bool remove(const uint256_t& key) override; + + // for 2PL, once it is done, all the commit will be pushed to + // the controller to judge if it can be committed. + // During the flesh, all the changes will be removed. + void Flesh(int64_t commit_id); + // Commit the changes. If there is a conflict, return false. + // Make sure all other committers have pushed their changes before calling Commit. + //bool Commit(); + // Remove all the changes. + //void Abort(); + +private: + ConcurrencyController * controller_; + int64_t commit_id_; + std::map> local_changes_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/local_view_test.cpp b/platform/consensus/ordering/fides/executor/manager/local_view_test.cpp new file mode 100644 index 000000000..f05672a9f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/local_view_test.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/local_view.h" +#include "service/contract/executor/manager/two_phase_controller.h" + +#include +#include + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +TEST(LocalViewTest, ViewChange) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + LocalView view(&controller, 0); + + EXPECT_EQ(view.load(address1), 2000) ; + view.store(address1, 3000); + EXPECT_EQ(view.load(address1), 3000) ; + + // storage still contains 2000 + EXPECT_EQ(storage.Load(address1).first, 2000); +} + +TEST(LocalViewTest, CommitChange) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + LocalView view(&controller, 0); + + EXPECT_EQ(view.load(address1), 2000) ; + view.store(address1, 3000); + EXPECT_EQ(view.load(address1), 3000) ; + + // storage still contains 2000 + EXPECT_EQ(storage.Load(address1).first, 2000); + + view.Flesh(0); + EXPECT_TRUE(controller.Commit(0)); + // Save to real storage. + EXPECT_EQ(storage.Load(address1).first, 3000); +} + +TEST(LocalViewTest, CommitConflict) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + LocalView view1(&controller, 0); + LocalView view2(&controller, 1); + + EXPECT_EQ(view1.load(address1), 2000) ; + view1.store(address1, 3000); + EXPECT_EQ(view1.load(address1), 3000) ; + + // storage still contains 2000 + EXPECT_EQ(storage.Load(address1).first, 2000); + + + EXPECT_EQ(view2.load(address1), 2000) ; + view2.store(address1, 4000); + EXPECT_EQ(view2.load(address1), 4000) ; + + // storage still contains 2000 + EXPECT_EQ(storage.Load(address1).first, 2000); + + + view1.Flesh(0); + view2.Flesh(1); + + EXPECT_FALSE(controller.Commit(1)); + EXPECT_TRUE(controller.Commit(0)); + + // Save to real storage. + EXPECT_EQ(storage.Load(address1).first, 3000); +} + + + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/mock_d_storage.h b/platform/consensus/ordering/fides/executor/manager/mock_d_storage.h new file mode 100644 index 000000000..01d590af3 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/mock_d_storage.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "gmock/gmock.h" +#include "service/contract/executor/manager/d_storage.h" + +namespace resdb { +namespace contract { + +class MockDStorage : public D_Storage { + public: + typedef std::pair LoadType; + + MOCK_METHOD(int64_t, Store, (const uint256_t& key, const uint256_t& value, bool), (override)); + MOCK_METHOD(bool, Remove, (const uint256_t&, bool), (override)); + MOCK_METHOD(bool, Exist, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(int64_t, GetVersion, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(LoadType, Load, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(void, Reset, (const uint256_t&, const uint256_t&, int64_t, bool), (override)); +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/mock_data_storage.h b/platform/consensus/ordering/fides/executor/manager/mock_data_storage.h new file mode 100644 index 000000000..99717b1f4 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/mock_data_storage.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "gmock/gmock.h" +#include "service/contract/executor/manager/data_storage.h" + +namespace resdb { +namespace contract { + +class MockStorage : public DataStorage { + public: + typedef std::pair LoadType; + + MOCK_METHOD(int64_t, Store, (const uint256_t& key, const uint256_t& value, bool), (override)); + MOCK_METHOD(bool, Remove, (const uint256_t&, bool), (override)); + MOCK_METHOD(bool, Exist, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(int64_t, GetVersion, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(LoadType, Load, (const uint256_t&, bool), (const, override)); +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/ooo_committer.cpp b/platform/consensus/ordering/fides/executor/manager/ooo_committer.cpp new file mode 100644 index 000000000..20980d8ea --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/ooo_committer.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/ooo_committer.h" + +#include "service/contract/executor/manager/local_state.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { + +OOOCommitter:: OOOCommitter( + DataStorage * storage, + GlobalState * global_state, int worker_num):gs_(global_state),worker_num_(worker_num) { + + controller_ = std::make_unique(storage); + executor_ = std::make_unique(); + is_stop_ = false; + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request = request_queue_.Pop(); + if (request == nullptr) { + continue; + } + LocalState local_state(controller_.get()); + local_state.Set(gs_->GetAccount( + request->contract_address), + request->commit_id); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->caller_address, + request->contract_address, + request->func_addr, + request->func_params, &local_state); + resp->state = ret.status(); + resp->contract_address = request->contract_address; + resp->commit_id = request->commit_id; + resp->user_id = request->user_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + } + else { + resp->ret = -1; + } + resp_queue_.Push(std::move(resp)); + } + })); + } +} + +OOOCommitter::~OOOCommitter(){ + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + +std::vector> OOOCommitter::ExecContract( + std::vector& requests) { + + int process_num = requests.size(); + std::vector> resp_list; + + std::set commits; + resp_list.resize(process_num); + + for(auto& request: requests) { + request_queue_.Push(std::make_unique(request)); + } + + while(process_num){ + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + int64_t resp_commit_id = resp->commit_id; + resp_list[resp->commit_id-1]=std::move(resp); + process_num--; + } + + return resp_list; +} + +absl::StatusOr OOOCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/ooo_committer.h b/platform/consensus/ordering/fides/executor/manager/ooo_committer.h new file mode 100644 index 000000000..18cf258ef --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/ooo_committer.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/ooo_controller.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/common/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { + +class OOOCommitter : public ContractCommitter { + public: + OOOCommitter( + DataStorage * storage, + GlobalState * global_state, int worker_num = 2); + + ~OOOCommitter(); + + std::vector> ExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + private: + std::unique_ptr controller_; + std::unique_ptr executor_; + GlobalState* gs_; + std::vector workers_; + std::atomic is_stop_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + + const int worker_num_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/ooo_controller.cpp b/platform/consensus/ordering/fides/executor/manager/ooo_controller.cpp new file mode 100644 index 000000000..83f783e9b --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/ooo_controller.cpp @@ -0,0 +1,35 @@ +#include "service/contract/executor/manager/ooo_controller.h" + +#include + +namespace resdb { +namespace contract { + +OOOController::OOOController(DataStorage * storage) : ConcurrencyController(storage){ +} + +OOOController::~OOOController(){} + +void OOOController::PushCommit(int64_t commit_id, const ModifyMap& local_changes) { + for(const auto& it : local_changes){ + bool done = false; + for(int i = it.second.size()-1; i >=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + storage_->Store(it.first, op.data); + done = true; + break; + case REMOVE: + storage_->Remove(it.first); + done = true; + break; + } + } + } +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/ooo_controller.h b/platform/consensus/ordering/fides/executor/manager/ooo_controller.h new file mode 100644 index 000000000..172802738 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/ooo_controller.h @@ -0,0 +1,17 @@ +#pragma once + +#include "service/contract/executor/manager/concurrency_controller.h" + +namespace resdb { +namespace contract { + +class OOOController : public ConcurrencyController { + public: + OOOController(DataStorage * storage); + ~OOOController(); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes); +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/sequential_cc_controller.cpp b/platform/consensus/ordering/fides/executor/manager/sequential_cc_controller.cpp new file mode 100644 index 000000000..b24fd9d0a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/sequential_cc_controller.cpp @@ -0,0 +1,263 @@ +#include "service/contract/executor/manager/sequential_cc_controller.h" + +#include + +namespace resdb { +namespace contract { + +SequentialCCController::SequentialCCController(DataStorage * storage) : ConcurrencyController(storage){ + + for(int i = 0; i < window_size_; ++i){ + is_redo_.push_back(false); + } + + Clear(); + last_commit_id_ = 0; +} + +SequentialCCController::~SequentialCCController(){} + +void SequentialCCController::Clear(){ + last_commit_id_=0; + + changes_list_.resize(window_size_); + for(int i = 0; i < window_size_; ++i){ + changes_list_[i].clear(); + is_redo_[i] = false; + } + for(int i = 0; i < 1024; ++i){ + commit_list_[i].clear(); + } + m_list_.clear(); +} + +std::vector& SequentialCCController::GetRedo(){ + return redo_; +} + +int SequentialCCController::GetHashKey(const uint256_t& address){ + // Get big-endian form + uint8_t arr[32] = {}; + memset(arr,0,sizeof(arr)); + intx::be::store(arr, address); + uint32_t v = 0; + for(int i = 0; i < 32; ++i){ + v += arr[i]; + } + return v%128; +} + +void SequentialCCController::SetCallback(CallBack call_back) { + call_back_ = call_back; +} + +void SequentialCCController::RedoCommit(int64_t commit_id, int flag) { + if(is_redo_[commit_id]){ + return; + } + is_redo_[commit_id] = true; + redo_.push_back(commit_id); +} + +void SequentialCCController::PushCommit(int64_t commit_id, const ModifyMap& local_changes) { + if(commit_id<=last_commit_id_){ + //assert(!changes_list_[commit_id].empty()); + changes_list_[commit_id] = local_changes; + //assert(Commit(commit_id)); + return; + } + + { + changes_list_[commit_id] = local_changes; + /* + for(const auto& it : local_changes){ + int hash_idx = GetHashKey(it.first); + //LOG(ERROR)<<"address:"<last_commit_id_){ + const auto & local_changes = changes_list_[commit_id]; + for(const auto& it : local_changes){ + int hash_idx = GetHashKey(it.first); + //LOG(ERROR)<<"address:"< new_commit_ids; + for(const auto& it : change_set){ + bool done = false; + const uint256_t& address = it.first; + int64_t new_v = 0; + for(int i = it.second.size()-1; i >=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<Store(it.first, op.data); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first); + done = true; + break; + } + } + int64_t next_commit_id = Remove(address, commit_id, new_v); + //if(next_commit_id> 0){ + if(next_commit_id> 0 && next_commit_id <= last_commit_id_){ + new_commit_ids.insert(next_commit_id); + } + if(done && next_commit_id>last_commit_id_){ + if(IsRead(address, next_commit_id)){ + new_commit_ids.insert(next_commit_id); + } + } + } + Remove(commit_id); + for(int64_t redo_commit: new_commit_ids){ + RedoCommit(redo_commit, 1); + } + return true; +} + +bool SequentialCCController::CheckFirstCommit(const uint256_t& address, int64_t commit_id){ + int idx = GetHashKey(address); + //std::shared_lock lock(mutexs_[idx]); + //LOG(ERROR)<<"load idx:"<0); + + if(commit_set.front() < commit_id){ + //if(*commit_set.begin() < commit_id){ + // not the first candidate + //LOG(ERROR)<<"still have dep. commit id:"<GetVersion(address); + if(op.version != v){ + //LOG(ERROR)<<"check load:"< +#include +#include +#include + +#include "service/contract/executor/manager/concurrency_controller.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { + +class SequentialCCController : public ConcurrencyController { + public: + struct CallBack { + std::function redo_callback = nullptr; + std::function committed_callback = nullptr; + }; + + SequentialCCController(DataStorage * storage); + ~SequentialCCController(); + + void SetCallback(CallBack call_back); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_); + bool Commit(int64_t commit_id); + std::vector& GetRedo(); + + void Clear(); + + private: + bool CommitInternal(int64_t commit_id); + bool CheckCommit(int64_t commit_id); + bool CheckFirstCommit(const uint256_t& address, int64_t commit_id); + + const ModifyMap * GetChangeList(int64_t commit_id); + int64_t Remove(const uint256_t& address, int64_t commit_id, uint64_t v); + void Remove(int64_t commit_id); + + + std::function GetCommitCallBack(int64_t commit_id); + std::function GetRedoCallBack(int64_t commit_id); + + void CommitDone(int64_t commit_id); + void RedoCommit(int64_t commit_id, int flag); + + int GetHashKey(const uint256_t& address); + + bool IsRead(const uint256_t& address, int64_t commit_id); + + private: + const int window_size_ = 1000; + mutable std::shared_mutex mutex_, mutexs_[1024]; + + std::map first_commit_; + std::atomic last_commit_id_; + + std::vector changes_list_; + std::map > commit_list_[1024]; + //std::map > commit_list_[1024]; + std::map m_list_; + + std::vector is_redo_; + CallBack call_back_; + + std::vector redo_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/sequential_cc_controller_test.cpp b/platform/consensus/ordering/fides/executor/manager/sequential_cc_controller_test.cpp new file mode 100644 index 000000000..8ee81a035 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/sequential_cc_controller_test.cpp @@ -0,0 +1,1056 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/sequential_cc_controller.h" + +#include +#include +#include + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +void GetData(const std::string& addr, const DataStorage& storage, ConcurrencyController::ModifyMap& changes){ + changes[HexToInt(addr)].push_back(Data(LOAD,storage.Load(HexToInt(addr)).first, storage.Load(HexToInt(addr)).second)); +} + +void SetData(const std::string& addr, int value, ConcurrencyController::ModifyMap& changes){ + changes[HexToInt(addr)].push_back(Data(STORE, value)); +} + +TEST(ContractDagManagerTest, PushOneCommit) { + + std::promise done; + std::future done_future = done.get_future(); + + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t){ + LOG(ERROR)<<"committed"; + done.set_value(true); + }; + + int64_t commit_id = 1; + + DataStorage storage; + SequentialCCController controller(&storage); + controller.SetCallback(call_back); + + SequentialCCController::ModifyMap changes; + GetData("0x123", storage, changes); + SetData("0x124", 1000, changes); + + controller.PushCommit(commit_id, changes); + + done_future.get(); + EXPECT_EQ(storage.Load(HexToInt("0x123")).first, 0); + EXPECT_EQ(storage.Load(HexToInt("0x124")).first, 1000); +} + +TEST(ContractDagManagerTest, PushTwoOOOCommit) { + + std::promise done; + std::future done_future = done.get_future(); + + int committed_num = 0; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t){ + LOG(ERROR)<<"committed"; + committed_num++; + if(committed_num==2){ + done.set_value(true); + } + }; + + DataStorage storage; + SequentialCCController controller(&storage); + controller.SetCallback(call_back); + + { + int64_t commit_id = 2; + + + SequentialCCController::ModifyMap changes; + + SetData("0x123", 3000, changes); + SetData("0x124", 4000, changes); + + controller.PushCommit(commit_id, changes); + } + + { + int64_t commit_id = 1; + + SequentialCCController::ModifyMap changes; + SetData("0x123", 1000, changes); + SetData("0x124", 2000, changes); + + controller.PushCommit(commit_id, changes); + } + + done_future.get(); + EXPECT_EQ(storage.Load(HexToInt("0x123")).first, 3000); + EXPECT_EQ(storage.Load(HexToInt("0x124")).first, 4000); +} + +TEST(ContractDagManagerTest, PushTwoOOOCommitRAWBlock) { + + DataStorage storage; + SequentialCCController controller(&storage); + + std::promise done; + std::future done_future = done.get_future(); + + int committed1_done = 0,redo_num = 0; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + if(commit_id==1){ + committed1_done = 1; + } + }; + + call_back.redo_callback = [&](int64_t commit_id){ + EXPECT_EQ(commit_id, 2); + redo_num=1; + if(committed1_done==1&&redo_num==1){ + done.set_value(true); + } + LOG(ERROR)<<"redo:"< done; + std::future done_future = done.get_future(); + + int committed1_done = 0, committed2_done = 0,redo_num = 0; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + if(commit_id==1){ + committed1_done = 1; + } + if(commit_id==2){ + committed2_done = 1; + } + if(committed1_done==1&&committed2_done==1&&redo_num==1){ + done.set_value(true); + } + }; + + call_back.redo_callback = [&](int64_t commit_id){ + EXPECT_EQ(commit_id, 2); + redo_num=1; + LOG(ERROR)<<"redo:"< done; + std::future done_future = done.get_future(); + + int committed1_done = 0, committed2_done = 0,redo_num = 0; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + if(commit_id==1){ + committed1_done = 1; + } + if(commit_id==2){ + committed2_done = 1; + } + if(committed1_done==1&&committed2_done==1&&redo_num==1){ + done.set_value(true); + } + }; + + call_back.redo_callback = [&](int64_t commit_id){ + EXPECT_EQ(commit_id, 2); + redo_num=1; + LOG(ERROR)<<"redo:"< done; + std::future done_future = done.get_future(); + std::set done_list; + int redo_num = 0; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + done_list.insert(commit_id); + if(done_list.size()==3&&redo_num==1){ + done.set_value(true); + } + }; + + call_back.redo_callback = [&](int64_t commit_id){ + EXPECT_EQ(commit_id, 3); + redo_num=1; + LOG(ERROR)<<"redo:"< done; + std::future done_future = done.get_future(); + std::set done_list; + int redo_num = 0; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + LOG(ERROR)<<"commit:"< done; + std::future done_future = done.get_future(); + std::set done_list; + int redo_num = 0; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + done_list.insert(commit_id); + if(done_list.size()==3&&redo_num==2){ + done.set_value(true); + } + }; + + call_back.redo_callback = [&](int64_t commit_id){ + redo_num++; + LOG(ERROR)<<"redo:"< done; + std::future done_future = done.get_future(); + + int redo_num = 0; + std::set done_list; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + done_list.insert(commit_id); + if(done_list.size()==3&&redo_num==1){ + done.set_value(true); + } + }; + + call_back.redo_callback = [&](int64_t commit_id){ + EXPECT_EQ(commit_id, 2); + redo_num=1; + LOG(ERROR)<<"redo:"< done; + std::future done_future = done.get_future(); + + int redo_num = 0; + std::set done_list; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + done_list.insert(commit_id); + if(done_list.size()==3&&redo_num==2){ + done.set_value(true); + } + }; + + call_back.redo_callback = [&](int64_t commit_id){ + redo_num++; + LOG(ERROR)<<"redo:"< done; + std::future done_future = done.get_future(); + + int committed1_done = 0, committed2_done = 0,redo_num = 0; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + if(commit_id==1){ + committed1_done = 1; + } + if(commit_id==2){ + committed2_done = 1; + } + if(committed1_done==1&&committed2_done==1&&redo_num==0){ + done.set_value(true); + } + }; + + call_back.redo_callback = [&](int64_t commit_id){ + EXPECT_EQ(commit_id, 2); + redo_num=1; + LOG(ERROR)<<"redo:"< done; + std::future done_future = done.get_future(); + + int committed1_done = 0, committed2_done = 0,redo_num = 0; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + if(commit_id==1){ + committed1_done = 1; + } + if(commit_id==2){ + committed2_done = 1; + } + if(committed1_done==1&&committed2_done==1&&redo_num==0){ + done.set_value(true); + } + }; + + call_back.redo_callback = [&](int64_t commit_id){ + EXPECT_EQ(commit_id, 2); + redo_num=1; + LOG(ERROR)<<"redo:"< done; + std::future done_future = done.get_future(); + + int committed1_done = 0, committed2_done = 0,redo_num = 0; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + if(commit_id==1){ + committed1_done = 1; + } + if(commit_id==2){ + committed2_done = 1; + } + if(committed1_done==1&&committed2_done==1&&redo_num==0){ + done.set_value(true); + } + }; + + call_back.redo_callback = [&](int64_t commit_id){ + EXPECT_EQ(commit_id, 2); + redo_num=1; + LOG(ERROR)<<"redo:"< done; + std::future done_future = done.get_future(); + + int committed1_done = 0, committed2_done = 0,redo_num = 0; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + if(commit_id==1){ + committed1_done = 1; + } + if(commit_id==2){ + committed2_done = 1; + } + if(committed1_done==1&&committed2_done==1&&redo_num==0){ + done.set_value(true); + } + }; + + call_back.redo_callback = [&](int64_t commit_id){ + EXPECT_EQ(commit_id, 2); + redo_num=1; + LOG(ERROR)<<"redo:"< done; + std::future done_future = done.get_future(); + + int committed1_done = 0, committed2_done = 0, redo_num = 0; + SequentialCCController::CallBack call_back; + call_back.committed_callback = [&](int64_t commit_id){ + LOG(ERROR)<<"commit id ====:"<=1){ + done.set_value(true); + } + }; + + call_back.redo_callback = [&](int64_t commit_id){ + EXPECT_EQ(commit_id, 2); + redo_num=1; + LOG(ERROR)<<"redo:"< + +#include "service/contract/executor/manager/local_state.h" +#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { + +/* +ExecutionContext::ExecutionContext(const ContractExecuteInfo & info ) { + info_ = std::make_unique(info); +} + +const ContractExecuteInfo * ExecutionContext::GetContractExecuteInfo() const { + return info_.get(); +} + +void ExecutionContext::SetResult(std::unique_ptr result) { + result_ = std::move(result); +} + +bool ExecutionContext::IsRedo() { + return is_redo_; +} + +void ExecutionContext::SetRedo(){ + is_redo_ = true; +} + +std::unique_ptr ExecutionContext::FetchResult() { + return std::move(result_); +} +*/ + +ExecutionState * SequentialConcurrencyCommitter::GetExecutionState() { + return &execution_state_; +} + +SequentialConcurrencyCommitter:: SequentialConcurrencyCommitter( + DataStorage * storage, + GlobalState * global_state, int worker_num):storage_(storage), gs_(global_state),worker_num_(worker_num) { + + controller_ = std::make_unique(storage); + executor_ = std::make_unique(); + is_stop_ = false; + + SequentialCCController::CallBack callback; + callback.redo_callback = std::bind(&SequentialConcurrencyCommitter::RedoCallBack, this, std::placeholders::_1, std::placeholders::_2); + callback.committed_callback = std::bind(&SequentialConcurrencyCommitter::CommitCallBack, this,std::placeholders::_1); + + controller_->SetCallback(callback); + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request_ptr = request_queue_.Pop(); + if (request_ptr == nullptr) { + continue; + } + ExecutionContext * request = *request_ptr; + + LocalState local_state(controller_.get()); + local_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &local_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=1; + // request->SetResult(std::move(resp)); + } + local_state.Flesh(request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->commit_id); + } + else { + resp->ret = -1; + } + //if(!request->IsRedo()){ + resp_queue_.Push(std::move(resp)); + //} + } + })); + } +} + +SequentialConcurrencyCommitter::~SequentialConcurrencyCommitter(){ + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + +void SequentialConcurrencyCommitter::AddTask(int64_t commit_id, std::unique_ptr context){ + context_list_[commit_id] = std::move(context); +} + +void SequentialConcurrencyCommitter::RemoveTask(int64_t commit_id){ + context_list_.erase(context_list_.find(commit_id)); +} + +ExecutionContext* SequentialConcurrencyCommitter::GetTaskContext(int64_t commit_id){ + return context_list_[commit_id].get(); +} + +void SequentialConcurrencyCommitter::CommitCallBack(int64_t commit_id){ +} + +void SequentialConcurrencyCommitter::RedoCallBack(int64_t commit_id, int flag){ +} + +std::vector> SequentialConcurrencyCommitter::ExecContract( + std::vector& requests) { + + execution_state_.commit_time = 0; + execution_state_.redo_time = 0; + + int process_num = requests.size(); + std::vector> resp_list; + + std::set commits; + int id = 1; + resp_list.resize(process_num); + for(auto& request: requests) { + resp_list[id-1] = nullptr; + request.commit_id = id++; + auto context = std::make_unique(request); + AddTask(request.commit_id, std::move(context)); + commits.insert(request.commit_id); + } + + controller_->Clear(); + for(auto& request: requests) { + auto context_ptr = GetTaskContext(request.commit_id); + request_queue_.Push(std::make_unique(context_ptr)); + } + + auto cur_it = commits.begin(); + std::queue redo_list; + while(process_num){ + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + int64_t resp_commit_id = resp->commit_id; + //LOG(ERROR)<<"recv :"<commit_id-1]=std::move(resp); + if(cur_it == commits.end() || resp_commit_id < *cur_it){ + bool ret = controller_->Commit(resp_commit_id); + std::vector list = controller_->GetRedo(); + for(int64_t next_id : list){ + bool ret = controller_->Commit(next_id); + if(!ret){ + //redo_list.push(next_id); + auto context_ptr = GetTaskContext(next_id); + context_ptr->SetRedo(); + request_queue_.Push(std::make_unique(context_ptr)); + } + } + assert(ret); + process_num--; + } + while(cur_it != commits.end() && resp_list[*cur_it-1] !=nullptr){ + int64_t commit_id = *cur_it; + bool ret = controller_->Commit(commit_id); + cur_it++; + if(!ret){ + resp_list[commit_id-1]=nullptr; + if(controller_->GetRedo().size()){ + //redo_list.push(commit_id); + + auto context_ptr = GetTaskContext(commit_id); + context_ptr->SetRedo(); + request_queue_.Push(std::make_unique(context_ptr)); + } + } + else { + process_num--; + std::vector list = controller_->GetRedo(); + for(int64_t next_id : list){ + resp_list[next_id-1]=nullptr; + //redo_list.push(next_id); + auto context_ptr = GetTaskContext(next_id); + context_ptr->SetRedo(); + request_queue_.Push(std::make_unique(context_ptr)); + } + } + } + } + + for(auto& request: requests) { + RemoveTask(request.commit_id); + } + + storage_->Flush(); + + return resp_list; +} + +absl::StatusOr SequentialConcurrencyCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/sequential_concurrency_committer.h b/platform/consensus/ordering/fides/executor/manager/sequential_concurrency_committer.h new file mode 100644 index 000000000..640993f25 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/sequential_concurrency_committer.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/sequential_cc_controller.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/committer_context.h" +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/common/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { + +/* +class ExecutionContext { +public: + ExecutionContext(const ContractExecuteInfo & info ) ; + const ContractExecuteInfo * GetContractExecuteInfo() const; + + void SetRedo(); + bool IsRedo(); + + void SetResult(std::unique_ptr result); + std::unique_ptr FetchResult(); + + private: + bool is_redo_ = false; + std::unique_ptr result_; + std::unique_ptr info_; +}; +*/ + + +struct ExecutionState{ + std::atomic commit_time; + int redo_time = 0; +}; + +class SequentialConcurrencyCommitter : public ContractCommitter { + public: + SequentialConcurrencyCommitter( + DataStorage * storage, + GlobalState * global_state, int worker_num = 2); + + ~SequentialConcurrencyCommitter(); + + std::vector> ExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + ExecutionState * GetExecutionState(); + +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + ExecutionContext* GetTaskContext(int64_t commit_id); + + void CommitCallBack(int64_t commit_id); + void RedoCallBack(int64_t commit_id, int flag); + + private: + std::unique_ptr controller_; + std::unique_ptr executor_; + DataStorage * storage_; + GlobalState* gs_; + std::vector workers_; + std::atomic is_stop_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + + std::map> context_list_; + + const int worker_num_; + ExecutionState execution_state_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/sequential_concurrency_committer_test.cpp b/platform/consensus/ordering/fides/executor/manager/sequential_concurrency_committer_test.cpp new file mode 100644 index 000000000..723c2c754 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/sequential_concurrency_committer_test.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/sequential_concurrency_committer.h" + +#include + +#include "service/contract/executor/manager/mock_data_storage.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/contract_deployer.h" +#include "service/contract/executor/manager/address_manager.h" +#include "service/contract/proto/func_params.pb.h" + +#include +#include + + + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; +using ::testing::Invoke; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +class SequentialConcurrencyCommitterTest : public Test { + public: + SequentialConcurrencyCommitterTest() : owner_address_(get_random_address()) { + std::string contract_path = test_dir + "test_data/contract.json"; + + std::ifstream contract_fstream(contract_path); + if (!contract_fstream) { + throw std::runtime_error(fmt::format( + "Unable to open contract definition file {}", contract_path)); + } + + const auto contracts_definition = nlohmann::json::parse(contract_fstream); + const auto all_contracts = contracts_definition["contracts"]; + const auto contract_code = all_contracts["ERC20.sol:ERC20Token"]; + storage_ = std::make_unique(); + contract_json_ = contract_code; + + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address) { + return data_[address]; + })); + + EXPECT_CALL(*storage_, Store).WillRepeatedly(Invoke([&](const uint256_t& key, const uint256_t& value) { + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + })); + + EXPECT_CALL(*storage_, GetVersion).WillRepeatedly(Invoke([&](const uint256_t& key) { + return data_[key].second; + })); + + Init(); + } + + void Init() { + gs_ = std::make_unique(storage_.get()); + + committer_ = std::make_unique(storage_.get(), gs_.get()); + + contract_address_ = AddressManager::CreateContractAddress(owner_address_); + deployer_ = std::make_unique(committer_.get(), gs_.get()); + contract_address_ = deployer_->DeployContract(owner_address_, contract_json_, {1000}); + } + + std::vector> ExecContract(std::vector& execute_info) { + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i+1; + } + return committer_->ExecContract(execute_info); + } + + protected: + Address owner_address_; + Address contract_address_; + nlohmann::json contract_json_; + std::unique_ptr storage_; + std::unique_ptr gs_; + std::unique_ptrcommitter_; + std::map> data_; + std::unique_ptr deployer_; +}; + +TEST_F(SequentialConcurrencyCommitterTest, ExecContract) { + // owner 1000 + std::vector info; + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + std::vector> resp = ExecContract(info); + EXPECT_EQ(resp.size(), 1); + EXPECT_EQ(resp[0]->ret, 0); + } +} + +// get a +// a->b +TEST_F(SequentialConcurrencyCommitterTest, TwoTxnNoConflict) { + Address transfer_receiver = get_random_address(); + + // owner 1000 + std::vector info; + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + std::vector> resp = ExecContract(info); + EXPECT_EQ(resp.size(), 2); + EXPECT_EQ(resp[0]->ret, 0); + EXPECT_EQ(HexToInt(resp[0]->result), 1000); + EXPECT_EQ(resp[1]->ret, 0); + EXPECT_EQ(HexToInt(resp[1]->result), 1); + } + //LOG(ERROR)<<"commit time:"<GetExecutionState()->commit_time<<" redo time:"<GetExecutionState()->redo_time; + EXPECT_EQ(committer_->GetExecutionState()->commit_time,2); + EXPECT_EQ(committer_->GetExecutionState()->redo_time,0); +} + +// a->b +// a->b +TEST_F(SequentialConcurrencyCommitterTest, TwoTxnConflict) { + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address) { + if(start){ + load_time[address]++; + } + return data_[address]; + })); + + EXPECT_CALL(*storage_, Store).WillRepeatedly(Invoke([&](const uint256_t& key, const uint256_t& value) { + if(start) { + bool done = false; + while(!done){ + for(auto it : load_time){ + if(it.second>1){ + done = true; + break; + } + } + } + } + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + })); + + Init(); + start = true; + + // owner 1000 + std::vector info; + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + std::vector> resp = ExecContract(info); + EXPECT_EQ(resp.size(), 2); + EXPECT_EQ(resp[0]->ret, 0); + EXPECT_EQ(HexToInt(resp[0]->result), 1); + EXPECT_EQ(resp[1]->ret, 0); + EXPECT_EQ(HexToInt(resp[1]->result), 1); + } + EXPECT_EQ(committer_->GetExecutionState()->commit_time,2); + EXPECT_EQ(committer_->GetExecutionState()->redo_time,1); +} + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/streaming_committer.cpp b/platform/consensus/ordering/fides/executor/manager/streaming_committer.cpp new file mode 100644 index 000000000..55d0bf9a0 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/streaming_committer.cpp @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/streaming_committer.h" + +#include +#include + +#include "service/contract/executor/manager/local_state.h" +#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + + +namespace resdb { +namespace contract { +namespace streaming { + +ExecutionContext::ExecutionContext(const ContractExecuteInfo & info ) { + info_ = std::make_unique(info); +} + +const ContractExecuteInfo * ExecutionContext::GetContractExecuteInfo() const { + return info_.get(); +} + +void ExecutionContext::SetResult(std::unique_ptr result) { + result_ = std::move(result); +} + +bool ExecutionContext::IsRedo() { + return is_redo_; +} + +void ExecutionContext::SetRedo(){ + is_redo_++; +} + +int ExecutionContext::RedoTime() { + return is_redo_; +} + +std::unique_ptr ExecutionContext::FetchResult() { + return std::move(result_); +} + +ExecutionState * StreamingCommitter::GetExecutionState() { + return &execution_state_; +} + +StreamingCommitter:: StreamingCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back, + int worker_num):storage_(storage), gs_(global_state), + worker_num_(worker_num), + window_size_(window_size), + call_back_(call_back) { + + controller_ = std::make_unique(storage, window_size*2); + executor_ = std::make_unique(); + + resp_list_.resize(window_size_); + is_done_.resize(window_size_); + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + first_id_ = 0; + last_id_ = 1; + is_stop_ = false; + id_ = 1; + + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request_ptr = request_queue_.Pop(); + if (request_ptr == nullptr) { + continue; + } + ExecutionContext * request = *request_ptr; + + LocalState local_state(controller_.get()); + local_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &local_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + //LOG(ERROR)<<"========= get resp commit id:"<GetContractExecuteInfo()->commit_id<<" param:"<< + // request->GetContractExecuteInfo()->func_params.DebugString(); + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=request->RedoTime(); + // request->SetResult(std::move(resp)); + } + local_state.Flesh(request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->commit_id); + } + else { + LOG(ERROR)<<"commit :"<commit_id<<" fail"; + resp->ret = -1; + assert(resp->ret>=0); + } + resp_queue_.Push(std::move(resp)); + } + })); + } + + response_ = std::thread([&]() { + while (!is_stop_) { + ResponseProcess(); + } + }); +} + +void StreamingCommitter::SetExecuteCallBack(std::function)> func) { + call_back_ = std::move(func); +} + +StreamingCommitter::~StreamingCommitter(){ + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } + if(response_.joinable()){ + response_.join(); + } +} + +void StreamingCommitter::AddTask(int64_t commit_id, std::unique_ptr context){ + context_list_[commit_id%window_size_] = std::move(context); +} + +void StreamingCommitter::RemoveTask(int64_t commit_id){ + context_list_.erase(context_list_.find(commit_id)); +} + +ExecutionContext* StreamingCommitter::GetTaskContext(int64_t commit_id){ + return context_list_[commit_id%window_size_].get(); +} + +void StreamingCommitter::CallBack(uint64_t commit_id){ + int idx = commit_id%window_size_; + if(call_back_){ + call_back_(std::move(resp_list_[idx])); + } + else { + resp_list_[idx] = nullptr; + } + is_done_[idx] = true; + + //LOG(ERROR)<<"current commit done call back commit id:"< lk(mutex_); + cv_.notify_all(); + } + //LOG(ERROR)<<"call back done:"< lk(mutex_); + cv_.wait_for(lk, std::chrono::microseconds(timeout_ms), [&] { + return id_ - first_id_ lk(mutex_); + cv_.wait_for(lk, std::chrono::microseconds(timeout_ms), [&] { + return first_id_>0&&first_id_%500==0; + //return id_ - first_id_commit_id; + int idx = resp->commit_id % window_size_; + //LOG(ERROR)<<"recv :"< q; + q.push(resp_commit_id); + while(!q.empty()){ + int64_t next_id = q.front(); + q.pop(); + + //LOG(ERROR)<<"!!!!!! commit retry:"<Commit(next_id); + if(!ret){ + //LOG(ERROR)<<"retry:"<SetRedo(); + request_queue_.Push(std::make_unique(context_ptr)); + } + else { + CallBack(next_id); + } + std::vector next_commit = controller_->GetRedo(); + for(int64_t new_next : next_commit) { + if(next_id == new_next){ + continue; + } + q.push(new_next); + //LOG(ERROR)<<"get retry next:"<commit_id; + //LOG(ERROR)<<" !!!!! commit new resp:"<Commit(current_commit_id); + if(!ret){ + //LOG(ERROR)<<"redo size:"<GetRedo().size(); + if(controller_->GetRedo().size()){ + assert(controller_->GetRedo()[0] == current_commit_id); + //redo_list.push(commit_id); + //LOG(ERROR)<<"commit redo:"<SetRedo(); + request_queue_.Push(std::make_unique(context_ptr)); + } + } + else { + std::vector list = controller_->GetRedo(); + assert(list.empty()); + //LOG(ERROR)<<"commit done:"<SetRedo(); + request_queue_.Push(std::make_unique(context_ptr)); + } + CallBack(current_commit_id); + } + last_id_++; + } +} + +void StreamingCommitter::AsyncExecContract(std::vector& requests) { + for(auto& request: requests) { + if(!WaitNext()){ + return; + } + + int cur_idx = id_%window_size_; + assert(id_>=last_id_); + + request.commit_id = id_++; + auto context = std::make_unique(request); + auto context_ptr = context.get(); + + //LOG(ERROR)<<"execute:"<(context_ptr)); + } + + return ; +} + +absl::StatusOr StreamingCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/streaming_committer.h b/platform/consensus/ordering/fides/executor/manager/streaming_committer.h new file mode 100644 index 000000000..d17ab010a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/streaming_committer.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/streaming_controller.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/common/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace streaming { + +class ExecutionContext { +public: + ExecutionContext(const ContractExecuteInfo & info ); + const ContractExecuteInfo * GetContractExecuteInfo() const; + + void SetRedo(); + bool IsRedo(); + int RedoTime(); + + void SetResult(std::unique_ptr result); + std::unique_ptr FetchResult(); + + private: + int is_redo_ = 0; + std::unique_ptr result_; + std::unique_ptr info_; +}; + + +struct ExecutionState{ + std::atomic commit_time; + int redo_time = 0; +}; + +class StreamingCommitter : public ContractCommitter { + public: + StreamingCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back = nullptr, + int worker_num = 2); + + ~StreamingCommitter(); + + void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + ExecutionState * GetExecutionState(); + + std::vector> ExecContract(std::vector& execute_info) { return {}; } +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + + void CallBack(uint64_t commit_id); + + private: + std::unique_ptr controller_; + std::unique_ptr executor_; + DataStorage * storage_; + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::atomic first_id_, last_id_, id_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + std::vector> resp_list_; + std::vector is_done_; + + std::map> context_list_; + + const int worker_num_; + int window_size_; + ExecutionState execution_state_; + std::function)> call_back_; + std::condition_variable cv_; + std::mutex mutex_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/streaming_controller.cpp b/platform/consensus/ordering/fides/executor/manager/streaming_controller.cpp new file mode 100644 index 000000000..d9d789eaf --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/streaming_controller.cpp @@ -0,0 +1,228 @@ +#include "service/contract/executor/manager/streaming_controller.h" + +#include + +namespace resdb { +namespace contract { +namespace streaming { + +StreamingController::StreamingController(DataStorage * storage, int window_size) : + ConcurrencyController(storage), window_size_(window_size){ + Clear(); + last_commit_id_ = 0; +} + +StreamingController::~StreamingController(){} + +void StreamingController::Clear(){ + last_commit_id_=0; + + is_redo_.resize(window_size_); + changes_list_.resize(window_size_); + for(int i = 0; i < window_size_; ++i){ + changes_list_[i].clear(); + is_redo_[i] = false; + } + + for(int i = 0; i < 1024; ++i){ + commit_list_[i].clear(); + } + m_list_.clear(); +} + +std::vector& StreamingController::GetRedo(){ + return redo_; +} + +int StreamingController::GetHashKey(const uint256_t& address){ + // Get big-endian form + uint8_t arr[32] = {}; + memset(arr,0,sizeof(arr)); + intx::be::store(arr, address); + uint32_t v = 0; + for(int i = 0; i < 32; ++i){ + v += arr[i]; + } + return v%128; +} + +void StreamingController::RedoCommit(int64_t commit_id, int flag) { + if(is_redo_[commit_id%window_size_]){ + return; + } + is_redo_[commit_id%window_size_] = true; + redo_.push_back(commit_id); +} + +void StreamingController::PushCommit(int64_t commit_id, const ModifyMap& local_changes) { + //LOG(ERROR)<<"push commit:"<last_commit_id_){ + const auto & local_changes = changes_list_[commit_id%window_size_]; + for(const auto& it : local_changes){ + int hash_idx = GetHashKey(it.first); + auto& commit_set = commit_list_[hash_idx][it.first]; + commit_set.push_back(commit_id); + } + } + + redo_.clear(); + bool ret = CommitInternal(commit_id); + if(commit_id == last_commit_id_+1){ + last_commit_id_++; + } + return ret; +} + +bool StreamingController::CommitInternal(int64_t commit_id){ + if(!CheckCommit(commit_id)){ + //LOG(ERROR)<<"check commit fail:"< new_commit_ids; + for(const auto& it : change_set){ + bool done = false; + const uint256_t& address = it.first; + int64_t new_v = 0; + for(int i = it.second.size()-1; i >=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<Store(it.first, op.data); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first); + done = true; + break; + } + } + int64_t next_commit_id = Remove(address, commit_id, new_v); + //if(next_commit_id> 0){ + if(next_commit_id> 0 && next_commit_id <= last_commit_id_){ + new_commit_ids.insert(next_commit_id); + } + if(done && next_commit_id>last_commit_id_){ + if(IsRead(address, next_commit_id)){ + new_commit_ids.insert(next_commit_id); + } + } + } + Remove(commit_id); + for(int64_t redo_commit: new_commit_ids){ + RedoCommit(redo_commit, 1); + } + return true; +} + +bool StreamingController::CheckFirstCommit(const uint256_t& address, int64_t commit_id){ + int idx = GetHashKey(address); + //std::shared_lock lock(mutexs_[idx]); + //LOG(ERROR)<<"load idx:"<0); + + if(commit_set.front() < commit_id){ + //if(*commit_set.begin() < commit_id){ + // not the first candidate + //LOG(ERROR)<<"still have dep. commit id:"<GetVersion(address); + if(op.version != v){ + //LOG(ERROR)<<"check load:"< +#include +#include +#include + +#include "service/contract/executor/manager/concurrency_controller.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace streaming { + +class StreamingController : public ConcurrencyController { + public: + StreamingController(DataStorage * storage, int window_size); + ~StreamingController(); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_); + bool Commit(int64_t commit_id); + std::vector& GetRedo(); + + void Clear(); + + private: + bool CommitInternal(int64_t commit_id); + bool CheckCommit(int64_t commit_id); + bool CheckFirstCommit(const uint256_t& address, int64_t commit_id); + + const ModifyMap * GetChangeList(int64_t commit_id); + int64_t Remove(const uint256_t& address, int64_t commit_id, uint64_t v); + void Remove(int64_t commit_id); + + + std::function GetCommitCallBack(int64_t commit_id); + std::function GetRedoCallBack(int64_t commit_id); + + void CommitDone(int64_t commit_id); + void RedoCommit(int64_t commit_id, int flag); + + int GetHashKey(const uint256_t& address); + + bool IsRead(const uint256_t& address, int64_t commit_id); + + private: + const int window_size_ = 1000; + std::atomic last_commit_id_; + + std::vector changes_list_; + std::map > commit_list_[1024]; + //std::map > commit_list_[1024]; + std::map m_list_; + + std::vector is_redo_; + + std::vector redo_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/streaming_dq_committer.cpp b/platform/consensus/ordering/fides/executor/manager/streaming_dq_committer.cpp new file mode 100644 index 000000000..efa85f602 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/streaming_dq_committer.cpp @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/streaming_dq_committer.h" + +#include +#include + +#include "service/contract/executor/manager/local_state.h" +#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + + +namespace resdb { +namespace contract { +namespace streaming { + +namespace { +class TimeTrack { +public: + TimeTrack(std::string name = ""){ + name_ = name; + start_time_ = GetCurrentTime(); + } + + ~TimeTrack(){ + uint64_t end_time = GetCurrentTime(); + //LOG(ERROR) << name_ <<" run:" << (end_time - start_time_)<<"ms"; + } + + double GetRunTime(){ + uint64_t end_time = GetCurrentTime(); + return (end_time - start_time_) / 1000000.0; + } +private: + std::string name_; + uint64_t start_time_; +}; +} + +StreamingDQCommitter:: StreamingDQCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back, + int worker_num):storage_(storage), gs_(global_state), + worker_num_(worker_num), + window_size_(window_size), + call_back_(call_back) { + + //LOG(ERROR)<<"init window:"<(storage, window_size*2); + executor_ = std::make_unique(); + + resp_list_.resize(window_size_); + is_done_.resize(window_size_); + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + first_id_ = 0; + last_id_ = 1; + is_stop_ = false; + id_ = 1; + + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request_ptr = request_queue_.Pop(); + if (request_ptr == nullptr) { + continue; + } + ExecutionContext * request = *request_ptr; + + TimeTrack track; + LocalState local_state(controller_.get()); + local_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id); + + //LOG(ERROR)<<"========= start resp commit id:"<GetContractExecuteInfo()->commit_id; + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &local_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + //LOG(ERROR)<<"========= get resp commit id:"<GetContractExecuteInfo()->commit_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=request->RedoTime(); + } + local_state.Flesh(request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->commit_id); + resp->runtime = track.GetRunTime()*1000; + //LOG(ERROR)<<"retry:"<retry_time<<" run:"<runtime; + //LOG(ERROR)<<"run time:"<runtime; + } + else { + LOG(ERROR)<<"commit :"<commit_id<<" fail"; + resp->ret = -1; + assert(resp->ret>=0); + } + resp_queue_.Push(std::move(resp)); + } + })); + cpu_set_t cpu_s; + CPU_ZERO(&cpu_s); + CPU_SET(i, &cpu_s); + int rc = pthread_setaffinity_np(workers_[i].native_handle(), sizeof(cpu_s), &cpu_s); + assert(rc==0); + } + + response_ = std::thread([&]() { + while (!is_stop_) { + ResponseProcess(); + } + }); +} + +void StreamingDQCommitter::SetExecuteCallBack(std::function)> func) { + call_back_ = std::move(func); +} + +StreamingDQCommitter::~StreamingDQCommitter(){ + //LOG(ERROR)<<"desp"; + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } + if(response_.joinable()){ + response_.join(); + } +} + +void StreamingDQCommitter::AddTask(int64_t commit_id, std::unique_ptr context){ + context_list_[commit_id%window_size_] = std::move(context); +} + +void StreamingDQCommitter::RemoveTask(int64_t commit_id){ + context_list_.erase(context_list_.find(commit_id)); +} + +ExecutionContext* StreamingDQCommitter::GetTaskContext(int64_t commit_id){ + return context_list_[commit_id%window_size_].get(); +} + +void StreamingDQCommitter::Clear(){ + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + first_id_ = 0; + last_id_ = 1; + id_ = 1; +} + +void StreamingDQCommitter::CallBack(uint64_t commit_id){ + int idx = commit_id%window_size_; + //LOG(ERROR)<<"call back:"<retry_time; + if(call_back_){ + call_back_(std::move(resp_list_[idx])); + } + else { + resp_list_[idx] = nullptr; + } + is_done_[idx] = true; + + //LOG(ERROR)<<"current commit done call back commit id:"< lk(mutex_); + cv_.notify_all(); + } + //LOG(ERROR)<<"call back done:"< lk(mutex_); + cv_.wait_for(lk, std::chrono::microseconds(timeout_ms), [&] { + return id_ - first_id_ lk(mutex_); + cv_.wait_for(lk, std::chrono::microseconds(timeout_ms), [&] { + return first_id_>0&&first_id_%500==0; + //return id_ - first_id_commit_id; + int idx = resp->commit_id % window_size_; + //LOG(ERROR)<<"recv :"< q; + q.push(resp_commit_id); + while(!q.empty()){ + int64_t next_id = q.front(); + q.pop(); + + bool ret = controller_->Commit(next_id); + std::vector next_commit = controller_->GetRedo(); + //LOG(ERROR)<<"redo size:"<SetRedo(); + controller_->Clear(new_next); + //LOG(ERROR)<<"redo :"<(context_ptr)); + } + else { + q.push(new_next); + } + } + + std::vector done_list = controller_->GetDone(); + for(int64_t done_id : done_list) { + //LOG(ERROR)<<"get doen id:"<commit_id; + //LOG(ERROR)<<" !!!!! commit new resp:"<Commit(current_commit_id); + if(!ret){ + //LOG(ERROR)<<"redo size:"<GetRedo().size(); + if(controller_->GetRedo().size()){ + assert(controller_->GetRedo()[0] == current_commit_id); + //redo_list.push(commit_id); + //LOG(ERROR)<<"commit redo:"<SetRedo(); + controller_->Clear(current_commit_id); + //LOG(ERROR)<<"redo :"<(context_ptr)); + } + } + else { + std::vector list = controller_->GetRedo(); + for(int nd : list){ + //redo_list.push(commit_id); + //LOG(ERROR)<<"commit redo:"<SetRedo(); + controller_->Clear(nd); + //LOG(ERROR)<<"redo :"<(context_ptr)); + } + } + + std::vector done_list = controller_->GetDone(); + for(int64_t done_id : done_list) { + //LOG(ERROR)<<"get doen id:"<& requests) { + Clear(); + controller_->Clear(); + + for(auto& request: requests) { + if(!WaitNext()){ + return; + } + int cur_idx = id_%window_size_; + assert(id_>=last_id_); + + request.commit_id = id_++; + auto context = std::make_unique(request); + auto context_ptr = context.get(); + + //LOG(ERROR)<<"execute:"<(context_ptr)); + } + + return ; +} + +absl::StatusOr StreamingDQCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/streaming_dq_committer.h b/platform/consensus/ordering/fides/executor/manager/streaming_dq_committer.h new file mode 100644 index 000000000..f4eba1011 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/streaming_dq_committer.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/streaming_dq_controller.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/manager/committer_context.h" +#include "service/contract/executor/common/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace streaming { + +class StreamingDQCommitter : public ContractCommitter { + public: + StreamingDQCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back = nullptr, + int worker_num = 2); + + ~StreamingDQCommitter(); + + void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info) { return {}; } +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + + void CallBack(uint64_t commit_id); + void Clear(); + + private: + std::unique_ptr controller_; + std::unique_ptr executor_; + DataStorage * storage_; + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::atomic first_id_, last_id_, id_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + std::vector> resp_list_; + std::vector is_done_; + + std::map> context_list_; + + const int worker_num_; + int window_size_; + std::function)> call_back_; + std::condition_variable cv_; + std::mutex mutex_; + std::atomic num_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/streaming_dq_committer_test.cpp b/platform/consensus/ordering/fides/executor/manager/streaming_dq_committer_test.cpp new file mode 100644 index 000000000..39f49818a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/streaming_dq_committer_test.cpp @@ -0,0 +1,1100 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/streaming_dq_committer.h" + +#include + +#include "service/contract/executor/manager/mock_d_storage.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/contract_deployer.h" +#include "service/contract/executor/manager/address_manager.h" +#include "service/contract/proto/func_params.pb.h" + +#include +#include + + + +namespace resdb { +namespace contract { +namespace streaming { +namespace { + +using ::testing::Test; +using ::testing::Invoke; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +class StreamingDQCommitterTest : public Test { + public: + StreamingDQCommitterTest() : owner_address_(get_random_address()) { + std::string contract_path = test_dir + "test_data/kv.json"; + + std::ifstream contract_fstream(contract_path); + if (!contract_fstream) { + throw std::runtime_error(fmt::format( + "Unable to open contract definition file {}", contract_path)); + } + + const auto contracts_definition = nlohmann::json::parse(contract_fstream); + const auto all_contracts = contracts_definition["contracts"]; + const auto contract_code = all_contracts["kv.sol:KV"]; + storage_ = std::make_unique(); + contract_json_ = contract_code; + + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + if(data_.find(address) == data_.end()){ + data_[address] = g_data_[address]; + } + auto ret = is_local? data_[address]: g_data_[address]; + LOG(ERROR)<<"load:"<(storage_.get()); + + committer_ = std::make_unique(storage_.get(), gs_.get(), 10); + + contract_address_ = AddressManager::CreateContractAddress(owner_address_); + deployer_ = std::make_unique(committer_.get(), gs_.get()); + contract_address_ = deployer_->DeployContract(owner_address_, contract_json_, {1000}); + } + + void ExecContract(std::vector& execute_info) { + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i+1; + } + committer_->AsyncExecContract(execute_info); + } + + protected: + Address owner_address_; + Address contract_address_; + nlohmann::json contract_json_; + std::unique_ptr storage_; + std::unique_ptr gs_; + std::unique_ptrcommitter_; + std::map> data_, g_data_; + std::unique_ptr deployer_; +}; + +TEST_F(StreamingDQCommitterTest, ExecContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + { + Params func_params; + func_params.set_func_name("get(address)"); + func_params.add_param(U256ToString(owner_address_)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done.set_value(true); + }); + + { + ExecContract(info); + } + done_future.get(); +} + + +TEST_F(StreamingDQCommitterTest, ExecNoConflictContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==2){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); +} + +TEST_F(StreamingDQCommitterTest, ExecConflictContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + LOG(ERROR)<<"load add:"<1){ + done = true; + break; + } + } + } + } + + if(is_local){ + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + } + else { + int v = g_data_[key].second; + g_data_[key] = std::make_pair(value, v+1); + } + return 1; + })); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==2){ + done.set_value(true); + } + }); + + start = true; + { + ExecContract(info); + } + done_future.get(); +} + +TEST_F(StreamingDQCommitterTest, ExecConflictContractAhead2) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + LOG(ERROR)<<"load add:"<1){ + done = true; + break; + } + } + } + } + + if(is_local){ + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + } + else { + int v = g_data_[key].second; + g_data_[key] = std::make_pair(value, v+1); + } + return 1; + })); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("get(address)"); + func_params.add_param(U256ToString(transfer_receiver3)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + start = true; + { + ExecContract(info); + } + done_future.get(); +} + +TEST_F(StreamingDQCommitterTest, ExecConflictContractAhead) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + if(is_local){ + if(data_.find(address) == data_.end()){ + data_[address] = g_data_[address]; + } + } + if(is_local){ + load_time[address]++; + } + auto ret = is_local? data_[address]: g_data_[address]; + LOG(ERROR)<<"load add:"<1){ + done = true; + break; + } + } + } + } + + if(is_local){ + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + } + else { + int v = g_data_[key].second; + g_data_[key] = std::make_pair(value, v+1); + } + return 1; + })); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver3)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + start = true; + { + ExecContract(info); + } + done_future.get(); +} + +TEST_F(StreamingDQCommitterTest, ExecConflictPreCommitContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + if(is_local){ + if(data_.find(address) == data_.end()){ + data_[address] = g_data_[address]; + } + } + if(is_local){ + load_time[address]++; + } + auto ret = is_local? data_[address]: g_data_[address]; + LOG(ERROR)<<"load add:"<1){ + done = true; + break; + } + } + } + } + + if(is_local){ + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + } + else { + int v = g_data_[key].second; + g_data_[key] = std::make_pair(value, v+1); + } + return 1; + })); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + start = true; + { + ExecContract(info); + } + done_future.get(); +} + +TEST_F(StreamingDQCommitterTest, ExecConflictPreCommitContract2) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + if(is_local){ + if(data_.find(address) == data_.end()){ + data_[address] = g_data_[address]; + } + } + if(is_local){ + load_time[address]++; + } + auto ret = is_local? data_[address]: g_data_[address]; + LOG(ERROR)<<"load add:"<1){ + done = true; + break; + } + } + } + } + + if(is_local){ + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + } + else { + int v = g_data_[key].second; + g_data_[key] = std::make_pair(value, v+1); + } + return 1; + })); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + start = true; + { + ExecContract(info); + } + done_future.get(); +} + +TEST_F(StreamingDQCommitterTest, ExecConflictCommitContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + if(is_local){ + if(data_.find(address) == data_.end()){ + data_[address] = g_data_[address]; + } + } + if(is_local){ + load_time[address]++; + } + auto ret = is_local? data_[address]: g_data_[address]; + LOG(ERROR)<<"load add:"<1){ + done = true; + break; + } + } + } + } + + if(is_local){ + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + } + else { + int v = g_data_[key].second; + g_data_[key] = std::make_pair(value, v+1); + } + return 1; + })); + + EXPECT_CALL(*storage_, Reset).WillRepeatedly(Invoke([&](const uint256_t& key, const uint256_t& value, int64_t version, bool is_local) { + LOG(ERROR)<<"reset key:"< done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + start = true; + { + ExecContract(info); + } + done_future.get(); +} + + +TEST_F(StreamingDQCommitterTest, ExecConflictCommitContract2) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + + bool start = false; + int store_time = 0; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + if(is_local){ + if(data_.find(address) == data_.end()){ + data_[address] = g_data_[address]; + } + } + if(address==owner_key){ + //if(address==HexToInt("57815374765124470849362214049032306256895895577454318163812448629066198159199")){ + if(is_local){ + LOG(ERROR)<<" ==================== load store time:"< done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"!!!!! get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==6){ + done.set_value(true); + } + }); + + start = true; + { + ExecContract(info); + } + done_future.get(); + +/* + uint256_t owner_key = HexToInt("57815374765124470849362214049032306256895895577454318163812448629066198159199"); + uint256_t transfer = HexToInt("27068505347551469483271880684020111790651525950042222728557705477772470047978"); + uint256_t transfer2 = HexToInt("78596659736029077736286538721783748383020833717077044719314309740706971846630"); + uint256_t transfer3 = HexToInt("4045740438897326892663995084801035374080699693195822287106415777594567914589"); + + EXPECT_EQ(g_data_[owner_key].first, HexToInt("400")); + EXPECT_EQ(g_data_[transfer].first, HexToInt("1000")); + EXPECT_EQ(g_data_[transfer2].first, HexToInt("300")); + EXPECT_EQ(g_data_[transfer3].first, HexToInt("800")); + + for(auto& key : g_data_){ + LOG(ERROR)<<"key:"< done; + std::future done_future = done.get_future(); + std::vector info; + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + + bool start = false; + int store_time = 0; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + if(is_local){ + if(data_.find(address) == data_.end()){ + data_[address] = g_data_[address]; + } + } + if(address==owner_key){ + //if(address==HexToInt("57815374765124470849362214049032306256895895577454318163812448629066198159199")){ + if(is_local){ + LOG(ERROR)<<" ==================== load store time:"<2){ + while(store_time<9){ + sleep(1); + LOG(ERROR)<<" ==================== load store time:"< done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"!!!!! get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==6){ + done.set_value(true); + } + }); + + start = true; + { + ExecContract(info); + } + done_future.get(); + +/* + LOG(ERROR)<<"owner:"< +#include +#include + +//#define CDebug + +namespace resdb { +namespace contract { +namespace streaming { + +StreamingDQController::StreamingDQController(DataStorage * storage, int window_size) : + ConcurrencyController(storage), window_size_(window_size), storage_(storage){ + //ConcurrencyController(storage), window_size_(window_size), storage_(static_cast(storage)){ + for(int i = 0; i < 32; i++){ + if((1<window_size_){ + window_size_ = (1<& StreamingDQController::GetRedo(){ + return redo_; +} + +std::vector& StreamingDQController::GetDone(){ + return done_; +} + +void StreamingDQController::CommitDone(int64_t commit_id) { + committed_[commit_id&window_size_] = true; + //LOG(ERROR)<<"commit done:"<GetVersion(it.first, false); +#ifdef CDebug + LOG(ERROR)<<"op log:"< new_commit_ids; + for(const auto& it : change_set){ + const uint256_t& address = it.first; + //LOG(ERROR)<<"get pre-op:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: +#ifdef CDebug + LOG(ERROR)<<"commit:"<Reset(it.first, op.data, op.version, false); + storage_->Store(it.first, op.data); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, true); + storage_->Reset(it.first, 0, op.version, false); + done = true; + break; + } + } + } + + CommitDone(commit_id); + last_commit_id_++; + return true; +} + +void StreamingDQController::RedoCommit(int64_t commit_id, int flag){ + if(is_redo_[commit_id]){ + return; + } + is_redo_[commit_id] = true; +#ifdef CDebug + LOG(ERROR)<<"====== add redo:"< +#include +#include +#include + +#include "service/contract/executor/manager/concurrency_controller.h" +#include "service/contract/executor/manager/d_storage.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace streaming { + +class StreamingDQController : public ConcurrencyController { + public: + StreamingDQController(DataStorage * storage, int window_size); + ~StreamingDQController(); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_); + bool Commit(int64_t commit_id); + + std::vector& GetRedo(); + std::vector& GetDone(); + + typedef std::map > CommitList; + + void Clear(int64_t commit_id); + void Clear(); + + private: + + + bool PreCommit(int64_t commit_id); + bool PreCommitInternal(int64_t commit_id); + void MergeChangeList(int64_t commit_id); + + bool PostCommit(int64_t commit_id); + void RedoConflict(int64_t commit_id); + + bool CheckCommit(int64_t commit_id); + bool CheckPreCommit(int64_t commit_id); + + const ModifyMap * GetChangeList(int64_t commit_id); + void Remove(int64_t commit_id); + + + void CommitDone(int64_t commit_id); + void RedoCommit(int64_t commit_id, int flag); + + void RollBackData(const uint256_t& address, const Data& data); + + bool IsRead(const uint256_t& address, int64_t commit_id); + + private: + int window_size_ = 2000; + + std::vector changes_list_,rechanges_list_; + + CommitList commit_list_[4196]; + int64_t last_commit_id_, current_commit_id_; + + CommitList pre_commit_list_[4196]; + int64_t last_pre_commit_id_; + + std::atomic is_redo_[4196]; + std::vector redo_; + bool wait_[4196], committed_[4196], finish_[4196]; + + //std::atomic is_done_[1024]; + std::vector done_; + + DataStorage * storage_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/streaming_single_committer.cpp b/platform/consensus/ordering/fides/executor/manager/streaming_single_committer.cpp new file mode 100644 index 000000000..a57d45bfd --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/streaming_single_committer.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/streaming_single_committer.h" + +#include +#include + +#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + + +namespace resdb { +namespace contract { +namespace streaming { + +StreamingSingleCommitter:: StreamingSingleCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back, + int worker_num):storage_(storage), gs_(global_state), + call_back_(call_back) { + + executor_ = std::make_unique(); + + id_ = 1; +} + +void StreamingSingleCommitter::SetExecuteCallBack(std::function)> func) { + call_back_ = std::move(func); +} + +StreamingSingleCommitter::~StreamingSingleCommitter(){ +} + +void StreamingSingleCommitter::Execute(const ContractExecuteInfo& request){ + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request.caller_address, + request.contract_address, + request.func_addr, + request.func_params, gs_); + resp->state = ret.status(); + resp->contract_address = request.contract_address; + resp->commit_id = request.commit_id; + resp->user_id = request.user_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + //LOG(ERROR)<<"commit :"<commit_id; + } + else { + LOG(ERROR)<<"commit :"<commit_id<<" fail"; + resp->ret = -1; + assert(resp->ret>=0); + } + if(call_back_){ + call_back_(std::move(resp)); + } +} + +void StreamingSingleCommitter::AsyncExecContract(std::vector& requests) { + for(auto& request: requests) { + request.commit_id = id_++; + Execute(request); + } + + return ; +} + +absl::StatusOr StreamingSingleCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/streaming_single_committer.h b/platform/consensus/ordering/fides/executor/manager/streaming_single_committer.h new file mode 100644 index 000000000..a6d530b94 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/streaming_single_committer.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/manager/committer_context.h" +#include "service/contract/executor/common/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace streaming { + +class StreamingSingleCommitter : public ContractCommitter { + public: + StreamingSingleCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back = nullptr, + int worker_num = 2); + + ~StreamingSingleCommitter(); + + void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info) { return {}; } + +private: + void Execute(const ContractExecuteInfo& request); + + private: + std::unique_ptr executor_; + DataStorage * storage_; + GlobalState* gs_; + int64_t id_; + + std::function)> call_back_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/test_committer.cpp b/platform/consensus/ordering/fides/executor/manager/test_committer.cpp new file mode 100644 index 000000000..e69912d0b --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/test_committer.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/test_committer.h" + +#include "glog/logging.h" +//#include "eEVM/processor.h" + +namespace resdb { +namespace contract { + +TestCommitter:: TestCommitter( + DataStorage* storage, + GlobalState * global_state):gs_(global_state) { + + controller_ = std::make_unique(storage); + executor_ = std::make_unique(); +} + +TestCommitter::~TestCommitter(){ +} + +std::vector> TestCommitter::ExecContract( + const std::vector& requests) { + + std::vector > resp_list; + for(const auto& request: requests){ + std::unique_ptr resp = std::make_unique(); + //auto start_time = GetCurrentTime(); + auto ret = ExecContract(request.caller_address, request.contract_address, + request.func_addr, + request.func_params, gs_); + resp->state = ret.status(); + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + } + else { + LOG(ERROR)<<"exec fail"; + resp->ret = -1; + } + resp->contract_address = request.contract_address; + resp->commit_id = request.commit_id; + + resp_list.push_back(std::move(resp)); + } + return resp_list; +} + +absl::StatusOr TestCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/test_committer.h b/platform/consensus/ordering/fides/executor/manager/test_committer.h new file mode 100644 index 000000000..0d98bafba --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/test_committer.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include + +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/test_controller.h" +#include "service/contract/proto/func_params.pb.h" + +#include "absl/status/statusor.h" + +namespace resdb { +namespace contract { + +class TestCommitter : public ContractCommitter { + public: + TestCommitter( + DataStorage* storage, + GlobalState * global_state); + + virtual ~TestCommitter(); + + std::vector> ExecContract(const std::vector& request); + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + private: + std::unique_ptr controller_; + GlobalState* gs_; + std::unique_ptr executor_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/test_controller.cpp b/platform/consensus/ordering/fides/executor/manager/test_controller.cpp new file mode 100644 index 000000000..97edd57ed --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/test_controller.cpp @@ -0,0 +1,35 @@ +#include "service/contract/executor/manager/test_controller.h" + +#include + +namespace resdb { +namespace contract { + +TestController::TestController(DataStorage * storage) : ConcurrencyController(storage){} + +void TestController::PushCommit(int64_t commit_id, const ModifyMap& local_changes) { + for(auto it : local_changes){ + bool done = false; + for(int i = it.second.size()-1; i >=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<Store(it.first, op.data); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first); + done = true; + break; + } + } + } + return ; +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/test_controller.h b/platform/consensus/ordering/fides/executor/manager/test_controller.h new file mode 100644 index 000000000..a4371033a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/test_controller.h @@ -0,0 +1,19 @@ +#pragma once + +#include "service/contract/executor/manager/concurrency_controller.h" + +#include +#include + +namespace resdb { +namespace contract { + +class TestController : public ConcurrencyController { + public: + TestController(DataStorage * storage); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_); +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/test_data/BUILD b/platform/consensus/ordering/fides/executor/manager/test_data/BUILD new file mode 100644 index 000000000..6f9052157 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/test_data/BUILD @@ -0,0 +1 @@ +exports_files(["contract.json", "kv.json"]) diff --git a/platform/consensus/ordering/fides/executor/manager/test_data/compile.sh b/platform/consensus/ordering/fides/executor/manager/test_data/compile.sh new file mode 100644 index 000000000..dfd25e66f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/test_data/compile.sh @@ -0,0 +1,5 @@ +# sudo add-apt-repository ppa:ethereum/ethereum +# sudo apt-get update +# sudo apt-get install solc +solc --evm-version homestead --combined-json bin,hashes --pretty-json --optimize kv.sol > kv.json + diff --git a/platform/consensus/ordering/fides/executor/manager/test_data/contract.json b/platform/consensus/ordering/fides/executor/manager/test_data/contract.json new file mode 100644 index 000000000..e9c0d972f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/test_data/contract.json @@ -0,0 +1,19 @@ +{ + "contracts": + { + "ERC20.sol:ERC20Token": + { + "bin": "608060405234801561001057600080fd5b506040516104423803806104428339818101604052602081101561003357600080fd5b50516000818155338152600160205260409020556103ec806100566000396000f3fe608060405234801561001057600080fd5b506004361061007e577c01000000000000000000000000000000000000000000000000000000006000350463095ea7b3811461008357806318160ddd146100c357806323b872dd146100dd57806370a0823114610113578063a9059cbb14610139578063dd62ed3e14610165575b600080fd5b6100af6004803603604081101561009957600080fd5b50600160a060020a038135169060200135610193565b604080519115158252519081900360200190f35b6100cb6101fa565b60408051918252519081900360200190f35b6100af600480360360608110156100f357600080fd5b50600160a060020a03813581169160208101359091169060400135610200565b6100cb6004803603602081101561012957600080fd5b5035600160a060020a03166102e6565b6100af6004803603604081101561014f57600080fd5b50600160a060020a038135169060200135610301565b6100cb6004803603604081101561017b57600080fd5b50600160a060020a038135811691602001351661038c565b336000818152600260209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b60005490565b600160a060020a038316600090815260016020526040812054821180159061024b5750600160a060020a03841660009081526002602090815260408083203384529091529020548211155b156102db57600160a060020a038085166000818152600160209081526040808320805488900390559387168083528483208054880190559282526002815283822033808452908252918490208054879003905583518681529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35060016102df565b5060005b9392505050565b600160a060020a031660009081526001602052604090205490565b3360009081526001602052604081205482116103845733600081815260016020908152604080832080548790039055600160a060020a03871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35060016101f4565b5060006101f4565b600160a060020a0391821660009081526002602090815260408083209390941682529190915220549056fea265627a7a72315820e4ae92c4517e475d9f77ac0bfcd10463a09239f34734fc0ab4d7966450fb428464736f6c63430005100032", + "hashes": + { + "allowance(address,address)": "dd62ed3e", + "approve(address,uint256)": "095ea7b3", + "balanceOf(address)": "70a08231", + "totalSupply()": "18160ddd", + "transfer(address,uint256)": "a9059cbb", + "transferFrom(address,address,uint256)": "23b872dd" + } + } + }, + "version": "0.5.16+commit.9c3226ce.Linux.g++" +} diff --git a/platform/consensus/ordering/fides/executor/manager/test_data/kv.json b/platform/consensus/ordering/fides/executor/manager/test_data/kv.json new file mode 100644 index 000000000..13fc7e73b --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/test_data/kv.json @@ -0,0 +1,18 @@ +{ + "contracts": + { + "kv.sol:KV": + { + "bin": "608060405234801561001057600080fd5b506040516103d13803806103d18339818101604052602081101561003357600080fd5b50513360009081526020819052604090205561037d806100546000396000f3fe608060405234801561001057600080fd5b5060043610610073577c01000000000000000000000000000000000000000000000000000000006000350463239b83eb81146100785780633825d828146100c8578063beabacc8146100f4578063c2bc2efc1461012a578063cfc9c3f914610162575b600080fd5b6100b46004803603608081101561008e57600080fd5b50600160a060020a03813581169160208101358216916040820135169060600135610198565b604080519115158252519081900360200190f35b6100b4600480360360408110156100de57600080fd5b50600160a060020a038135169060200135610231565b6100b46004803603606081101561010a57600080fd5b50600160a060020a03813581169160208101359091169060400135610257565b6101506004803603602081101561014057600080fd5b5035600160a060020a03166102bf565b60408051918252519081900360200190f35b6100b46004803603606081101561017857600080fd5b50600160a060020a038135811691602081013590911690604001356102da565b600160a060020a038416600090815260208190526040812054828111156101d957600160a060020a0386166000908152602081905260409020805484900390555b61032081101561020657600160a060020a0385166000908152602081905260409020805484019055610225565b600160a060020a03841660009081526020819052604090208054840190555b50600195945050505050565b600160a060020a0382166000908152602081905260409020805482019055600192915050565b600160a060020a03831660009081526020819052604081205482101561029757600160a060020a0384166000908152602081905260409020805483900390555b50600160a060020a038216600090815260208190526040902080548201905560019392505050565b600160a060020a031660009081526020819052604090205490565b336000908152602081905260408120805483810390915561032081101561031e57600160a060020a038516600090815260208190526040902080548401905561033d565b600160a060020a03841660009081526020819052604090208054840190555b50600194935050505056fea265627a7a7231582073de5a372b480ae10296a8fccae0f9bc5adfb8d0ef56a2c198cac4b72fe6e8d264736f6c63430005100032", + "hashes": + { + "get(address)": "c2bc2efc", + "set(address,uint256)": "3825d828", + "transfer(address,address,uint256)": "beabacc8", + "transferif(address,address,address,uint256)": "239b83eb", + "transferto(address,address,uint256)": "cfc9c3f9" + } + } + }, + "version": "0.5.16+commit.9c3226ce.Linux.g++" +} diff --git a/platform/consensus/ordering/fides/executor/manager/test_data/kv.sol b/platform/consensus/ordering/fides/executor/manager/test_data/kv.sol new file mode 100644 index 000000000..f5bfed426 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/test_data/kv.sol @@ -0,0 +1,59 @@ +pragma solidity >= 0.5.0; + +// Transfer tokens from the contract owner +contract KV { + mapping (address => uint256) balances; + mapping (address => uint256) allow; + + constructor(uint256 s) public { + balances[msg.sender] = s; + } + + // Get the account balance of another account with address _owner + function get(address _owner) public view returns (uint256) { + return balances[_owner]; + } + + // Send _value amount of tokens to address _to + function set(address _to, uint256 _value) public returns (bool) { + uint256 values = balances[_to]; + balances[_to] = _value + values; + return true; + } + + // Send _value amount of tokens to address _to + function transfer(address _from, address _to, uint256 _value) public returns (bool) { + if (balances[_from] > _value) { + balances[_from] -= _value; + } + balances[_to] += _value; + return true; + } + + function transferif(address _from, address _to1, address _to2, uint256 _value) public returns (bool) { + uint256 value = balances[_from]; + + if (balances[_from] > _value) { + balances[_from] -= _value; + } + if (value < 800 ) { + balances[_to1] += _value; + } else { + balances[_to2] += _value; + } + return true; + } + + function transferto(address _to1, address _to2, uint256 _value) public returns (bool) { + uint256 value = balances[msg.sender]; + balances[msg.sender] -= _value; + if (value < 800 ) { + balances[_to1] += _value; + } else { + balances[_to2] += _value; + } + return true; + } + +} + diff --git a/platform/consensus/ordering/fides/executor/manager/two_phase_committer.cpp b/platform/consensus/ordering/fides/executor/manager/two_phase_committer.cpp new file mode 100644 index 000000000..2ab251d72 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/two_phase_committer.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/two_phase_committer.h" + +#include "service/contract/executor/manager/local_state.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { + +TwoPhaseCommitter:: TwoPhaseCommitter( + DataStorage* storage, + GlobalState * global_state, int worker_num):gs_(global_state),worker_num_(worker_num) { + controller_ = std::make_unique(storage); + executor_ = std::make_unique(); + is_stop_ = false; + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request = request_queue_.Pop(); + if (request == nullptr) { + continue; + } + + LocalState local_state(controller_.get()); + local_state.Set(gs_->GetAccount(request->contract_address), request->commit_id); + + //LOG(ERROR)<<"worker:"<contract_address<<" commit id:"<commit_id; + std::unique_ptr resp = std::make_unique(); + //auto start_time = GetCurrentTime(); + auto ret = ExecContract(request->caller_address, request->contract_address, + request->func_addr, + request->func_params, &local_state); + resp->state = ret.status(); + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + local_state.Flesh(request->contract_address, request->commit_id); + } + else { + LOG(ERROR)<<"exec fail"; + resp->ret = -1; + } + //LOG(ERROR)<<"execute:"<contract_address = request->contract_address; + resp->commit_id = request->commit_id; + resp->user_id = request->user_id; + resp_queue_.Push(std::move(resp)); + } + })); + } +} + +TwoPhaseCommitter::~TwoPhaseCommitter(){ + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + +std::vector> TwoPhaseCommitter::ExecContract( + std::vector& requests) { + + //LOG(ERROR)<<"executor contract size:"< fail_list; + std::map > responses; + + int do_time = 0; + //auto start_time = GetCurrentTime(); + do{ + controller_->Clear(); + + // process + int process_num = 0; + int receive_num = 0; + for(auto request: requests) { + if(fail_list.empty()){ + // first try + //LOG(ERROR)<<"try commit id:"<(request)); + process_num++; + } + else { + if(fail_list.find(request.commit_id) != fail_list.end()){ + // re-do + //LOG(ERROR)<<"re-do commit id:"<(request)); + process_num++; + } + } + } + + std::map > tmp_responses; + + while(process_num != receive_num){ + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + tmp_responses[resp->commit_id] = std::move(resp); + receive_num++; + } + + // commit + fail_list.clear(); + for(auto& resp_it: tmp_responses) { + auto& resp = resp_it.second; + if(resp->ret==0){ + //gs_->Flesh(resp->contract_address, resp->commit_id); + if(!controller_->Commit(resp->commit_id)){ + //LOG(ERROR)<<"commit fail, contract address:"<contract_address<<" commit id:"<commit_id; + fail_list.insert(resp->commit_id); + } + else { + //LOG(ERROR)<<"commit done, contract address:"<contract_address<<" commit id:"<commit_id; + } + } + resp->retry_time = do_time; + responses[resp_it.first] = std::move(resp); + } + do_time++; + }while(!fail_list.empty()); + + std::vector > resp_list; + for(auto& resp_it: responses) { + resp_list.push_back(std::move(resp_it.second)); + } + //if(do_time>1) + //LOG(ERROR)<<"commit time:"< TwoPhaseCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/two_phase_committer.h b/platform/consensus/ordering/fides/executor/manager/two_phase_committer.h new file mode 100644 index 000000000..cf68d50d3 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/two_phase_committer.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include + +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/two_phase_controller.h" +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/common/utils.h" +#include "service/contract/proto/func_params.pb.h" + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" + +namespace resdb { +namespace contract { + +class TwoPhaseCommitter : public ContractCommitter { + public: + TwoPhaseCommitter( + DataStorage* storage, + GlobalState * global_state, int worker_num = 2); + + ~TwoPhaseCommitter(); + + std::vector> ExecContract(std::vector& request); + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + private: + std::unique_ptr controller_; + GlobalState* gs_; + std::vector workers_; + std::atomic is_stop_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + const int worker_num_; + std::unique_ptr executor_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/two_phase_committer_test.cpp b/platform/consensus/ordering/fides/executor/manager/two_phase_committer_test.cpp new file mode 100644 index 000000000..13df5808e --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/two_phase_committer_test.cpp @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/two_phase_committer.h" + +#include + +#include "service/contract/executor/manager/contract_deployer.h" +#include "service/contract/executor/manager/address_manager.h" + +#include +#include + + + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +uint256_t GetAddressHash(uint256_t address){ + std::vectorcode; + code.resize(64u); + eevm::to_big_endian(address, code.data()); + code[63]=1; + + uint8_t h[32]; + eevm::keccak_256(code.data(), static_cast(code.size()), h); + return eevm::from_big_endian(h, sizeof(h)); +} + + +class TwoPhaseCommitterTest : public Test { + public: + TwoPhaseCommitterTest() : owner_address_(get_random_address()) { + std::string contract_path = test_dir + "test_data/contract.json"; + LOG(ERROR)<<"test dir:"<(); + gs_ = std::make_unique(storage_.get()); + + committer_ = std::make_unique(storage_.get(), gs_.get()); + + contract_address_ = AddressManager::CreateContractAddress(owner_address_); + deployer_ = std::make_unique(committer_.get(), gs_.get()); + contract_address_ = deployer_->DeployContract(owner_address_, contract_json_, {1000}); + } + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const Params& func_param) { + std::string func_addr = + deployer_->GetFuncAddress(contract_address, func_param.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << func_param.func_name(); + return absl::InvalidArgumentError("Func not exist."); + } + + LOG(ERROR)<<"caller:"< result = committer_->ExecContract( + caller_address, contract_address, + func_addr, + func_param, gs_.get()); + if(result.ok()){ + return *result; + } + return result.status(); + } + + std::vector> ExecContract(std::vector& execute_info) { + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i; + } + return committer_->ExecContract(execute_info); + } + + + protected: + Address owner_address_; + Address contract_address_; + nlohmann::json contract_json_; + std::unique_ptr storage_; + std::unique_ptr deployer_; + std::unique_ptr gs_; + std::unique_ptrcommitter_; + std::map> func_address_; +}; + +TEST_F(TwoPhaseCommitterTest, ExecContract) { + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + LOG(ERROR)<<"owner address:"<Load(owner_key).first, 1000); + } + + // receiver 0 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(transfer_receiver)); + + auto result = + ExecContract(owner_address_, contract_address_, func_params); + EXPECT_EQ(HexToInt(*result), 0); + + EXPECT_EQ(storage_->Load(transfer_key).first, 0); + } + + // transfer 400 to receiver + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(400)); + + auto result = + ExecContract(owner_address_, contract_address_, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_->Load(transfer_key).first, 400); + EXPECT_EQ(storage_->Load(owner_key).first, 600); + } + + // owner 600 + { + Address caller = get_random_address(); + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = + ExecContract(caller, contract_address_, func_params); + EXPECT_EQ(HexToInt(*result), 600); + + EXPECT_EQ(storage_->Load(transfer_key).first, 400); + EXPECT_EQ(storage_->Load(owner_key).first, 600); + } + + // transfer 200 to receiver2 from receiver + { + Params func_params; + func_params.set_func_name("approve(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + auto result = + ExecContract(transfer_receiver, contract_address_, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_->Load(transfer2_key).first, 0); + EXPECT_EQ(storage_->Load(transfer_key).first, 400); + EXPECT_EQ(storage_->Load(owner_key).first, 600); + } + { + Params func_params; + func_params.set_func_name("transferFrom(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + auto result = + ExecContract(transfer_receiver, contract_address_, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_->Load(transfer2_key).first, 100); + EXPECT_EQ(storage_->Load(transfer_key).first, 300); + EXPECT_EQ(storage_->Load(owner_key).first, 600); + } +} + +TEST_F(TwoPhaseCommitterTest, ExecMultiContractNoConflict) { + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + uint256_t owner_key = GetAddressHash(owner_address_); + uint256_t transfer_key = GetAddressHash(transfer_receiver); + uint256_t transfer2_key = GetAddressHash(transfer_receiver2); + uint256_t transfer3_key = GetAddressHash(transfer_receiver3); + + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(400)); + + auto result = + ExecContract(owner_address_, contract_address_, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_->Load(transfer_key).first, 400); + EXPECT_EQ(storage_->Load(owner_key).first, 600); + } + + // transfer 200 to receiver2 from receiver + { + Params func_params; + func_params.set_func_name("approve(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(200)); + + auto result = + ExecContract(transfer_receiver, contract_address_, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } + + std::vector info; + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver3)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("transferFrom(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(200)); + + info.push_back(ContractExecuteInfo(transfer_receiver, contract_address_, "", func_params, 0)); + } + std::vector> resp = ExecContract(info); + EXPECT_EQ(storage_->Load(transfer2_key).first, 200); + EXPECT_EQ(storage_->Load(transfer3_key).first, 100); + + LOG(ERROR)<<"resp size:"<ret, 0); + EXPECT_EQ(resp[1]->ret, 0); + + EXPECT_EQ(HexToInt(resp[0]->result), 1); + EXPECT_EQ(HexToInt(resp[1]->result), 1); +} + +TEST_F(TwoPhaseCommitterTest, ExecMultiContractHaveConflict) { + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + uint256_t owner_key = GetAddressHash(owner_address_); + uint256_t transfer_key = GetAddressHash(transfer_receiver); + uint256_t transfer2_key = GetAddressHash(transfer_receiver2); + + std::vector info; + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::vector> resp = ExecContract(info); + EXPECT_EQ(storage_->Load(owner_key).first, 800); + EXPECT_EQ(storage_->Load(transfer_key).first, 100); + EXPECT_EQ(storage_->Load(transfer2_key).first, 100); + + LOG(ERROR)<<"resp size:"<ret, 0); + EXPECT_EQ(resp[1]->ret, 0); + + EXPECT_EQ(HexToInt(resp[0]->result), 1); + EXPECT_EQ(HexToInt(resp[1]->result), 1); +} + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/two_phase_controller.cpp b/platform/consensus/ordering/fides/executor/manager/two_phase_controller.cpp new file mode 100644 index 000000000..e30d1e21c --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/two_phase_controller.cpp @@ -0,0 +1,112 @@ +#include "service/contract/executor/manager/two_phase_controller.h" + +#include + +namespace resdb { +namespace contract { + +TwoPhaseController::TwoPhaseController(DataStorage * storage) : ConcurrencyController(storage){} + +void TwoPhaseController::Clear(){ + std::unique_lock lock(mutex_); + changes_list_.clear(); + first_commit_.clear(); + + changes_list_.resize(window_size_); + for(int i = 0; i < window_size_; ++i){ + changes_list_[i].clear(); + } +} + +void TwoPhaseController::PushCommit(int64_t commit_id, const ModifyMap& local_changes) { + if(!changes_list_[commit_id].empty()){ + LOG(ERROR)<<"push record:"<second > commit_id){ + first_commit_[it.first] = commit_id; + } + } +} + +bool TwoPhaseController::CheckCommit(int64_t commit_id) { + const auto& change_set = changes_list_[commit_id]; + if(change_set.empty()){ + LOG(ERROR)<<" no commit id record found:"<second < commit_id){ + return false; + } + } + return true; +} + +bool TwoPhaseController::Commit(int64_t commit_id){ + if(!CheckCommit(commit_id)){ + return false; + } + + const auto& change_set = changes_list_[commit_id]; + if(change_set.empty()){ + LOG(ERROR)<<" no commit id record found:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<Store(it.first, op.data); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first); + done = true; + break; + } + } + } + return true; +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/two_phase_controller.h b/platform/consensus/ordering/fides/executor/manager/two_phase_controller.h new file mode 100644 index 000000000..b27b01cef --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/two_phase_controller.h @@ -0,0 +1,33 @@ +#pragma once + +#include "service/contract/executor/manager/concurrency_controller.h" + +#include +#include + +namespace resdb { +namespace contract { + +class TwoPhaseController : public ConcurrencyController { + public: + TwoPhaseController(DataStorage * storage); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_); + + bool Commit(int64_t commit_id); + + // Before each 2PL, make sure clear the data from the previous round. + void Clear(); + + private: + bool CheckCommit(int64_t commit_id); + + protected: + mutable std::shared_mutex mutex_; + std::vector changes_list_; + std::map first_commit_; + const int window_size_ = 1000; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/two_phase_controller_test.cpp b/platform/consensus/ordering/fides/executor/manager/two_phase_controller_test.cpp new file mode 100644 index 000000000..a9546d52b --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/two_phase_controller_test.cpp @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/two_phase_controller.h" + +#include +#include + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +void GetData(const std::string& addr, const DataStorage& storage, TwoPhaseController::ModifyMap& changes){ + changes[HexToInt(addr)].push_back(Data(LOAD,storage.Load(HexToInt(addr)).first, storage.Load(HexToInt(addr)).second)); +} + +void GetData(const uint256_t& addr, const DataStorage& storage, TwoPhaseController::ModifyMap& changes){ + changes[addr].push_back(Data(LOAD,storage.Load(addr).first, storage.Load(addr).second)); +} + +void SetData(const uint256_t& addr, int value, TwoPhaseController::ModifyMap& changes){ + changes[addr].push_back(Data(STORE, value)); +} + +void SetData(const std::string& addr, int value, TwoPhaseController::ModifyMap& changes){ + changes[HexToInt(addr)].push_back(Data(STORE, value)); +} + +TEST(TwoPhaseControllerTest, PushOneCommit) { + DataStorage storage; + TwoPhaseController controller(&storage); + + TwoPhaseController::ModifyMap changes; + + GetData("0x123", storage, changes); + SetData("0x124", 1000, changes); + + controller.PushCommit(0, changes); + + controller.Commit(0); + + EXPECT_EQ(storage.Load(HexToInt("0x123")).first, 0); + EXPECT_EQ(storage.Load(HexToInt("0x124")).first, 1000); +} + +TEST(TwoPhaseControllerTest, SkipLOAD) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + uint256_t address2 = HexToInt("0x124"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + TwoPhaseController::ModifyMap changes; + + GetData("0x123", storage, changes); + SetData("0x124", 1000, changes); + + controller.PushCommit(0, changes); + + controller.Commit(0); + + EXPECT_EQ(storage.Load(address1).first, 2000); + EXPECT_EQ(storage.Load(address2).first, 1000); +} + +TEST(TwoPhaseControllerTest, Cover) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + TwoPhaseController::ModifyMap changes; + + GetData(address1, storage, changes); + SetData(address1, 1000, changes); + + controller.PushCommit(0, changes); + + EXPECT_TRUE(controller.Commit(0)); + + EXPECT_EQ(storage.Load(address1).first, 1000); +} + +TEST(TwoPhaseControllerTest, PushTwice) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + TwoPhaseController::ModifyMap changes; + + GetData(address1, storage, changes); + SetData(address1, 1000, changes); + + controller.PushCommit(0, changes); + controller.PushCommit(0, changes); + + EXPECT_TRUE(controller.Commit(0)); + + EXPECT_EQ(storage.Load(address1).first, 1000); +} + +TEST(TwoPhaseControllerTest, CommitTwice) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + TwoPhaseController::ModifyMap changes; + GetData(address1, storage, changes); + SetData(address1, 1000, changes); + + controller.PushCommit(0, changes); + + EXPECT_TRUE(controller.Commit(0)); + EXPECT_TRUE(controller.Commit(0)); + + EXPECT_EQ(storage.Load(address1).first, 1000); +} + +TEST(TwoPhaseControllerTest, ConflictFull) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + uint256_t address2 = HexToInt("0x124"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + // commit 0: + { + TwoPhaseController::ModifyMap changes; + GetData(address1, storage, changes); + SetData(address2, 1000, changes); + + controller.PushCommit(0, changes); + } + + // commit 1: + { + TwoPhaseController::ModifyMap changes; + GetData(address1, storage, changes); + SetData(address2, 3000, changes); + + controller.PushCommit(1, changes); + } + + EXPECT_TRUE(controller.Commit(0)); + EXPECT_FALSE(controller.Commit(1)); + + EXPECT_EQ(storage.Load(address1).first, 2000); + EXPECT_EQ(storage.Load(address2).first, 1000); +} + +TEST(TwoPhaseControllerTest, ConflictCommit1Again) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + uint256_t address2 = HexToInt("0x124"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + // commit 1: + { + TwoPhaseController::ModifyMap changes; + GetData(address1, storage, changes); + SetData(address2, 3000, changes); + + controller.PushCommit(1, changes); + } + + // commit 0: + { + TwoPhaseController::ModifyMap changes; + GetData(address1, storage, changes); + SetData(address2, 1000, changes); + + controller.PushCommit(0, changes); + } + + EXPECT_TRUE(controller.Commit(0)); + EXPECT_FALSE(controller.Commit(1)); + + EXPECT_EQ(storage.Load(address1).first, 2000); + EXPECT_EQ(storage.Load(address2).first, 1000); +} + +TEST(TwoPhaseControllerTest, ReadAfterWrite) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + uint256_t address2 = HexToInt("0x124"); + uint256_t address3 = HexToInt("0x125"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + // commit 0: + { + TwoPhaseController::ModifyMap changes; + GetData(address1, storage, changes); + SetData(address2, 3000, changes); + + controller.PushCommit(0, changes); + } + + // commit 1: + { + TwoPhaseController::ModifyMap changes; + GetData(address2, storage, changes); + SetData(address3, 1000, changes); + + controller.PushCommit(1, changes); + } + + EXPECT_TRUE(controller.Commit(0)); + EXPECT_FALSE(controller.Commit(1)); + + EXPECT_EQ(storage.Load(address1).first, 2000); + EXPECT_EQ(storage.Load(address2).first, 3000); + EXPECT_FALSE(storage.Exist(address3)); +} + +TEST(TwoPhaseControllerTest, WriteAfterWrite) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + uint256_t address2 = HexToInt("0x124"); + uint256_t address3 = HexToInt("0x125"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + // commit 0: + { + TwoPhaseController::ModifyMap changes; + GetData(address1, storage, changes); + SetData(address2, 3000, changes); + + controller.PushCommit(0, changes); + } + + // commit 1: + { + TwoPhaseController::ModifyMap changes; + GetData(address2, storage, changes); + SetData(address3, 1000, changes); + + controller.PushCommit(1, changes); + } + + EXPECT_TRUE(controller.Commit(0)); + EXPECT_FALSE(controller.Commit(1)); + + EXPECT_EQ(storage.Load(address1).first, 2000); + EXPECT_EQ(storage.Load(address2).first, 3000); + EXPECT_FALSE(storage.Exist(address3)); +} + +TEST(TwoPhaseControllerTest, ReadAfterRead) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + uint256_t address2 = HexToInt("0x124"); + uint256_t address3 = HexToInt("0x125"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + // commit 0: + { + TwoPhaseController::ModifyMap changes; + GetData(address1, storage, changes); + SetData(address2, 3000, changes); + + controller.PushCommit(0, changes); + } + + // commit 1: + { + TwoPhaseController::ModifyMap changes; + GetData(address1, storage, changes); + SetData(address3, 1000, changes); + + controller.PushCommit(1, changes); + } + + EXPECT_TRUE(controller.Commit(0)); + EXPECT_TRUE(controller.Commit(1)); + + EXPECT_EQ(storage.Load(address1).first, 2000); + EXPECT_EQ(storage.Load(address2).first, 3000); + EXPECT_EQ(storage.Load(address3).first, 1000); +} + +TEST(TwoPhaseControllerTest, WriteAfterRead) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + uint256_t address2 = HexToInt("0x124"); + uint256_t address3 = HexToInt("0x125"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + // commit 0: + { + TwoPhaseController::ModifyMap changes; + GetData(address1, storage, changes); + SetData(address2, 3000, changes); + + controller.PushCommit(0, changes); + } + + // commit 1: + { + TwoPhaseController::ModifyMap changes; + SetData(address1, 500, changes); + SetData(address3, 1000, changes); + + controller.PushCommit(1, changes); + } + + EXPECT_TRUE(controller.Commit(0)); + EXPECT_TRUE(controller.Commit(1)); + + EXPECT_EQ(storage.Load(address1).first, 500); + EXPECT_EQ(storage.Load(address2).first, 3000); + EXPECT_EQ(storage.Load(address3).first, 1000); +} + +TEST(TwoPhaseControllerTest, ReadAfterWriteAfterRead) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + uint256_t address2 = HexToInt("0x124"); + uint256_t address3 = HexToInt("0x125"); + uint256_t address4 = HexToInt("0x126"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + // commit 0: + { + TwoPhaseController::ModifyMap changes; + GetData(address1, storage, changes); + SetData(address2, 3000, changes); + + controller.PushCommit(0, changes); + } + + // commit 1: + { + TwoPhaseController::ModifyMap changes; + SetData(address1, 500, changes); + SetData(address3, 1000, changes); + + controller.PushCommit(1, changes); + } + + // commit 2: + { + TwoPhaseController::ModifyMap changes; + GetData(address1, storage, changes); + SetData(address4, 2000, changes); + + controller.PushCommit(2, changes); + } + + EXPECT_TRUE(controller.Commit(0)); + EXPECT_TRUE(controller.Commit(1)); + EXPECT_FALSE(controller.Commit(2)); + + EXPECT_EQ(storage.Load(address1).first, 500); + EXPECT_EQ(storage.Load(address2).first, 3000); + EXPECT_EQ(storage.Load(address3).first, 1000); + EXPECT_FALSE(storage.Exist(address4)); +} + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/two_phase_ooo_committer.cpp b/platform/consensus/ordering/fides/executor/manager/two_phase_ooo_committer.cpp new file mode 100644 index 000000000..ad92f4661 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/two_phase_ooo_committer.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/two_phase_ooo_committer.h" + +#include "service/contract/executor/manager/local_state.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { + +TwoPhaseOOOCommitter:: TwoPhaseOOOCommitter( + DataStorage* storage, + GlobalState * global_state, int worker_num):gs_(global_state),worker_num_(worker_num) { + controller_ = std::make_unique(storage); + executor_ = std::make_unique(); + is_stop_ = false; + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request = request_queue_.Pop(); + if (request == nullptr) { + continue; + } + + LocalState local_state(controller_.get()); + local_state.Set(gs_->GetAccount(request->contract_address), request->commit_id); + + //LOG(ERROR)<<"worker:"<contract_address<<" commit id:"<commit_id; + std::unique_ptr resp = std::make_unique(); + //auto start_time = GetCurrentTime(); + auto ret = ExecContract(request->caller_address, request->contract_address, + request->func_addr, + request->func_params, &local_state); + resp->state = ret.status(); + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + local_state.Flesh(request->contract_address, request->commit_id); + } + else { + LOG(ERROR)<<"exec fail"; + resp->ret = -1; + } + //LOG(ERROR)<<"execute:"<contract_address = request->contract_address; + resp->commit_id = request->commit_id; + resp->user_id = request->user_id; + resp_queue_.Push(std::move(resp)); + } + })); + } +} + +TwoPhaseOOOCommitter::~TwoPhaseOOOCommitter(){ + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + +std::vector> TwoPhaseOOOCommitter::ExecContract( + std::vector& requests) { + + //LOG(ERROR)<<"executor contract size:"< fail_list; + std::map > responses; + + int do_time = 0; + //auto start_time = GetCurrentTime(); + do{ + controller_->Clear(); + + // process + int process_num = 0; + int receive_num = 0; + for(auto request: requests) { + if(fail_list.empty()){ + // first try + //LOG(ERROR)<<"try commit id:"<(request)); + process_num++; + } + else { + if(fail_list.find(request.commit_id) != fail_list.end()){ + // re-do + //LOG(ERROR)<<"re-do commit id:"<(request)); + process_num++; + } + } + } + + std::map > tmp_responses; + + fail_list.clear(); + while(process_num != receive_num){ + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + receive_num++; + + if(!controller_->Commit(resp->commit_id)){ + //LOG(ERROR)<<"commit fail, contract address:"<contract_address<<" commit id:"<commit_id; + fail_list.insert(resp->commit_id); + } + + resp->retry_time = do_time; + responses[resp->commit_id] = std::move(resp); + } + + do_time++; + }while(!fail_list.empty()); + + std::vector > resp_list; + for(auto& resp_it: responses) { + resp_list.push_back(std::move(resp_it.second)); + } + //if(do_time>1) + //LOG(ERROR)<<"commit time:"< TwoPhaseOOOCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/two_phase_ooo_committer.h b/platform/consensus/ordering/fides/executor/manager/two_phase_ooo_committer.h new file mode 100644 index 000000000..2dfdd4b2b --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/two_phase_ooo_committer.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include + +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/two_phase_ooo_controller.h" +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/common/utils.h" +#include "service/contract/proto/func_params.pb.h" + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" + +namespace resdb { +namespace contract { + +class TwoPhaseOOOCommitter : public ContractCommitter { + public: + TwoPhaseOOOCommitter( + DataStorage* storage, + GlobalState * global_state, int worker_num = 2); + + ~TwoPhaseOOOCommitter(); + + std::vector> ExecContract(std::vector& request); + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + private: + std::unique_ptr controller_; + GlobalState* gs_; + std::vector workers_; + std::atomic is_stop_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + const int worker_num_; + std::unique_ptr executor_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/two_phase_ooo_controller.cpp b/platform/consensus/ordering/fides/executor/manager/two_phase_ooo_controller.cpp new file mode 100644 index 000000000..5603bb706 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/two_phase_ooo_controller.cpp @@ -0,0 +1,86 @@ +#include "service/contract/executor/manager/two_phase_ooo_controller.h" + +#include + +namespace resdb { +namespace contract { + +TwoPhaseOOOController::TwoPhaseOOOController(DataStorage * storage) : ConcurrencyController(storage){} + +void TwoPhaseOOOController::Clear(){ + std::unique_lock lock(mutex_); + changes_list_.clear(); + first_commit_.clear(); + + changes_list_.resize(window_size_); + for(int i = 0; i < window_size_; ++i){ + changes_list_[i].clear(); + } +} + +void TwoPhaseOOOController::PushCommit(int64_t commit_id, const ModifyMap& local_changes) { + if(!changes_list_[commit_id].empty()){ + LOG(ERROR)<<"push record:"<GetVersion(address); + if(op.version != v){ + return false; + } + } + } + } + + return true; +} + +bool TwoPhaseOOOController::Commit(int64_t commit_id){ + if(!CheckCommit(commit_id)){ + return false; + } + + const auto& change_set = changes_list_[commit_id]; + if(change_set.empty()){ + LOG(ERROR)<<" no commit id record found:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<Store(it.first, op.data); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first); + done = true; + break; + } + } + } + return true; +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/two_phase_ooo_controller.h b/platform/consensus/ordering/fides/executor/manager/two_phase_ooo_controller.h new file mode 100644 index 000000000..5f9f52d3e --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/two_phase_ooo_controller.h @@ -0,0 +1,33 @@ +#pragma once + +#include "service/contract/executor/manager/concurrency_controller.h" + +#include +#include + +namespace resdb { +namespace contract { + +class TwoPhaseOOOController : public ConcurrencyController { + public: + TwoPhaseOOOController(DataStorage * storage); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_); + + bool Commit(int64_t commit_id); + + // Before each 2PL, make sure clear the data from the previous round. + void Clear(); + + private: + bool CheckCommit(int64_t commit_id); + + protected: + mutable std::shared_mutex mutex_; + std::vector changes_list_; + std::map first_commit_; + const int window_size_ = 1000; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/v_controller.cpp b/platform/consensus/ordering/fides/executor/manager/v_controller.cpp new file mode 100644 index 000000000..70e26674e --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/v_controller.cpp @@ -0,0 +1,85 @@ +#include "service/contract/executor/manager/v_controller.h" + +#include + +namespace resdb { +namespace contract { + +VController::VController(DataStorage * storage) : ConcurrencyController(storage){ + + changes_list_.resize(window_size_); + for(int i = 0; i < window_size_; ++i){ + changes_list_[i].clear(); + } +} + +VController::~VController(){} + +const ConcurrencyController::ModifyMap * VController::GetChangeList(int64_t commit_id) const { + return &changes_list_[commit_id]; +} + +void VController::PushCommit(int64_t commit_id, const ModifyMap& local_changes) { + changes_list_[commit_id] = local_changes; +} + +bool VController::CheckCommit(int64_t commit_id) { + const auto& change_set = changes_list_[commit_id]; + if(change_set.empty()){ + LOG(ERROR)<<" no commit id record found:"<GetVersion(address); + //LOG(ERROR)<<"get version:"< new_commit_ids; + for(const auto& it : change_set){ + bool done = false; + for(int i = it.second.size()-1; i >=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<Store(it.first, op.data); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first); + done = true; + break; + } + } + } + return true; + +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/manager/v_controller.h b/platform/consensus/ordering/fides/executor/manager/v_controller.h new file mode 100644 index 000000000..9e1dfaf8f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/v_controller.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include +#include + +#include "service/contract/executor/manager/concurrency_controller.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { + +class VController : public ConcurrencyController { + public: + VController(DataStorage * storage); + ~VController(); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_); + bool Commit(int64_t commit_id); + const ModifyMap * GetChangeList(int64_t commit_id) const; + +private: +bool CheckCommit(int64_t commit_id); + private: + const int window_size_ = 2000; + std::vector changes_list_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/x_committer.cpp b/platform/consensus/ordering/fides/executor/manager/x_committer.cpp new file mode 100644 index 000000000..584a8f015 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/x_committer.cpp @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/x_committer.h" + +#include + +#include "service/contract/executor/manager/local_state.h" +#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { + +namespace { + +class TimeTrack { +public: + TimeTrack(std::string name = ""){ + name_ = name; + start_time_ = GetCurrentTime(); + } + + ~TimeTrack(){ + uint64_t end_time = GetCurrentTime(); + //LOG(ERROR) << name_ <<" run:" << (end_time - start_time_)<<"ms"; + } + + double GetRunTime(){ + uint64_t end_time = GetCurrentTime(); + return (end_time - start_time_) / 1000000.0; + } +private: + std::string name_; + uint64_t start_time_; +}; + +} + +XCommitter:: XCommitter( + DataStorage * storage, + GlobalState * global_state, int worker_num):storage_(storage), gs_(global_state),worker_num_(worker_num) { + + controller_ = std::make_unique(storage); + executor_ = std::make_unique(); + is_stop_ = false; + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request_ptr = request_queue_.Pop(); + if (request_ptr == nullptr) { + continue; + } + TimeTrack track; + ExecutionContext * request = *request_ptr; + + LocalState local_state(controller_.get()); + local_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &local_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=request->RedoTime(); + } + local_state.Flesh(request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->commit_id); + resp->runtime = track.GetRunTime()*1000; + //if(resp->retry_time>1){ + //LOG(ERROR)<<"runtime:"<runtime; + //} + } + else { + resp->ret = -1; + } + resp_queue_.Push(std::move(resp)); + } + })); + cpu_set_t cpu_s; + CPU_ZERO(&cpu_s); + CPU_SET(i+1, &cpu_s); + int rc = pthread_setaffinity_np(workers_[i].native_handle(), sizeof(cpu_s), &cpu_s); + assert(rc==0); + } +} + +XCommitter::~XCommitter(){ + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + +void XCommitter::AddTask(int64_t commit_id, std::unique_ptr context){ + context_list_[commit_id] = std::move(context); +} + +void XCommitter::RemoveTask(int64_t commit_id){ + context_list_.erase(context_list_.find(commit_id)); +} + +ExecutionContext* XCommitter::GetTaskContext(int64_t commit_id){ + return context_list_[commit_id].get(); +} + +std::vector> XCommitter::ExecContract( + std::vector& requests) { + + + controller_->Clear(); + int process_num = requests.size(); + std::vector> resp_list; + + int id = 1; + for(auto& request: requests) { + request.commit_id = id++; + auto context = std::make_unique(request); + auto context_ptr = context.get(); + AddTask(request.commit_id, std::move(context)); + request_queue_.Push(std::make_unique(context_ptr)); + } + + while(process_num){ + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + int64_t resp_commit_id = resp->commit_id; + bool ret = controller_->Commit(resp_commit_id); + //LOG(ERROR)<<"resp commit:"<rws = *controller_->GetChangeList(resp_commit_id); + //LOG(ERROR)<<"get rws:"<retry_time; + resp_list.push_back(std::move(resp)); + RemoveTask(resp_commit_id); + process_num--; + continue; + } + /* + else { + auto context_ptr = GetTaskContext(resp_commit_id); + context_ptr->SetRedo(); + //LOG(ERROR)<<"redo:"<(context_ptr)); + } + */ + + std::vector list = controller_->GetRedo(); + //LOG(ERROR)<<"get list:"<SetRedo(); + //LOG(ERROR)<<"redo:"<(context_ptr)); + } + } + + return resp_list; +} + +absl::StatusOr XCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/x_committer.h b/platform/consensus/ordering/fides/executor/manager/x_committer.h new file mode 100644 index 000000000..21d3c596c --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/x_committer.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/x_controller.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/committer_context.h" +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/common/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { + +struct ExecutionState{ + std::atomic commit_time; + int redo_time = 0; +}; + +class XCommitter : public ContractCommitter { + public: + XCommitter( + DataStorage * storage, + GlobalState * global_state, int worker_num = 2); + + ~XCommitter(); + + std::vector> ExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + ExecutionContext* GetTaskContext(int64_t commit_id); + + + private: + std::unique_ptr controller_; + std::unique_ptr executor_; + DataStorage * storage_; + GlobalState* gs_; + std::vector workers_; + std::atomic is_stop_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + + std::map> context_list_; + + const int worker_num_; + ExecutionState execution_state_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/x_committer_test.cpp b/platform/consensus/ordering/fides/executor/manager/x_committer_test.cpp new file mode 100644 index 000000000..f0a7f22e2 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/x_committer_test.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/x_committer.h" + +#include + +#include "service/contract/executor/manager/mock_data_storage.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/contract_deployer.h" +#include "service/contract/executor/manager/address_manager.h" +#include "service/contract/proto/func_params.pb.h" + +#include +#include + + + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; +using ::testing::Invoke; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +class XCommitterTest : public Test { + public: + XCommitterTest() : owner_address_(get_random_address()) { + std::string contract_path = test_dir + "test_data/contract.json"; + + std::ifstream contract_fstream(contract_path); + if (!contract_fstream) { + throw std::runtime_error(fmt::format( + "Unable to open contract definition file {}", contract_path)); + } + + const auto contracts_definition = nlohmann::json::parse(contract_fstream); + const auto all_contracts = contracts_definition["contracts"]; + const auto contract_code = all_contracts["ERC20.sol:ERC20Token"]; + storage_ = std::make_unique(); + contract_json_ = contract_code; + + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool) { + return data_[address]; + })); + + EXPECT_CALL(*storage_, Store).WillRepeatedly(Invoke([&](const uint256_t& key, const uint256_t& value, bool ) { + int v = data_[key].second; + LOG(ERROR)<<"store:"<(storage_.get()); + + committer_ = std::make_unique(storage_.get(), gs_.get()); + + contract_address_ = AddressManager::CreateContractAddress(owner_address_); + deployer_ = std::make_unique(committer_.get(), gs_.get()); + contract_address_ = deployer_->DeployContract(owner_address_, contract_json_, {1000}); + } + + std::vector> ExecContract(std::vector& execute_info) { + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i+1; + } + return committer_->ExecContract(execute_info); + } + + protected: + Address owner_address_; + Address contract_address_; + nlohmann::json contract_json_; + std::unique_ptr storage_; + std::unique_ptr gs_; + std::unique_ptrcommitter_; + std::map> data_; + std::unique_ptr deployer_; +}; + +/* +TEST_F(XCommitterTest, ExecContract) { + // owner 1000 + std::vector info; + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + std::vector> resp = ExecContract(info); + EXPECT_EQ(resp.size(), 1); + EXPECT_EQ(resp[0]->ret, 0); + } +} +*/ + +// get a +// a->b +TEST_F(XCommitterTest, TwoTxnNoConflict) { + Address transfer_receiver = get_random_address(); + + // owner 1000 + std::vector info; + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + std::vector> resp = ExecContract(info); + EXPECT_EQ(resp.size(), 2); + EXPECT_EQ(resp[0]->ret, 0); + EXPECT_EQ(HexToInt(resp[0]->result), 1000); + EXPECT_EQ(resp[1]->ret, 0); + EXPECT_EQ(HexToInt(resp[1]->result), 1); + } + //LOG(ERROR)<<"commit time:"<GetExecutionState()->commit_time<<" redo time:"<GetExecutionState()->redo_time; + //EXPECT_EQ(committer_->GetExecutionState()->commit_time,2); + //EXPECT_EQ(committer_->GetExecutionState()->redo_time,0); +} + +// a->b +TEST_F(XCommitterTest, TwoTxnConflict) { + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + /* + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address) { + if(start){ + load_time[address]++; + } + return data_[address]; + })); + + EXPECT_CALL(*storage_, Store).WillRepeatedly(Invoke([&](const uint256_t& key, const uint256_t& value,bool) { + if(start) { + bool done = false; + while(!done){ + for(auto it : load_time){ + if(it.second>1){ + done = true; + break; + } + } + } + } + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + })); + + Init(); + start = true; + */ + + // owner 1000 + std::vector info; + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + std::vector> resp = ExecContract(info); + EXPECT_EQ(resp.size(), 2); + EXPECT_EQ(resp[0]->ret, 0); + EXPECT_EQ(HexToInt(resp[0]->result), 1); + EXPECT_EQ(resp[1]->ret, 0); + EXPECT_EQ(HexToInt(resp[1]->result), 1); + } + //EXPECT_EQ(committer_->GetExecutionState()->commit_time,2); + //EXPECT_EQ(committer_->GetExecutionState()->redo_time,1); +} + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/x_controller.cpp b/platform/consensus/ordering/fides/executor/manager/x_controller.cpp new file mode 100644 index 000000000..3443744f2 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/x_controller.cpp @@ -0,0 +1,241 @@ +#include "service/contract/executor/manager/x_controller.h" + +#include + +namespace resdb { +namespace contract { + +XController::XController(DataStorage * storage) : ConcurrencyController(storage){ + + for(int i = 0; i < window_size_; ++i){ + is_redo_.push_back(false); + } + + Clear(); + last_commit_id_ = 0; +} + +XController::~XController(){} + +void XController::Clear(){ + last_commit_id_=0; + + changes_list_.resize(window_size_); + pending_list_.resize(window_size_); + for(int i = 0; i < window_size_; ++i){ + changes_list_[i].clear(); + pending_list_[i].clear(); + is_redo_[i] = false; + } + commit_list_.clear(); + m_list_.clear(); +} + +void XController::UseOCC(){ + use_occ_ = true; +} + +std::vector& XController::GetRedo(){ + return redo_; +} + +int XController::GetHashKey(const uint256_t& address){ + // Get big-endian form + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%1; + //return v%128; +} + +void XController::SetCallback(CallBack call_back) { + call_back_ = call_back; +} + +void XController::RedoCommit(int64_t commit_id) { + if(is_redo_[commit_id]){ + return; + } + is_redo_[commit_id] = true; + //LOG(ERROR)<<" add redo:"< list; + for(int64_t id : redo_list_){ + if(use_occ_){ + list.insert(id); + continue; + } + const auto& change_set = changes_list_[id]; + if(change_set.empty()){ + //LOG(ERROR)<<" no commit id record found:"< 0){ + ok = 0; + break; + } + } + if(ok){ + list.insert(id); + + //LOG(ERROR)<<"redo id:"< new_commit_ids; + for(const auto& it : change_set){ + bool done = false; + for(int i = it.second.size()-1; i >=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + { + storage_->Store(it.first, op.data); + done = true; + break; + } + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first); + done = true; + break; + } + } + } + return true; +} + +bool XController::CheckCommit(int64_t commit_id) { + const auto& change_set = changes_list_[commit_id]; + if(change_set.empty()){ + LOG(ERROR)<<" no commit id record found:"<GetVersion(address); + //LOG(ERROR)<<"get version:"< +#include +#include +#include + +#include "service/contract/executor/manager/concurrency_controller.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { + +class XController : public ConcurrencyController { + public: + struct CallBack { + std::function redo_callback = nullptr; + std::function committed_callback = nullptr; + }; + + XController(DataStorage * storage); + ~XController(); + + void SetCallback(CallBack call_back); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_); + bool Commit(int64_t commit_id); + std::vector& GetRedo(); + + void Clear(); + const ModifyMap * GetChangeList(int64_t commit_id); + + void UseOCC(); + + private: + bool CommitInternal(int64_t commit_id); + bool CheckCommit(int64_t commit_id); + bool CheckFirstCommit(const uint256_t& address, int64_t commit_id); + + //int64_t Remove(const uint256_t& address, int64_t commit_id, uint64_t v); + void Remove(int64_t commit_id); + + + std::function GetCommitCallBack(int64_t commit_id); + std::function GetRedoCallBack(int64_t commit_id); + + void CommitDone(int64_t commit_id); + void RedoCommit(int64_t commit_id); + + void CheckRedo(); + void AddRedo(int64_t commit_id); + + int GetHashKey(const uint256_t& address); + + bool IsRead(const uint256_t& address, int64_t commit_id); + + private: + const int window_size_ = 4096; + mutable std::shared_mutex mutex_, mutexs_[4096], cmutex_; + + std::map first_commit_; + std::atomic last_commit_id_; + + std::vector changes_list_, pending_list_; + std::map > commit_list_; + //std::map > commit_list_[2048]; + //std::map > commit_list_[1024]; + std::map m_list_; + + std::vector is_redo_; + CallBack call_back_; + + std::vector redo_; + std::set redo_list_; + std::map ref_; + bool use_occ_ = false; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/x_verifier.cpp b/platform/consensus/ordering/fides/executor/manager/x_verifier.cpp new file mode 100644 index 000000000..911b7572a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/x_verifier.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/x_verifier.h" + +#include + +#include "service/contract/executor/manager/local_state.h" +#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { + + +XVerifier:: XVerifier( + DataStorage * storage, + GlobalState * global_state, int worker_num):storage_(storage), gs_(global_state),worker_num_(worker_num) { + + controller_ = std::make_unique(storage); + is_stop_ = false; + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request = request_queue_.Pop(); + if (request == nullptr) { + continue; + } + + LocalState local_state(controller_.get()); + local_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &local_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time++; + } + local_state.Flesh(request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->commit_id); + } + else { + resp->ret = -1; + } + resp_queue_.Push(std::move(resp)); + } + })); + } +} + +XVerifier::~XVerifier(){ + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + + +bool XVerifier::VerifyContract( + const std::vector& request_list, + const std::vector& rws_list) { + std::vector d; + std::map > g; + std::map id; + + for(int i = 0; i < rws_list.size();++i){ + d.push_back(0); + for(auto it : rws_list[i]){ + const Address& address = it.first; + //LOG(ERROR)<<"i ="< q; + for(int i = 0; i < request_list.size();++i){ + if(d[i]==0){ + auto context = std::make_unique(request_list[i]); + context->GetContractExecuteInfo()->commit_id = i; + request_queue_.Push(std::move(context)); + //LOG(ERROR)<<"add:"<0){ + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + process_num--; + int resp_commit_id = resp->commit_id; + bool ret = controller_->Commit(resp_commit_id); + if(!ret){ + return false; + } + //LOG(ERROR)<<"verify:"<GetChangeList(resp_commit_id); + if(!RWSEqual(*rws, rws_list[resp_commit_id])){ + LOG(ERROR)<<"rws not equal"; + return false; + } + for(int n_id : g[resp_commit_id]){ + //LOG(ERROR)<<"next id:"<(request_list[n_id]); + context->GetContractExecuteInfo()->commit_id = n_id; + request_queue_.Push(std::move(context)); + //LOG(ERROR)<<"add next:"<first != it2->first){ + LOG(ERROR)<<"address not equal:"<first<<" "<first; + return false; + } + if(it1->second.size() != it2->second.size()){ + LOG(ERROR)<<"item size not equal:"<second.size()<<" "<second.size(); + return false; + } + for(int i = 0; i < it1->second.size(); i++){ + if(it1->second[i] != it2->second[i]){ + LOG(ERROR)<<"data not equal:"<second[i].data<<" "<second[i].data<<" addr:"<first; + return false; + } + } + } + return true; +} + + +} // namespace contract +} // namespace resdb + diff --git a/platform/consensus/ordering/fides/executor/manager/x_verifier.h b/platform/consensus/ordering/fides/executor/manager/x_verifier.h new file mode 100644 index 000000000..e3e24f8fc --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/x_verifier.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/v_controller.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/committer_context.h" +#include "service/contract/executor/manager/contract_verifier.h" +#include "service/contract/executor/common/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { + +class XVerifier : public ContractVerifier { + public: + XVerifier( + DataStorage * storage, + GlobalState * global_state, int worker_num = 2); + + ~XVerifier(); + + bool VerifyContract( + const std::vector& request_list, + const std::vector& rws_list); + + bool RWSEqual(const ConcurrencyController :: ModifyMap&a, const ConcurrencyController :: ModifyMap&b); + + private: + DataStorage * storage_; + GlobalState* gs_; + std::vector workers_; + std::unique_ptr controller_; + std::atomic is_stop_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + const int worker_num_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/x_verifier_test.cpp b/platform/consensus/ordering/fides/executor/manager/x_verifier_test.cpp new file mode 100644 index 000000000..e95fd6171 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/x_verifier_test.cpp @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/x_verifier.h" + +#include + +#include "service/contract/executor/manager/x_committer.h" +#include "service/contract/executor/manager/mock_data_storage.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/contract_deployer.h" +#include "service/contract/executor/manager/address_manager.h" +#include "service/contract/proto/func_params.pb.h" + +#include +#include + + + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; +using ::testing::Invoke; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +class VVerifierTest : public Test { + public: + VVerifierTest() : owner_address_(get_random_address()) { + std::string contract_path = test_dir + "test_data/kv.json"; + + std::ifstream contract_fstream(contract_path); + if (!contract_fstream) { + throw std::runtime_error(fmt::format( + "Unable to open contract definition file {}", contract_path)); + } + + const auto contracts_definition = nlohmann::json::parse(contract_fstream); + const auto all_contracts = contracts_definition["contracts"]; + const auto contract_code = all_contracts["kv.sol:KV"]; + storage_ = std::make_unique(); + v_storage_ = std::make_unique(); + contract_json_ = contract_code; + + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool) { + return data_[address]; + })); + + EXPECT_CALL(*storage_, Store).WillRepeatedly(Invoke([&](const uint256_t& key, const uint256_t& value, bool ) { + int v = data_[key].second; + LOG(ERROR)<<"store:"<(storage_.get()); + + committer_ = std::make_unique(storage_.get(), gs_.get()); + + contract_address_ = AddressManager::CreateContractAddress(owner_address_); + deployer_ = std::make_unique(committer_.get(), gs_.get()); + contract_address_ = deployer_->DeployContract(owner_address_, contract_json_, {1000}); + + + v_gs_ = std::make_unique(v_storage_.get()); + + verifier_ = std::make_unique(v_storage_.get(), v_gs_.get()); + + v_deployer_ = std::make_unique(verifier_.get(), v_gs_.get()); + v_deployer_->DeployContract(owner_address_, contract_json_, {1000}, contract_address_); + } + + std::vector> ExecContract(std::vector& execute_info) { + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i+1; + } + return committer_->ExecContract(execute_info); + } + + protected: + Address owner_address_; + Address contract_address_; + nlohmann::json contract_json_; + std::unique_ptr storage_; + std::unique_ptr v_storage_; + std::unique_ptr gs_, v_gs_; + std::unique_ptrcommitter_; + std::unique_ptr verifier_; + std::map> data_; + std::unique_ptr deployer_, v_deployer_; +}; + +TEST_F(VVerifierTest, TwoTxnNoConflict) { + Address transfer_receiver = get_random_address(); + LOG(ERROR)<<"start"; + // owner 1000 + std::vector info; + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(200)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + std::vector> resp = ExecContract(info); + EXPECT_EQ(resp.size(), 2); + + std::vector new_info; + std::vector rws_list; + for(int i = 0; i < resp.size();++i){ + rws_list.push_back(resp[i]->rws); + for(int j = 0; j < info.size();++j){ + if(info[j].commit_id == resp[i]->commit_id){ + new_info.push_back(info[j]); + } + } + } + + EXPECT_TRUE(verifier_->VerifyContract(new_info, rws_list)); + + } + LOG(ERROR)<<"done"; +} + +// a->b +TEST_F(VVerifierTest, TwoTxnConflict) { + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + // owner 1000 + std::vector info; + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + std::vector> resp = ExecContract(info); + EXPECT_EQ(resp.size(), 2); + + std::vector new_info; + std::vector rws_list; + for(int i = 0; i < resp.size();++i){ + rws_list.push_back(resp[i]->rws); + for(int j = 0; j < info.size();++j){ + if(info[j].commit_id == resp[i]->commit_id){ + new_info.push_back(info[j]); + } + } + } + + EXPECT_TRUE(verifier_->VerifyContract(new_info, rws_list)); + + } +} + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/xexecutor.cpp b/platform/consensus/ordering/fides/executor/manager/xexecutor.cpp new file mode 100644 index 000000000..daecb7360 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/xexecutor.cpp @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/paral_sm/streaming_dq_committer.h" + +#include +#include + +#include "service/contract/executor/paral_sm/local_state.h" +#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + + +namespace resdb { +namespace contract { +namespace paral_sm { + +XExecutor:: XExecutor( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back, + int worker_num):storage_(storage), gs_(global_state), + worker_num_(worker_num), + window_size_(window_size), + call_back_(call_back) { + + //LOG(ERROR)<<"init window:"<(storage, window_size*2); + executor_ = std::make_unique(); + + resp_list_.resize(window_size_); + is_done_.resize(window_size_); + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + first_id_ = 0; + last_id_ = 1; + is_stop_ = false; + id_ = 1; + + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request = request_queue_.Pop(); + if (request == nullptr) { + continue; + } + + LocalState local_state(controller_.get()); + local_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &local_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + //LOG(ERROR)<<"========= get resp commit id:"<GetContractExecuteInfo()->commit_id<<" param:"<< + // request->GetContractExecuteInfo()->func_params.DebugString(); + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=request->RedoTime(); + } + local_state.Flesh(request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->commit_id); + } + else { + LOG(ERROR)<<"commit :"<commit_id<<" fail"; + resp->ret = -1; + assert(resp->ret>=0); + } + request->SetResult(resp); + resp_queue_.Push(std::move(request)); + } + })); + } + + response_ = std::thread([&]() { + while (!is_stop_) { + ResponseProcess(); + } + }); +} + +void XExecutor::SetExecuteCallBack(std::function)> func) { + call_back_ = std::move(func); +} + +XExecutor::~XExecutor(){ + //LOG(ERROR)<<"desp"; + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } + if(response_.joinable()){ + response_.join(); + } +} + +/* +void XExecutor::CallBack(uint64_t commit_id){ + //LOG(ERROR)<<"call back:"< lk(mutex_); + cv_.notify_all(); + } + //LOG(ERROR)<<"call back done:"< lk(mutex_); + cv_.wait_for(lk, std::chrono::microseconds(timeout_ms), [&] { + return id_ - first_id_ lk(mutex_); + cv_.wait_for(lk, std::chrono::microseconds(timeout_ms), [&] { + return first_id_>0&&first_id_%500==0; + //return id_ - first_id_commit_id; + int idx = resp->commit_id % window_size_; + //LOG(ERROR)<<"recv :"< q; + q.push(resp_commit_id); + while(!q.empty()){ + int64_t next_id = q.front(); + q.pop(); + + bool ret = controller_->Commit(next_id); + std::vector next_commit = controller_->GetRedo(); + //LOG(ERROR)<<"redo size:"<SetRedo(); + //LOG(ERROR)<<"redo :"<(context_ptr)); + } + else { + q.push(new_next); + } + } + + std::vector done_list = controller_->GetDone(); + for(int64_t done_id : done_list) { + //LOG(ERROR)<<"get doen id:"<commit_id; + //LOG(ERROR)<<" !!!!! commit new resp:"<Commit(current_commit_id); + if(!ret){ + //LOG(ERROR)<<"redo size:"<GetRedo().size(); + if(controller_->GetRedo().size()){ + assert(controller_->GetRedo()[0] == current_commit_id); + //redo_list.push(commit_id); + //LOG(ERROR)<<"commit redo:"<SetRedo(); + //LOG(ERROR)<<"redo :"<(context_ptr)); + } + } + else { + std::vector list = controller_->GetRedo(); + assert(list.empty()); + } + + std::vector done_list = controller_->GetDone(); + for(int64_t done_id : done_list) { + //LOG(ERROR)<<"get doen id:"<& requests) { + for(auto& request: requests) { + if(!WaitNext()){ + return; + } + request_queue_.Push(std::make_unique(request)); + } + + return ; +} + +absl::StatusOr XExecutor::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/manager/xexecutor.h b/platform/consensus/ordering/fides/executor/manager/xexecutor.h new file mode 100644 index 000000000..42e3d523c --- /dev/null +++ b/platform/consensus/ordering/fides/executor/manager/xexecutor.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/streaming_dq_controller.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/manager/committer_context.h" +#include "service/contract/executor/manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace manager { + +class XExecutor : public ContractCommitter { + public: + XExecutor( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back = nullptr, + int worker_num = 2); + + ~XExecutor(); + + void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info) { return {}; } +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + + void CallBack(uint64_t commit_id); + + private: + std::unique_ptr controller_; + std::unique_ptr executor_; + DataStorage * storage_; + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::atomic first_id_, last_id_, id_; + + LockFreeQueue> request_queue_; + LockFreeQueue resp_queue_; + std::vector> resp_list_; + std::vector is_done_; + + std::map> context_list_; + + const int worker_num_; + int window_size_; + std::function)> call_back_; + std::condition_variable cv_; + std::mutex mutex_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/BUILD b/platform/consensus/ordering/fides/executor/paral_sm/BUILD new file mode 100644 index 000000000..b048f4963 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/BUILD @@ -0,0 +1,304 @@ +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "utils", + hdrs = ["utils.h"], + deps = [ + "//third_party:evm_lib", + ], +) + +cc_library( + name = "address_manager", + srcs = ["address_manager.cpp"], + hdrs = ["address_manager.h"], + deps = [ + ":utils", + "//common:comm", + ], +) + +cc_test( + name = "address_manager_test", + srcs = ["address_manager_test.cpp"], + deps = [ + ":address_manager", + "//common/test:test_main", + ], +) + +cc_library( + name = "data_storage", + srcs = ["data_storage.cpp"], + hdrs = ["data_storage.h"], + deps = [ + ":utils", + "//common:comm", + ], +) + +cc_library( + name = "mock_data_storage", + hdrs = ["mock_data_storage.h"], + deps = [ + ":storage", + "//common/test:test" + ], +) + +cc_library( + name = "mock_d_storage", + hdrs = ["mock_d_storage.h"], + deps = [ + ":d_storage", + "//common/test:test" + ], +) + + +cc_library( + name = "d_storage", + srcs = ["d_storage.cpp"], + hdrs = ["d_storage.h"], + deps = [ + ":data_storage", + "//common:comm", + ], +) + + +cc_library( + name = "leveldb", + srcs = ["leveldb.cpp"], + hdrs = ["leveldb.h"], + deps = [ + ":data_storage", + "//common:comm", + "//storage:res_leveldb" + ], +) + +cc_library( + name = "global_view", + srcs = ["global_view.cpp"], + hdrs = ["global_view.h"], + deps = [ + ":data_storage", + "//common:comm", + ], +) + +cc_library( + name = "db_view", + srcs = ["db_view.cpp"], + hdrs = ["db_view.h"], + deps = [ + ":concurrency_controller", + ":xcontroller", + "//common:comm", + ], +) + +cc_library( + name = "executor_state", + srcs = ["executor_state.cpp"], + hdrs = ["executor_state.h"], + deps = [ + ":evm_state", + ":utils", + ":db_view", + "//common:comm", + ], +) + +cc_library( + name = "evm_state", + hdrs = ["evm_state.h"], + deps = [ + ":utils", + "//common:comm", + ], +) + +cc_library( + name = "global_state", + srcs = ["global_state.cpp"], + hdrs = ["global_state.h"], + deps = [ + ":evm_state", + ":utils", + ":global_view", + "//common:comm", + ], +) + +cc_library( + name = "local_state", + srcs = ["local_state.cpp"], + hdrs = ["local_state.h"], + deps = [ + ":evm_state", + ":utils", + ":local_view", + "//common:comm", + ], +) + +cc_library( + name = "concurrency_controller", + srcs = ["concurrency_controller.cpp"], + hdrs = ["concurrency_controller.h"], + deps = [ + ":data_storage", + ], +) + +cc_library( + name = "xcontroller", + srcs = ["xcontroller.cpp"], + hdrs = ["xcontroller.h"], + deps = [ + ":concurrency_controller", + ":d_storage", + "//platform/common/queue:lock_free_queue", + "//common:comm", + "//common/utils:utils", + ], +) + +cc_library( + name = "mock_e_controller", + hdrs = ["mock_e_controller.h"], + deps = [ + ":xcontroller", + "//common/test:test" + ], +) + +cc_library( + name = "contract_executor", + srcs = ["contract_executor.cpp"], + hdrs = ["contract_executor.h"], + deps = [ + ":evm_state", + "//common:comm", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "committer_context", + srcs = ["committer_context.cpp"], + hdrs = ["committer_context.h"], + deps = [ + ":contract_committer", + ], +) + +cc_library( + name = "contract_committer", + hdrs = ["contract_committer.h"], + deps = [ + ":contract_executor", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "local_view", + srcs = ["local_view.cpp"], + hdrs = ["local_view.h"], + deps = [ + ":concurrency_controller", + "//common:comm", + ], +) + + +cc_library( + name = "xexecutor", + srcs = ["xexecutor.cpp"], + hdrs = ["xexecutor.h"], + deps = [ + ":local_state", + ":contract_committer", + ":contract_executor", + ":committer_context", + ":xcontroller", + ":global_state", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_test( + name = "xexecutor_test", + srcs = ["xexecutor_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + "//service/contract/executor/manager/test_data:kv.json", + ], + deps = [ + ":contract_deployer", + ":address_manager", + ":mock_d_storage", + ":mock_e_controller", + ":xexecutor", + "//common/test:test_main", + ], +) + + +cc_library( + name = "contract_deployer", + srcs = ["contract_deployer.cpp"], + hdrs = ["contract_deployer.h"], + deps = [ + ":concurrency_controller", + ":contract_committer", + ":global_state", + ":address_manager", + ], +) + +cc_test( + name = "contract_deployer_test", + srcs = ["contract_deployer_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + ], + deps = [ + ":test_committer", + ":contract_deployer", + "//common/test:test_main", + ], +) + +cc_library( + name = "contract_manager", + srcs = ["contract_manager.cpp"], + hdrs = ["contract_manager.h"], + deps = [ + ":contract_deployer", + ":xexecutor", + ":global_state", + ":address_manager", + ":utils", + "//common:comm", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_test( + name = "contract_manager_test", + srcs = ["contract_manager_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + ], + deps = [ + ":contract_manager", + "//common/test:test_main", + ], +) + diff --git a/platform/consensus/ordering/fides/executor/paral_sm/address_manager.cpp b/platform/consensus/ordering/fides/executor/paral_sm/address_manager.cpp new file mode 100644 index 000000000..328a33797 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/address_manager.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/address_manager.h" + +#include + +#include "eEVM/util.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +Address AddressManager::CreateRandomAddress() { + std::vector raw(20); + std::generate(raw.begin(), raw.end(), []() { return rand(); }); + Address address = eevm::from_big_endian(raw.data(), raw.size()); + users_.insert(address); + return address; +} + +bool AddressManager::Exist(const Address& address) { + return users_.find(address) != users_.end(); +} + +Address AddressManager::CreateContractAddress(const Address& owner) { + return eevm::generate_address(owner, 0u); +} + +std::string AddressManager::AddressToHex(const Address& address) { + return eevm::to_hex_string(address); +} + +Address AddressManager::HexToAddress(const std::string& address) { + return eevm::to_uint256(address); +} + +uint256_t AddressManager::AddressToSHAKey(const Address& address) { + std::vectorcode; + code.resize(64u); + eevm::to_big_endian(address, code.data()); + //code[63]=1; + //LOG(ERROR)<<"code size:"<(code.size()), h); + //LOG(ERROR)<<"get h:"< + +#include "service/contract/executor/x_manager/utils.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class AddressManager { + public: + AddressManager() {} + + // Create an address holding a 20 byte value + Address CreateRandomAddress(); + bool Exist(const Address& address); + + static Address CreateContractAddress(const Address& owner); + + static std::string AddressToHex(const Address& address); + static Address HexToAddress(const std::string& address); + + static uint256_t AddressToSHAKey(const Address& address); + + private: + std::set
users_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/address_manager_test.cpp b/platform/consensus/ordering/fides/executor/paral_sm/address_manager_test.cpp new file mode 100644 index 000000000..cb7d7454c --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/address_manager_test.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/address_manager.h" + +#include +#include + +#include "eEVM/util.h" + +namespace resdb { +namespace contract { +namespace { + +TEST(AddressManagerTest, CreateAddress) { + Address address = AddressManager().CreateRandomAddress(); + std::array raw; + eevm::to_big_endian(address, raw.data()); + Address m = eevm::from_big_endian(raw.data() + 12, raw.size() - 12); + EXPECT_EQ(m, address); +} + +TEST(AddressManagerTest, CreateContractAddress) { + Address address = AddressManager().CreateRandomAddress(); + + Address contract_address = AddressManager::CreateContractAddress(address); + + std::array raw; + eevm::to_big_endian(contract_address, raw.data()); + Address m = eevm::from_big_endian(raw.data() + 12, raw.size() - 12); + EXPECT_EQ(m, contract_address); +} + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/committer_context.cpp b/platform/consensus/ordering/fides/executor/paral_sm/committer_context.cpp new file mode 100644 index 000000000..4a6a0d340 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/committer_context.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/paral_sm/committer_context.h" + +#include "glog/logging.h" + +namespace resdb { +namespace contract { +namespace paral_sm { + +ExecutionContext::ExecutionContext(const ContractExecuteInfo & info ) { + info_ = std::make_unique(info); +} + +const ContractExecuteInfo * ExecutionContext::GetContractExecuteInfo() const { + return info_.get(); +} + +void ExecutionContext::SetResult(std::unique_ptr result) { + result_ = std::move(result); +} + +bool ExecutionContext::IsRedo() { + return is_redo_; +} + +void ExecutionContext::SetRedo(){ + is_redo_++; +} + +int ExecutionContext::RedoTime() { + return is_redo_; +} + + +std::unique_ptr ExecutionContext::FetchResult() { + return std::move(result_); +} + +} // namespace contract +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/committer_context.h b/platform/consensus/ordering/fides/executor/paral_sm/committer_context.h new file mode 100644 index 000000000..69fbbb6ad --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/committer_context.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "service/contract/executor/paral_sm/contract_committer.h" + +namespace resdb { +namespace contract { +namespace paral_sm { + +class ExecutionContext { +public: + ExecutionContext(const ContractExecuteInfo & info ) ; + const ContractExecuteInfo * GetContractExecuteInfo() const; + + void SetRedo(); + bool IsRedo(); + int RedoTime(); + + void SetResult(std::unique_ptr result); + std::unique_ptr FetchResult(); + + private: + int is_redo_ = 0; + std::unique_ptr result_; + std::unique_ptr info_; +}; + +} // namespace contract +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/concurrency_controller.cpp b/platform/consensus/ordering/fides/executor/paral_sm/concurrency_controller.cpp new file mode 100644 index 000000000..accac4f63 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/concurrency_controller.cpp @@ -0,0 +1,17 @@ +#include "service/contract/executor/paral_sm/concurrency_controller.h" + +#include + +namespace resdb { +namespace contract { + +ConcurrencyController::ConcurrencyController(DataStorage * storage) : storage_(storage){} + +const DataStorage * ConcurrencyController::GetStorage() const { + return storage_; +} + + + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/concurrency_controller.h b/platform/consensus/ordering/fides/executor/paral_sm/concurrency_controller.h new file mode 100644 index 000000000..c1fa7df12 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/concurrency_controller.h @@ -0,0 +1,46 @@ +#pragma once + +#include "service/contract/executor/paral_sm/data_storage.h" + +#include +#include + +namespace resdb { +namespace contract { + +enum State{ + LOAD = 0, + STORE = 1, + REMOVE = 2, +}; + +struct Data{ + State state; + uint256_t data; + int64_t version; + uint256_t old_data; + int commit_version; + Data(){} + Data(const State& state):state(state){} + Data(const State& state, const uint256_t& data, int64_t version = 0) + :state(state), data(data), version(version){} + Data(const State& state, const uint256_t& data, int64_t version, const uint256_t& old_data) + :state(state), data(data), version(version), old_data(old_data){} +}; + +class ConcurrencyController { + public: + ConcurrencyController(DataStorage * storage); + + typedef std::map> ModifyMap; + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_) = 0; + + const DataStorage * GetStorage() const; + + protected: + DataStorage * storage_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/contract_committer.h b/platform/consensus/ordering/fides/executor/paral_sm/contract_committer.h new file mode 100644 index 000000000..3c0d3085f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/contract_committer.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include + +#include "service/contract/executor/paral_sm/contract_executor.h" +#include "service/contract/proto/func_params.pb.h" + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "eEVM/address.h" + +namespace resdb { +namespace contract { +namespace paral_sm { + +struct ContractExecuteInfo { + eevm::Address caller_address; + eevm::Address contract_address; + std::string func_addr; + Params func_params; + int64_t commit_id; + uint64_t user_id; + ContractExecuteInfo(){} + ContractExecuteInfo( + eevm::Address caller_address, + eevm::Address contract_address, + std::string func_addr, + Params func_params, + int64_t commit_id): caller_address(caller_address), contract_address(contract_address), func_addr(func_addr), func_params(func_params), commit_id(commit_id){} +}; + +class ContractCommitter { + public: + ContractCommitter() = default; + virtual ~ContractCommitter() = default; + + virtual std::vector> ExecContract(std::vector& request) = 0; + + virtual void AsyncExecContract(std::vector& request){}; + + virtual absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) = 0; + + virtual void SetExecuteCallBack(std::function)> ){}; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/contract_deployer.cpp b/platform/consensus/ordering/fides/executor/paral_sm/contract_deployer.cpp new file mode 100644 index 000000000..0ad900050 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/contract_deployer.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/contract_deployer.h" + +#include "service/contract/executor/x_manager/address_manager.h" + +#include +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { +namespace x_manager { +namespace { + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } + +void AppendArgToInput(std::vector& code, const uint256_t& arg) { + const auto pre_size = code.size(); + code.resize(pre_size + 32u); + eevm::to_big_endian(arg, code.data() + pre_size); + LOG(ERROR)<<"add arg:"<& code, const std::string& arg) { + AppendArgToInput(code, eevm::to_uint256(arg)); +} + +} + +ContractDeployer::ContractDeployer(ContractCommitter * committer, GlobalState * gs) + : committer_(committer), gs_(gs){} + +std::string ContractDeployer::GetFuncAddress(const Address& contract_address, + const std::string& func_name) { + return func_address_[contract_address][func_name]; +} + +void ContractDeployer::SetFuncAddress(const Address& contract_address, + const FuncInfo& func) { + func_address_[contract_address][func.func_name()] = func.hash(); +} + +Address ContractDeployer::DeployContract(const Address& owner_address, + const DeployInfo& deploy_info) { + const auto contract_address = + AddressManager::CreateContractAddress(owner_address); + + auto contract_constructor = eevm::to_bytes(deploy_info.contract_bin()); + for (const std::string& param : deploy_info.init_param()) { + AppendArgToInput(contract_constructor, param); + } + + try { + auto contract = gs_->create(contract_address, 0u, contract_constructor); + absl::StatusOr result = committer_->ExecContract( + owner_address, contract_address, + "", + {}, gs_); + + if(result.ok()){ + // set the initialized class context code. + contract.acc.set_code(eevm::to_bytes(*result)); + + for (const auto& info : deploy_info.func_info()) { + SetFuncAddress(contract_address, info); + } + return contract.acc.get_address(); + } else { + gs_->remove(contract_address); + return 0; + } + } catch (...) { + LOG(ERROR) << "Deploy throw expection"; + return 0; + } +} + +Address ContractDeployer::DeployContract(const Address& owner_address, + const nlohmann::json& contract_json, const std::vector& init_params){ + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json["bin"]); + + for (auto& func : contract_json["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + for(const uint256_t& param : init_params){ + deploy_info.add_init_param(U256ToString(param)); + } + + return DeployContract(owner_address, deploy_info); +} + +absl::StatusOr ContractDeployer::GetContract( + const Address& address) { + if (!gs_->Exists(address)) { + return absl::InvalidArgumentError("Contract not exist."); + } + + return gs_->get(address); +} + +} // namespace contract +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/contract_deployer.h b/platform/consensus/ordering/fides/executor/paral_sm/contract_deployer.h new file mode 100644 index 000000000..cb75643b3 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/contract_deployer.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class ContractDeployer { + public: + ContractDeployer(ContractCommitter * committer, GlobalState * gs); + + public: + Address DeployContract(const Address& owner_address, + const DeployInfo& deploy_info); + + Address DeployContract(const Address& owner_address, + const nlohmann::json& contract_json, const std::vector& init_params); + + absl::StatusOr GetContract(const Address& address); + std::string GetFuncAddress(const Address& contract_address, + const std::string& func_name); + + private: + void SetFuncAddress(const Address& contract_address, const FuncInfo& func); + + private: + ContractCommitter* committer_; + GlobalState* gs_; + std::map> func_address_; +}; + +} // namespace contract +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/contract_deployer_test.cpp b/platform/consensus/ordering/fides/executor/paral_sm/contract_deployer_test.cpp new file mode 100644 index 000000000..41be4ae2c --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/contract_deployer_test.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/contract_deployer.h" + +#include +#include + +#include + +#include "service/contract/executor/manager/address_manager.h" +#include "service/contract/executor/manager/test_committer.h" + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } + +class ContractDeployerTest : public Test { + public: + ContractDeployerTest() : owner_address_(get_random_address()) { + + storage_ = std::make_unique(); + gs_ = std::make_unique(storage_.get()); + execotor_ = std::make_unique(storage_.get(), gs_.get()); + + + + LOG(ERROR)<<"owner:"< storage_; + std::unique_ptr gs_; + std::unique_ptrexecotor_; +}; + +TEST_F(ContractDeployerTest, NoContract) { + ContractDeployer deployer(execotor_.get(), gs_.get()); + auto account = deployer.GetContract(1234); + EXPECT_FALSE(account.ok()); +} + +TEST_F(ContractDeployerTest, DeployContract) { + ContractDeployer deployer(execotor_.get(), gs_.get()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + deployer.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = deployer.GetContract(contract_address); + EXPECT_TRUE(account.ok()); +} + +TEST_F(ContractDeployerTest, DeployContractFromJson) { + ContractDeployer deployer(execotor_.get(), gs_.get()); + + Address contract_address = + deployer.DeployContract(owner_address_, contract_json_, {1000}); + EXPECT_GT(contract_address, 0); + auto account = deployer.GetContract(contract_address); + EXPECT_TRUE(account.ok()); +} + + + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/contract_executor.cpp b/platform/consensus/ordering/fides/executor/paral_sm/contract_executor.cpp new file mode 100644 index 000000000..1809b6062 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/contract_executor.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/paral_sm/contract_executor.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { +namespace paral_sm { + +void AppendArgToInput(std::vector& code, const uint256_t& arg) { + const auto pre_size = code.size(); + code.resize(pre_size + 32u); + eevm::to_big_endian(arg, code.data() + pre_size); +} + +void AppendArgToInput(std::vector& code, const std::string& arg) { + AppendArgToInput(code, eevm::to_uint256(arg)); +} + +absl::StatusOr ContractExecutor::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + + std::vector inputs; + if(!func_addr.empty()){ + inputs = eevm::to_bytes(func_addr); + } + for (const std::string& param : func_param.param()) { + AppendArgToInput(inputs, param); + } + + auto result = Execute(caller_address, contract_address, inputs, state); + + if (result.ok()) { + return eevm::to_hex_string(*result); + } + else { + LOG(ERROR)<<"execute fail:"<> ContractExecutor::Execute( + const Address& caller_address, const Address& contract_address, + const std::vector& input, + EVMState * state) { + // Ignore any logs produced by this transaction + eevm::NullLogHandler ignore; + eevm::Transaction tx(caller_address, ignore); + + + // Record a trace to aid debugging + eevm::Trace tr; + eevm::Processor p(*state); + + // Run the transaction + try { + const auto exec_result = + p.run(tx, caller_address, state->get(contract_address), input, 0u, &tr); + + if (exec_result.er != eevm::ExitReason::returned) { + // Print the trace if nothing was returned + if (exec_result.er == eevm::ExitReason::threw) { + return absl::InternalError( + fmt::format("Execution error: {}", exec_result.exmsg)); + } + return absl::InternalError("Deployment did not return"); + } + return exec_result.output; + } catch (...) { + return absl::InternalError(fmt::format("Execution error:")); + } +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/contract_executor.h b/platform/consensus/ordering/fides/executor/paral_sm/contract_executor.h new file mode 100644 index 000000000..ab1484642 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/contract_executor.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "service/contract/executor/paral_sm/utils.h" +#include "service/contract/executor/paral_sm/evm_state.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace paral_sm { + +struct ExecuteResp { + int ret; + absl::Status state; + int64_t commit_id; + Address contract_address; + std::string result; + int retry_time = 0; + uint64_t user_id = 0; +}; + +class ContractExecutor { + public: + ContractExecutor() = default; + + ~ContractExecutor() = default; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + absl::StatusOr> Execute( + const Address& owner_address, const Address& contract_address, + const std::vector& func_params, EVMState * state); +}; + +} // namespace contract +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/contract_executor_test.cpp b/platform/consensus/ordering/fides/executor/paral_sm/contract_executor_test.cpp new file mode 100644 index 000000000..3c14e08c5 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/contract_executor_test.cpp @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/multi_contract_executor.h" +#include "service/contract/executor/manager/contract_manager.h" + +#include +#include + +#include + +#include "service/contract/executor/manager/address_manager.h" + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +uint256_t GetAddressHash(uint256_t address){ + std::vectorcode; + code.resize(64u); + eevm::to_big_endian(address, code.data()); + code[63]=1; + + uint8_t h[32]; + eevm::keccak_256(code.data(), static_cast(code.size()), h); + return eevm::from_big_endian(h, sizeof(h)); +} + + +class MultiContractExecutorTest : public Test { + public: + MultiContractExecutorTest() : owner_address_(get_random_address()) { + std::string contract_path = test_dir + "test_data/contract.json"; + LOG(ERROR)<<"test dir:"< storage = std::make_unique(); + DataStorage * storage_ptr = storage.get(); + ContractManager manager(std::move(storage)); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + LOG(ERROR)<<"owner address:"<Load(owner_key).first, 1000); + } + +/* + // receiver 0 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(transfer_receiver)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 0); + + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 0); + } + + // transfer 400 to receiver + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(400)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 400); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + + // owner 600 + { + Address caller = get_random_address(); + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = manager.ExecContract(caller, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 600); + + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 400); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + + // transfer 200 to receiver2 from receiver + { + Params func_params; + func_params.set_func_name("approve(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_ptr->Load(transfer2_key).first, 0); + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 400); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + { + Params func_params; + func_params.set_func_name("transferFrom(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_ptr->Load(transfer2_key).first, 100); + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 300); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + */ +} +/* + +TEST_F(MultiContractExecutorTest, ExecMultiContractNoConflict) { + + std::unique_ptr storage = std::make_unique(); + DataStorage * storage_ptr = storage.get(); + ContractManager manager(std::move(storage)); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + uint256_t owner_key = GetAddressHash(owner_address_); + uint256_t transfer_key = GetAddressHash(transfer_receiver); + uint256_t transfer2_key = GetAddressHash(transfer_receiver2); + uint256_t transfer3_key = GetAddressHash(transfer_receiver3); + + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(400)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 400); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + + // transfer 200 to receiver2 from receiver + { + Params func_params; + func_params.set_func_name("approve(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(200)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } + + std::vector info; + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver3)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("transferFrom(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(200)); + + info.push_back(ContractExecuteInfo(transfer_receiver, contract_address, "", func_params, 0)); + } + std::vector> resp = manager.ExecContract(info); + EXPECT_EQ(storage_ptr->Load(transfer2_key).first, 200); + EXPECT_EQ(storage_ptr->Load(transfer3_key).first, 100); + + LOG(ERROR)<<"resp size:"<ret, 0); + EXPECT_EQ(resp[1]->ret, 0); + + EXPECT_EQ(HexToInt(resp[0]->result), 1); + EXPECT_EQ(HexToInt(resp[1]->result), 1); +} + +TEST_F(MultiContractExecutorTest, ExecMultiContractHaveConflict) { + + std::unique_ptr storage = std::make_unique(); + DataStorage * storage_ptr = storage.get(); + ContractManager manager(std::move(storage)); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + uint256_t owner_key = GetAddressHash(owner_address_); + uint256_t transfer_key = GetAddressHash(transfer_receiver); + uint256_t transfer2_key = GetAddressHash(transfer_receiver2); + uint256_t transfer3_key = GetAddressHash(transfer_receiver3); + + std::vector info; + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address, "", func_params, 0)); + } + + std::vector> resp = manager.ExecContract(info); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 800); + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 100); + EXPECT_EQ(storage_ptr->Load(transfer2_key).first, 100); + + LOG(ERROR)<<"resp size:"<ret, 0); + EXPECT_EQ(resp[1]->ret, 0); + + EXPECT_EQ(HexToInt(resp[0]->result), 1); + EXPECT_EQ(HexToInt(resp[1]->result), 1); +} +*/ + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/contract_manager.cpp b/platform/consensus/ordering/fides/executor/paral_sm/contract_manager.cpp new file mode 100644 index 000000000..95ab216c4 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/contract_manager.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/contract_manager.h" + +#include "service/contract/executor/x_manager/address_manager.h" +#include "service/contract/executor/x_manager/streaming_e_committer.h" + +#include +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +ContractManager::ContractManager(std::unique_ptr storage, + int worker_num, Options op){ + storage_ = std::move(storage); + gs_ = std::make_unique(storage_.get()); + + committer_ = std::make_unique(storage_.get(), gs_.get(), 500, nullptr, worker_num); + + deployer_ = std::make_unique(committer_.get(), gs_.get()); +} + +void ContractManager::SetExecuteCallBack(std::function resp)> func) { + committer_->SetExecuteCallBack(std::move(func)); +} + +Address ContractManager::DeployContract(const Address& owner_address, + const DeployInfo& deploy_info) { + return deployer_->DeployContract(owner_address, deploy_info); +} + +absl::StatusOr ContractManager::GetContract(const Address& address) { + return deployer_->GetContract(address); +} + +std::vector> ContractManager::ExecContract(std::vector& execute_info) { + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i+1; + } + return committer_->ExecContract(execute_info); +} + +void ContractManager::AsyncExecContract(std::vector& execute_info) { + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i+1; + } + committer_->AsyncExecContract(execute_info); +} + + +absl::StatusOr ContractManager::ExecContract( + const Address& caller_address, const Address& contract_address, + const Params& func_param) { + std::string func_addr = + deployer_->GetFuncAddress(contract_address, func_param.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << func_param.func_name(); + return absl::InvalidArgumentError("Func not exist."); + } + + absl::StatusOr result = committer_->ExecContract( + caller_address, contract_address, + func_addr, + func_param, gs_.get()); + if(result.ok()){ + return *result; + } + return result.status(); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/contract_manager.h b/platform/consensus/ordering/fides/executor/paral_sm/contract_manager.h new file mode 100644 index 000000000..bc81a2e32 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/contract_manager.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/contract_deployer.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class ContractManager { + public: + enum Options { + Streaming = 1, + }; + ContractManager(std::unique_ptr storage, + int worker_num = 2, Options op = Streaming ); + + public: + Address DeployContract(const Address& owner_address, + const DeployInfo& deploy_info); + + absl::StatusOr GetContract(const Address& address); + + absl::StatusOr ExecContract(const Address& caller_address, + const Address& contract_address, + const Params& func_param); + + std::vector> ExecContract(std::vector& execute_info); + + void AsyncExecContract(std::vector& execute_info); + + void SetExecuteCallBack(std::function resp)> func); + + private: + std::string GetFuncAddress(const Address& contract_address, + const std::string& func_name); + void SetFuncAddress(const Address& contract_address, const FuncInfo& func); + + private: + std::unique_ptr storage_; + std::unique_ptr gs_; + std::unique_ptr committer_; + std::unique_ptr deployer_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/contract_manager_test.cpp b/platform/consensus/ordering/fides/executor/paral_sm/contract_manager_test.cpp new file mode 100644 index 000000000..759a24666 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/contract_manager_test.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/contract_manager.h" + +#include +#include + +#include + +#include "service/contract/executor/manager/address_manager.h" + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +class ContractManagerTest : public Test { + public: + ContractManagerTest() : owner_address_(get_random_address()) { + LOG(ERROR)<<"owner:"<()); + auto account = manager.GetContract(1234); + EXPECT_FALSE(account.ok()); +} + +TEST_F(ContractManagerTest, DeployContract) { + ContractManager manager(std::make_unique()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); +} + +TEST_F(ContractManagerTest, InitContract) { + ContractManager manager(std::make_unique()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + LOG(ERROR)<<" deploy done:"<()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + // owner 1000 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1000); + } + + // receiver 0 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(transfer_receiver)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 0); + } + + // transfer 400 to receiver + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(400)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } + + // receiver 400 + { + Address caller = get_random_address(); + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(transfer_receiver)); + + auto result = manager.ExecContract(caller, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 400); + } + // owner 600 + { + Address caller = get_random_address(); + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = manager.ExecContract(caller, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 600); + } + + // transfer 200 to receiver2 from receiver + { + Params func_params; + func_params.set_func_name("approve(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(200)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } + { + Params func_params; + func_params.set_func_name("transferFrom(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(200)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } +} + +TEST_F(ContractManagerTest, NoFunc) { + ContractManager manager(std::make_unique()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + // owner 1000 + { + Params func_params; + func_params.set_func_name("balanceOf()"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_FALSE(result.ok()); + } +} + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/d_storage.cpp b/platform/consensus/ordering/fides/executor/paral_sm/d_storage.cpp new file mode 100644 index 000000000..56f298c61 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/d_storage.cpp @@ -0,0 +1,151 @@ +#include "service/contract/executor/paral_sm/d_storage.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +namespace { + +void InternalReset(const uint256_t& key, const uint256_t& value, int64_t version, + std::map > * db, std::shared_mutex * mutex ) { + + std::unique_lock lock(*mutex); + (*db)[key] = std::make_pair(value,version); +} + +int64_t InternalStore(const uint256_t& key, const uint256_t& value, + std::map > * db, std::shared_mutex * mutex ) { + + std::unique_lock lock(*mutex); + int64_t v = (*db)[key].second; + (*db)[key] = std::make_pair(value,v+1); + return v+1; +} + +std::pair InternalLoad(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex){ + + std::shared_lock lock(*mutex); + auto e = db->find(key); + if (e == db->end()) + return std::make_pair(0,0); + return e->second; +} + +bool InternalRemove(const uint256_t& key, + std::map > * db, + std::shared_mutex * mutex) { + + std::unique_lock lock(*mutex); + auto e = db->find(key); + if (e == db->end()) + return false; + db->erase(e); + return true; +} + +bool InternalExist(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + return db->find(key) != db->end(); +} + +int64_t InternalGetVersion(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + auto it = db->find(key); + if( it == db->end()){ + return 0; + } + return it->second.second; +} + +} + +int64_t D_Storage::StoreWithVersion(const uint256_t& key, const uint256_t& value, int version, bool is_local) { +//LOG(ERROR)<<"storage key:"< D_Storage::Load(const uint256_t& key, bool is_local_view) const { + //LOG(ERROR)<<"load key:"<second.second)<<" key:"< +#include + +#include "service/contract/executor/paral_sm/data_storage.h" + +#include "eEVM/util.h" + +namespace resdb { +namespace contract { + +class D_Storage : public DataStorage { + +public: + virtual int64_t Store(const uint256_t& key, const uint256_t& value, bool is_local); + virtual int64_t StoreWithVersion(const uint256_t& key, const uint256_t& value, int version, bool is_local); + virtual std::pair Load(const uint256_t& key, bool is_from_local_view) const; + virtual bool Remove(const uint256_t& key, bool is_local); + virtual bool Exist(const uint256_t& key, bool is_local) const; + + virtual int64_t GetVersion(const uint256_t& key, bool is_local) const; + + virtual void Reset(const uint256_t& key, const uint256_t& value, int64_t version, bool is_local); + +protected: + std::map > c_s_; + mutable std::shared_mutex mutex_; + + std::map > g_s_; + mutable std::shared_mutex g_mutex_; + +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/data_storage.cpp b/platform/consensus/ordering/fides/executor/paral_sm/data_storage.cpp new file mode 100644 index 000000000..407f9b655 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/data_storage.cpp @@ -0,0 +1,51 @@ +#include "service/contract/executor/paral_sm/data_storage.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +int64_t DataStorage::Store(const uint256_t& key, const uint256_t& value, bool) { + std::unique_lock lock(mutex_); + //LOG(ERROR)<<"store key:"< DataStorage::Load(const uint256_t& key, bool) const { + std::shared_lock lock(mutex_); + //LOG(ERROR)<<"load key:"<second; +} + +bool DataStorage::Remove(const uint256_t& key, bool) { + std::unique_lock lock(mutex_); + auto e = s.find(key); + if (e == s.end()) + return false; + s.erase(e); + return true; +} + +bool DataStorage::Exist(const uint256_t& key, bool) const { + std::shared_lock lock(mutex_); + return s.find(key) != s.end(); +} + +int64_t DataStorage::GetVersion(const uint256_t& key, bool) const{ + LOG(ERROR)<<"?????"; + std::shared_lock lock(mutex_); + auto it = s.find(key); + if( it == s.end()){ + return 0; + } + return it->second.second; +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/data_storage.h b/platform/consensus/ordering/fides/executor/paral_sm/data_storage.h new file mode 100644 index 000000000..158e54909 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/data_storage.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +#include "eEVM/util.h" + +namespace resdb { +namespace contract { + +class DataStorage { + +public: + DataStorage() = default; + virtual ~DataStorage() = default; + + virtual int64_t Store(const uint256_t& key, const uint256_t& value, bool is_local = false); + virtual std::pair Load(const uint256_t& key, bool is_local_view = false) const; + virtual bool Remove(const uint256_t& key, bool is_local = false); + virtual bool Exist(const uint256_t& key, bool is_local = false) const; + + virtual int64_t GetVersion(const uint256_t& key, bool is_local = false) const; + + virtual void Reset(const uint256_t& key, const uint256_t& value, int64_t version, bool is_local = false) {} + virtual void Flush(){}; + +protected: + std::map > s; + mutable std::shared_mutex mutex_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/db_view.cpp b/platform/consensus/ordering/fides/executor/paral_sm/db_view.cpp new file mode 100644 index 000000000..a551251d0 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/db_view.cpp @@ -0,0 +1,40 @@ +#include "service/contract/executor/paral_sm/db_view.h" + +#include "eEVM/util.h" + +#include + +namespace resdb { +namespace contract { +namespace paral_sm { + +DBView::DBView(ConcurrencyController * controller, int64_t commit_id, int version) + :controller_(static_cast(controller)), + commit_id_(commit_id), version_(version){ + } + +void DBView::store(const uint256_t& key, const uint256_t& value) { + controller_->Store(commit_id_, key, value, version_); +} + +uint256_t DBView::load(const uint256_t& key) { + return controller_->Load(commit_id_, key, version_); +} + +bool DBView::remove(const uint256_t& key) { + //LOG(ERROR)<<"remove key:"<Remove(commit_id_, key, version_); +} + +/* +void DBView::Flesh(int64_t commit_id) { + commit_id_ = commit_id; + //LOG(ERROR)<<"commit push:"<PushCommit(commit_id, local_changes_); + local_changes_.clear(); +} +*/ + + +}} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/db_view.h b/platform/consensus/ordering/fides/executor/paral_sm/db_view.h new file mode 100644 index 000000000..203ab23c6 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/db_view.h @@ -0,0 +1,41 @@ +#pragma once + +#include + +#include "service/contract/executor/paral_sm/concurrency_controller.h" +#include "eEVM/storage.h" + +namespace resdb { +namespace contract { +namespace paral_sm { + +class DBView : public eevm::Storage { + +public: + DBView(ConcurrencyController * controller, int64_t commit_id, int version); + virtual ~DBView() = default; + + void store(const uint256_t& key, const uint256_t& value) override; + uint256_t load(const uint256_t& key) override; + bool remove(const uint256_t& key) override; + + // for 2PL, once it is done, all the commit will be pushed to + // the controller to judge if it can be committed. + // During the flesh, all the changes will be removed. + void Flesh(int64_t commit_id) {} + // Commit the changes. If there is a conflict, return false. + // Make sure all other committers have pushed their changes before calling Commit. + //bool Commit(); + // Remove all the changes. + //void Abort(); + +private: + ingEController * controller_; + int64_t commit_id_; + int version_; + std::map> local_changes_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/evm_state.h b/platform/consensus/ordering/fides/executor/paral_sm/evm_state.h new file mode 100644 index 000000000..ccd0d9500 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/evm_state.h @@ -0,0 +1,23 @@ +#pragma once + +#include "eEVM/globalstate.h" + +namespace resdb { +namespace contract { + +class EVMState : public eevm::GlobalState { +public: + EVMState() = default; + virtual ~EVMState() = default; + +protected: + const eevm::Block& get_current_block() override { return block_; } + uint256_t get_block_hash(uint8_t offset) override { return 0; } + +private: + // Unused. + eevm::Block block_; +}; + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/executor_state.h b/platform/consensus/ordering/fides/executor/paral_sm/executor_state.h new file mode 100644 index 000000000..222682c70 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/executor_state.h @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include "service/contract/executor/paral_sm/db_view.h" +#include "service/contract/executor/paral_sm/concurrency_controller.h" +#include "service/contract/executor/paral_sm/evm_state.h" + +#include "eEVM/simple/simpleaccount.h" + +namespace resdb { +namespace contract { +namespace paral_sm { + + class ExecutorState : public EVMState { + public: + using StateEntry = std::pair; + + public: + ExecutorState(ConcurrencyController * controller, int64_t commit_id); + virtual ~ExecutorState() = default; + + virtual void remove(const eevm::Address& addr) override; + + // Get contract by contract address. + eevm::AccountState get(const eevm::Address& addr) override; + + bool Exists(const eevm::Address& addr); + + // Flesh the local view to the controller with a commit id. + // Once all the contracts have fleshed their changes, they should call commit. + // Return false if contract not exists. + bool Flesh(const eevm::Address& addr, int commit_id); + // Commit the changes using the commit id from the flesh. + //bool Commit(const eevm::Address& addr); + + // Create an account for the contract, which the balance is 0. + eevm::AccountState create( + const eevm::Address& addr, const uint256_t& balance, const eevm::Code& code) override; + + const eevm::SimpleAccount& GetAccount(const eevm::Address& addr) ; + void Set(const eevm::SimpleAccount& acc, int64_t commit_id, int version); + + protected: + void Insert(const StateEntry& p); + + private: + std::map accounts; + ConcurrencyController * controller_; + }; + +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/global_state.cpp b/platform/consensus/ordering/fides/executor/paral_sm/global_state.cpp new file mode 100644 index 000000000..34db1839d --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/global_state.cpp @@ -0,0 +1,52 @@ +#include "service/contract/executor/paral_sm/global_state.h" + +#include + +namespace resdb { +namespace contract { +namespace paral_sm { + +using eevm::Address; +using eevm::AccountState; +using eevm::Code; +using eevm::SimpleAccount; + + GlobalState::GlobalState(DataStorage * storage) : storage_(storage) { + } + + bool GlobalState::Exists(const eevm::Address& addr) { + return accounts.find(addr) != accounts.cend(); + } + + void GlobalState::remove(const Address& addr) { + accounts.erase(addr); + } + + AccountState GlobalState::get(const Address& addr) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()) + return acc->second; + + return create(addr, 0, {}); + } + + AccountState GlobalState::create( + const Address& addr, const uint256_t& balance, const Code& code) { + Insert({SimpleAccount(addr, balance, code), GlobalView(storage_)}); + + return get(addr); + } + + const eevm::SimpleAccount& GlobalState::GetAccount(const eevm::Address& addr) { + const auto acc = accounts.find(addr); + return acc->second.first; + } + + void GlobalState::Insert(const StateEntry& p) { + const auto ib = accounts.insert(std::make_pair(p.first.get_address(), p)); + + assert(ib.second); + } +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/global_state.h b/platform/consensus/ordering/fides/executor/paral_sm/global_state.h new file mode 100644 index 000000000..dca091e85 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/global_state.h @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include "service/contract/executor/paral_sm/global_view.h" +#include "service/contract/executor/paral_sm/evm_state.h" + +#include "eEVM/simple/simpleaccount.h" + +namespace resdb { +namespace contract { +namespace paral_sm { + + class GlobalState : public EVMState{ + public: + using StateEntry = std::pair; + + public: + GlobalState(DataStorage* storage); + virtual ~GlobalState() = default; + + virtual void remove(const eevm::Address& addr) override; + + // Get contract by contract address. + eevm::AccountState get(const eevm::Address& addr) override; + + bool Exists(const eevm::Address& addr); + + // Create an account for the contract, which the balance is 0. + eevm::AccountState create( + const eevm::Address& addr, const uint256_t& balance, const eevm::Code& code) override; + + const eevm::SimpleAccount& GetAccount(const eevm::Address& addr) ; + + protected: + void Insert(const StateEntry& p); + + private: + std::map accounts; + DataStorage* storage_; + }; + +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/global_view.cpp b/platform/consensus/ordering/fides/executor/paral_sm/global_view.cpp new file mode 100644 index 000000000..f9ce4837a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/global_view.cpp @@ -0,0 +1,27 @@ +#include "service/contract/executor/paral_sm/global_view.h" + +#include "eEVM/util.h" + +#include + +namespace resdb { +namespace contract { +namespace paral_sm { + +GlobalView::GlobalView(DataStorage* storage) :storage_(storage){ } + +void GlobalView::store(const uint256_t& key, const uint256_t& value) { + storage_->Store(key, value); +} + +uint256_t GlobalView::load(const uint256_t& key) { + return storage_->Load(key).first; +} + +bool GlobalView::remove(const uint256_t& key) { + return storage_->Remove(key); +} + +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/global_view.h b/platform/consensus/ordering/fides/executor/paral_sm/global_view.h new file mode 100644 index 000000000..a57a4b535 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/global_view.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include "service/contract/executor/paral_sm/data_storage.h" +#include "eEVM/storage.h" + +namespace resdb { +namespace contract { +namespace paral_sm { + +class GlobalView : public eevm::Storage { + +public: + GlobalView(DataStorage* storage); + virtual ~GlobalView() = default; + + void store(const uint256_t& key, const uint256_t& value) override; + uint256_t load(const uint256_t& key) override; + bool remove(const uint256_t& key) override; + +private: + DataStorage * storage_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/leveldb.cpp b/platform/consensus/ordering/fides/executor/paral_sm/leveldb.cpp new file mode 100644 index 000000000..b540aed45 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/leveldb.cpp @@ -0,0 +1,30 @@ +#include "service/contract/executor/manager/leveldb.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +LevelDB::LevelDB(){ + db_ = std::make_unique("./"); + db_->SetBatchSize(10000); +} + +void LevelDB::Flush(){ + //LOG(ERROR)<<"flush"; + for(const auto& it : s){ + std::string addr = eevm::to_hex_string(it.first); + std::string value = eevm::to_hex_string(it.second.first); + //LOG(ERROR)<<"addr:"<SetValue(addr, std::string(buf, value.size()+sizeof(it.second.second))); + delete buf; + } +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/leveldb.h b/platform/consensus/ordering/fides/executor/paral_sm/leveldb.h new file mode 100644 index 000000000..e76ca274f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/leveldb.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#include "eEVM/util.h" +#include "service/contract/executor/manager/data_storage.h" +#include "storage/res_leveldb.h" + +namespace resdb { +namespace contract { + +class LevelDB : public DataStorage { + +public: + LevelDB(); + virtual ~LevelDB() = default; + + virtual void Flush(); + +private: + std::unique_ptr db_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/local_state.cpp b/platform/consensus/ordering/fides/executor/paral_sm/local_state.cpp new file mode 100644 index 000000000..6dc0014e3 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/local_state.cpp @@ -0,0 +1,73 @@ +#include "service/contract/executor/paral_sm/local_state.h" + +#include + +namespace resdb { +namespace contract { + +using eevm::Address; +using eevm::AccountState; +using eevm::Code; +using eevm::SimpleAccount; + + LocalState::LocalState(ConcurrencyController * controller) : controller_(controller) { + } + + bool LocalState::Exists(const eevm::Address& addr) { + return accounts.find(addr) != accounts.cend(); + } + + void LocalState::remove(const Address& addr) { + accounts.erase(addr); + } + + AccountState LocalState::get(const Address& addr) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()) + return acc->second; + + return create(addr, 0, {}); + } + + AccountState LocalState::create( + const Address& addr, const uint256_t& balance, const Code& code) { + Insert({SimpleAccount(addr, balance, code), LocalView(controller_, 0)}); + return get(addr); + } + + const eevm::SimpleAccount& LocalState::GetAccount(const eevm::Address& addr) { + const auto acc = accounts.find(addr); + return acc->second.first; + } + + void LocalState::Set(const eevm::SimpleAccount& acc, int64_t commit_id) { + Insert({acc, LocalView(controller_, commit_id)}); + } + + void LocalState::Insert(const StateEntry& p) { + const auto ib = accounts.insert(std::make_pair(p.first.get_address(), p)); + + assert(ib.second); + } + + bool LocalState::Flesh(const Address& addr, int commit_id) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()){ + acc->second.second.Flesh(commit_id); + return true; + } + return false; + } + +/* + bool LocalState::Commit(const eevm::Address& addr) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()){ + return acc->second.second.Commit(); + } + return false; + } + */ + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/local_state.h b/platform/consensus/ordering/fides/executor/paral_sm/local_state.h new file mode 100644 index 000000000..90a1d02e5 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/local_state.h @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include "service/contract/executor/paral_sm/local_view.h" +#include "service/contract/executor/paral_sm/concurrency_controller.h" +#include "service/contract/executor/paral_sm/evm_state.h" + +#include "eEVM/simple/simpleaccount.h" + +namespace resdb { +namespace contract { + + class LocalState : public EVMState { + public: + using StateEntry = std::pair; + + public: + LocalState(ConcurrencyController * controller); + virtual ~LocalState() = default; + + virtual void remove(const eevm::Address& addr) override; + + // Get contract by contract address. + eevm::AccountState get(const eevm::Address& addr) override; + + bool Exists(const eevm::Address& addr); + + // Flesh the local view to the controller with a commit id. + // Once all the contracts have fleshed their changes, they should call commit. + // Return false if contract not exists. + bool Flesh(const eevm::Address& addr, int commit_id); + // Commit the changes using the commit id from the flesh. + //bool Commit(const eevm::Address& addr); + + // Create an account for the contract, which the balance is 0. + eevm::AccountState create( + const eevm::Address& addr, const uint256_t& balance, const eevm::Code& code) override; + + const eevm::SimpleAccount& GetAccount(const eevm::Address& addr) ; + void Set(const eevm::SimpleAccount& acc, int64_t commit_id); + + protected: + void Insert(const StateEntry& p); + + private: + std::map accounts; + ConcurrencyController * controller_; + }; + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/local_view.cpp b/platform/consensus/ordering/fides/executor/paral_sm/local_view.cpp new file mode 100644 index 000000000..70a828885 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/local_view.cpp @@ -0,0 +1,50 @@ +#include "service/contract/executor/paral_sm/local_view.h" + +#include "eEVM/util.h" + +#include + +namespace resdb { +namespace contract { + +LocalView::LocalView(ConcurrencyController * controller, int64_t commit_id) + :controller_(controller), + commit_id_(commit_id){ } + +void LocalView::store(const uint256_t& key, const uint256_t& value) { + //LOG(ERROR)<<"========= store key:"< load_value = controller_->GetStorage()->Load(key, /*is_from_local=*/true); + local_changes_[key].push_back(Data(STORE, value, load_value.second, load_value.first)); + } + else { + local_changes_[key].push_back(Data(STORE, value)); + } +} + +uint256_t LocalView::load(const uint256_t& key) { + //LOG(ERROR)<<"load key:"< value = controller_->GetStorage()->Load(key, /*is_from_local=*/true); + local_changes_[key].push_back(Data(LOAD, value.first, value.second)); + return value.first; + } + return it->second.back().data; +} + +bool LocalView::remove(const uint256_t& key) { + local_changes_[key].push_back(Data(REMOVE)); + return true; +} + +void LocalView::Flesh(int64_t commit_id) { + commit_id_ = commit_id; + //LOG(ERROR)<<"commit push:"<PushCommit(commit_id, local_changes_); + local_changes_.clear(); +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/local_view.h b/platform/consensus/ordering/fides/executor/paral_sm/local_view.h new file mode 100644 index 000000000..52af688a8 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/local_view.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +#include "service/contract/executor/paral_sm/concurrency_controller.h" +#include "eEVM/storage.h" + +namespace resdb { +namespace contract { + +class LocalView : public eevm::Storage { + +public: + LocalView(ConcurrencyController * controller, int64_t commit_id); + virtual ~LocalView() = default; + + void store(const uint256_t& key, const uint256_t& value) override; + uint256_t load(const uint256_t& key) override; + bool remove(const uint256_t& key) override; + + // for 2PL, once it is done, all the commit will be pushed to + // the controller to judge if it can be committed. + // During the flesh, all the changes will be removed. + void Flesh(int64_t commit_id); + // Commit the changes. If there is a conflict, return false. + // Make sure all other committers have pushed their changes before calling Commit. + //bool Commit(); + // Remove all the changes. + //void Abort(); + +private: + ConcurrencyController * controller_; + int64_t commit_id_; + std::map> local_changes_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/local_view_test.cpp b/platform/consensus/ordering/fides/executor/paral_sm/local_view_test.cpp new file mode 100644 index 000000000..f05672a9f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/local_view_test.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/local_view.h" +#include "service/contract/executor/manager/two_phase_controller.h" + +#include +#include + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +TEST(LocalViewTest, ViewChange) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + LocalView view(&controller, 0); + + EXPECT_EQ(view.load(address1), 2000) ; + view.store(address1, 3000); + EXPECT_EQ(view.load(address1), 3000) ; + + // storage still contains 2000 + EXPECT_EQ(storage.Load(address1).first, 2000); +} + +TEST(LocalViewTest, CommitChange) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + LocalView view(&controller, 0); + + EXPECT_EQ(view.load(address1), 2000) ; + view.store(address1, 3000); + EXPECT_EQ(view.load(address1), 3000) ; + + // storage still contains 2000 + EXPECT_EQ(storage.Load(address1).first, 2000); + + view.Flesh(0); + EXPECT_TRUE(controller.Commit(0)); + // Save to real storage. + EXPECT_EQ(storage.Load(address1).first, 3000); +} + +TEST(LocalViewTest, CommitConflict) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + LocalView view1(&controller, 0); + LocalView view2(&controller, 1); + + EXPECT_EQ(view1.load(address1), 2000) ; + view1.store(address1, 3000); + EXPECT_EQ(view1.load(address1), 3000) ; + + // storage still contains 2000 + EXPECT_EQ(storage.Load(address1).first, 2000); + + + EXPECT_EQ(view2.load(address1), 2000) ; + view2.store(address1, 4000); + EXPECT_EQ(view2.load(address1), 4000) ; + + // storage still contains 2000 + EXPECT_EQ(storage.Load(address1).first, 2000); + + + view1.Flesh(0); + view2.Flesh(1); + + EXPECT_FALSE(controller.Commit(1)); + EXPECT_TRUE(controller.Commit(0)); + + // Save to real storage. + EXPECT_EQ(storage.Load(address1).first, 3000); +} + + + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/mock_d_storage.h b/platform/consensus/ordering/fides/executor/paral_sm/mock_d_storage.h new file mode 100644 index 000000000..976bf9e7f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/mock_d_storage.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "gmock/gmock.h" +#include "service/contract/executor/x_manager/d_storage.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class MockDStorage : public D_Storage { + public: + typedef std::pair LoadType; + + MOCK_METHOD(int64_t, Store, (const uint256_t& key, const uint256_t& value, bool), (override)); + MOCK_METHOD(int64_t, StoreWithVersion, (const uint256_t& key, const uint256_t& value, int version, bool), (override)); + MOCK_METHOD(bool, Remove, (const uint256_t&, bool), (override)); + MOCK_METHOD(bool, Exist, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(int64_t, GetVersion, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(LoadType, Load, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(void, Reset, (const uint256_t&, const uint256_t&, int64_t, bool), (override)); +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/mock_data_storage.h b/platform/consensus/ordering/fides/executor/paral_sm/mock_data_storage.h new file mode 100644 index 000000000..f438afabc --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/mock_data_storage.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "gmock/gmock.h" +#include "service/contract/executor/manager/data_storage.h" + +namespace resdb { +namespace contract { + +class MockStorage : public DataStorage { + public: + typedef std::pair LoadType; + + MOCK_METHOD(int64_t, Store, (const uint256_t& key, const uint256_t& value), (override)); + MOCK_METHOD(bool, Remove, (const uint256_t&), (override)); + MOCK_METHOD(bool, Exist, (const uint256_t&), (const, override)); + MOCK_METHOD(int64_t, GetVersion, (const uint256_t&), (const, override)); + MOCK_METHOD(LoadType, Load, (const uint256_t&), (const, override)); +}; + +} +} // namespace resdb diff --git a/chain/storage/txn_memory_db.cpp b/platform/consensus/ordering/fides/executor/paral_sm/mock_e_controller.h similarity index 69% rename from chain/storage/txn_memory_db.cpp rename to platform/consensus/ordering/fides/executor/paral_sm/mock_e_controller.h index f16445c0e..afdfc58bd 100644 --- a/chain/storage/txn_memory_db.cpp +++ b/platform/consensus/ordering/fides/executor/paral_sm/mock_e_controller.h @@ -23,28 +23,23 @@ * */ -#include "chain/storage/txn_memory_db.h" +#pragma once -#include +#include "gmock/gmock.h" +#include "service/contract/executor/x_manager/streaming_e_controller.h" namespace resdb { +namespace contract { +namespace x_manager { -TxnMemoryDB::TxnMemoryDB() : max_seq_(0) {} +class MockEController : public StreamingEController { + public: + MockEController(DataStorage* storage, int window):StreamingEController(storage, window){} -Request* TxnMemoryDB::Get(uint64_t seq) { - std::unique_lock lk(mutex_); - if (data_.find(seq) == data_.end()) { - return nullptr; - } - return data_[seq].get(); -} + MOCK_METHOD(void, Store, (const int64_t, const uint256_t& key, const uint256_t& value, int), (override)); + MOCK_METHOD(uint256_t, Load, (const int64_t, const uint256_t&, int), (override)); +}; -void TxnMemoryDB::Put(std::unique_ptr request) { - std::unique_lock lk(mutex_); - max_seq_ = request->seq(); - data_[max_seq_] = std::move(request); } - -uint64_t TxnMemoryDB::GetMaxSeq() { return max_seq_; } - +} } // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/streaming_e_committer.cpp b/platform/consensus/ordering/fides/executor/paral_sm/streaming_e_committer.cpp new file mode 100644 index 000000000..9e247242a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/streaming_e_committer.cpp @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/streaming_e_committer.h" +#include "service/contract/executor/x_manager/executor_state.h" + +#include +#include + +#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + + +namespace resdb { +namespace contract { +namespace x_manager { + +StreamingECommitter:: StreamingECommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back, + int worker_num):storage_(storage), gs_(global_state), + worker_num_(worker_num), + window_size_(window_size), + call_back_(call_back) { + + //LOG(ERROR)<<"init window:"<(storage, window_size*2); + executor_ = std::make_unique(); + + resp_list_.resize(window_size_); + is_done_.resize(window_size_); + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + first_id_ = 0; + last_id_ = 1; + is_stop_ = false; + id_ = 1; + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request_ptr = request_queue_.Pop(); + if (request_ptr == nullptr) { + continue; + } + ExecutionContext * request = *request_ptr; + + ExecutorState executor_state(controller_.get(), request->GetContractExecuteInfo()->commit_id); + executor_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id, + request->RedoTime()); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &executor_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + //LOG(ERROR)<<"========= get resp commit id:"<GetContractExecuteInfo()->commit_id<<" param:"<< + // request->GetContractExecuteInfo()->func_params.DebugString(); + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=request->RedoTime(); + } + //local_state.Flesh(request->GetContractExecuteInfo()->contract_address, + // request->GetContractExecuteInfo()->commit_id); + } + else { + LOG(ERROR)<<"commit :"<commit_id<<" fail"; + resp->ret = -1; + assert(resp->ret>=0); + } + resp_queue_.Push(std::move(resp)); + } + })); + } + + response_ = std::thread([&]() { + while (!is_stop_) { + ResponseProcess(); + } + }); +} + +void StreamingECommitter::SetExecuteCallBack(std::function)> func) { + call_back_ = std::move(func); +} + +StreamingECommitter::~StreamingECommitter(){ + //LOG(ERROR)<<"desp"; + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } + if(response_.joinable()){ + response_.join(); + } +} + +void StreamingECommitter::SetController(std::unique_ptr controller) { + controller_ = std::move(controller); +} + +void StreamingECommitter::AddTask(int64_t commit_id, std::unique_ptr context){ + context_list_[commit_id%window_size_] = std::move(context); +} + +void StreamingECommitter::RemoveTask(int64_t commit_id){ + context_list_.erase(context_list_.find(commit_id)); +} + +ExecutionContext* StreamingECommitter::GetTaskContext(int64_t commit_id){ + return context_list_[commit_id%window_size_].get(); +} + +void StreamingECommitter::CallBack(uint64_t commit_id){ + //LOG(ERROR)<<"call back:"< lk(mutex_); + cv_.notify_all(); + } + //LOG(ERROR)<<"call back done:"< lk(mutex_); + cv_.wait_for(lk, std::chrono::microseconds(timeout_ms), [&] { + return id_ - first_id_ lk(mutex_); + cv_.wait_for(lk, std::chrono::microseconds(timeout_ms), [&] { + return first_id_>0&&first_id_%500==0; + //return id_ - first_id_commit_id; + int idx = resp->commit_id % window_size_; + //LOG(ERROR)<<"recv :"< q; + q.push(resp_commit_id); + while(!q.empty()){ + int64_t next_id = q.front(); + q.pop(); + + bool ret = controller_->Commit(next_id); + std::vector next_commit = controller_->GetRedo(); + //LOG(ERROR)<<"redo size:"<SetRedo(); + //LOG(ERROR)<<"redo :"<(context_ptr)); + } + else { + q.push(new_next); + } + } + + std::vector done_list = controller_->GetDone(); + for(int64_t done_id : done_list) { + //LOG(ERROR)<<"get doen id:"<commit_id; + //LOG(ERROR)<<" !!!!! commit new resp:"<Commit(current_commit_id); + //LOG(ERROR)<<"commit id:"<GetRedo().size(); + if(controller_->GetRedo().size()){ + assert(controller_->GetRedo()[0] == current_commit_id); + //redo_list.push(commit_id); + //LOG(ERROR)<<"commit redo:"<SetRedo(); + //LOG(ERROR)<<"redo :"<(context_ptr)); + } + } + else { + std::vector list = controller_->GetRedo(); + assert(list.empty()); + } + + std::vector done_list = controller_->GetDone(); + for(int64_t done_id : done_list) { + //LOG(ERROR)<<"get doen id:"<& requests) { + for(auto& request: requests) { + if(!WaitNext()){ + return; + } + int cur_idx = id_%window_size_; + assert(id_>=last_id_); + + request.commit_id = id_++; + auto context = std::make_unique(request); + auto context_ptr = context.get(); + + //LOG(ERROR)<<"execute:"<(context_ptr)); + } + + return ; +} + +absl::StatusOr StreamingECommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + //LOG(ERROR)<<"start:"<ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/streaming_e_committer.h b/platform/consensus/ordering/fides/executor/paral_sm/streaming_e_committer.h new file mode 100644 index 000000000..eaed943b4 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/streaming_e_committer.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/contract_executor.h" +#include "service/contract/executor/x_manager/committer_context.h" +#include "service/contract/executor/x_manager/streaming_e_controller.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class StreamingECommitter : public ContractCommitter { + public: + StreamingECommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back = nullptr, + int worker_num = 2); + + ~StreamingECommitter(); + + void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info) { return {}; } + + void SetController(std::unique_ptr controller); + +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + + void CallBack(uint64_t commit_id); + + private: + std::unique_ptr controller_; + std::unique_ptr executor_; + DataStorage * storage_; + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::atomic first_id_, last_id_, id_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + std::vector> resp_list_; + std::vector is_done_; + + std::map> context_list_; + + const int worker_num_; + int window_size_; + std::function)> call_back_; + std::condition_variable cv_; + std::mutex mutex_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/streaming_e_committer_test.cpp b/platform/consensus/ordering/fides/executor/paral_sm/streaming_e_committer_test.cpp new file mode 100644 index 000000000..b0ab8c340 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/streaming_e_committer_test.cpp @@ -0,0 +1,889 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/streaming_e_committer.h" + +#include + +#include "service/contract/executor/x_manager/mock_d_storage.h" +#include "service/contract/executor/x_manager/mock_e_controller.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/contract_deployer.h" +#include "service/contract/executor/x_manager/address_manager.h" +#include "service/contract/proto/func_params.pb.h" + +#include +#include + + +namespace resdb { +namespace contract { +namespace x_manager { +namespace { + +using ::testing::Test; +using ::testing::Invoke; + +const std::string test_dir = "/home/ubuntu/nexres//service/contract/executor/manager/"; +//const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + // std::string(getenv("TEST_WORKSPACE")) + + // "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +class StreamingECommitterTest : public Test { + public: + StreamingECommitterTest() : owner_address_(get_random_address()) { + std::string contract_path = test_dir + "test_data/kv.json"; + + std::ifstream contract_fstream(contract_path); + if (!contract_fstream) { + throw std::runtime_error(fmt::format( + "Unable to open contract definition file {}", contract_path)); + } + + const auto contracts_definition = nlohmann::json::parse(contract_fstream); + const auto all_contracts = contracts_definition["contracts"]; + const auto contract_code = all_contracts["kv.sol:KV"]; + storage_ = std::make_unique(); + contract_json_ = contract_code; + + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + if(data_.find(address) == data_.end()){ + data_[address] = g_data_[address]; + } + auto ret = is_local? data_[address]: g_data_[address]; + LOG(ERROR)<<"load:"<(storage_.get()); + + auto controller = std::make_unique(storage_.get(), 10); + controller_ = controller.get(); + + EXPECT_CALL(*controller_, Load).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& address, int version) { + return controller_->LoadInternal(commit_id, address, version); + })); + + EXPECT_CALL(*controller_, Store).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version) { + return controller_->StoreInternal(commit_id, key, value, version); + })); + + + committer_ = std::make_unique(storage_.get(), gs_.get(), 10); + committer_->SetController(std::move(controller)); + + contract_address_ = AddressManager::CreateContractAddress(owner_address_); + deployer_ = std::make_unique(committer_.get(), gs_.get()); + contract_address_ = deployer_->DeployContract(owner_address_, contract_json_, {1000}); + } + + void ExecContract(std::vector& execute_info) { + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i+1; + } + committer_->AsyncExecContract(execute_info); + } + + protected: + Address owner_address_; + Address contract_address_; + nlohmann::json contract_json_; + std::unique_ptr storage_; + std::unique_ptr gs_; + std::unique_ptrcommitter_; + MockEController* controller_; + std::map> data_, g_data_; + std::unique_ptr deployer_; +}; + +TEST_F(StreamingECommitterTest, ExecContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + { + Params func_params; + func_params.set_func_name("get(address)"); + func_params.add_param(U256ToString(owner_address_)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done.set_value(true); + }); + + { + ExecContract(info); + } + done_future.get(); + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + //LOG(ERROR)<<"owner key:"< done; + std::future done_future = done.get_future(); + std::vector info; + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + assert(resp != nullptr); + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==2){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + EXPECT_EQ(data_[owner_key].first, 800); + EXPECT_EQ(data_[recer].first, 100); + EXPECT_EQ(data_[recer2].first, 100); +} + +TEST_F(StreamingECommitterTest, ExecConflictContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + std::set ids; + EXPECT_CALL(*controller_, Load).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& address, int version) { + if(commit_id==1){ + while(ids.find(2) == ids.end()){ + sleep(1); + } + } + ids.insert(commit_id); + return controller_->LoadInternal(commit_id, address, version); + })); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==2){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + EXPECT_EQ(data_[owner_key].first, 800); + EXPECT_EQ(data_[recer].first, 100); + EXPECT_EQ(data_[recer2].first, 100); + +} + +TEST_F(StreamingECommitterTest, ExecConflictContractAhead2) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + std::map ids; + EXPECT_CALL(*controller_, Load).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& address, int version) { + if(commit_id==1){ + while(ids.find(2) == ids.end()){ + sleep(1); + } + } + LOG(ERROR)<<"======== load :"<LoadInternal(commit_id, address, version); + })); + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("get(address)"); + func_params.add_param(U256ToString(transfer_receiver3)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); + EXPECT_EQ(ids[2], 1); + EXPECT_EQ(ids[1], 0); + EXPECT_EQ(ids[3], 0); + + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + EXPECT_EQ(data_[owner_key].first, 800); + EXPECT_EQ(data_[recer].first, 100); + EXPECT_EQ(data_[recer2].first, 100); + +} + +TEST_F(StreamingECommitterTest, ExecConflictContractAhead) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + std::map ids; + EXPECT_CALL(*controller_, Load).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& address, int version) { + if(commit_id==1){ + while(ids.find(2) == ids.end()){ + sleep(1); + } + } + LOG(ERROR)<<"======== load :"<LoadInternal(commit_id, address, version); + })); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver3)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + uint256_t recer3 = AddressManager::AddressToSHAKey(transfer_receiver3); + EXPECT_EQ(data_[owner_key].first, 400); + EXPECT_EQ(data_[recer].first, 300); + EXPECT_EQ(data_[recer2].first, 300); + EXPECT_EQ(data_[recer3].first, 500); +} + +TEST_F(StreamingECommitterTest, ExecConflictPreCommitContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + std::map ids; + EXPECT_CALL(*controller_, Load).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& address, int version) { + if(commit_id==1){ + while(ids.find(2) == ids.end()){ + sleep(1); + } + } + LOG(ERROR)<<"======== load :"<LoadInternal(commit_id, address, version); + })); + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + uint256_t recer3 = AddressManager::AddressToSHAKey(transfer_receiver3); + EXPECT_EQ(data_[owner_key].first, 400); + EXPECT_EQ(data_[recer].first, 300); + EXPECT_EQ(data_[recer2].first, 800); +} + +TEST_F(StreamingECommitterTest, ExecConflictPreCommitContract2) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + if(is_local){ + if(data_.find(address) == data_.end()){ + data_[address] = g_data_[address]; + } + } + if(is_local){ + load_time[address]++; + } + auto ret = is_local? data_[address]: g_data_[address]; + LOG(ERROR)<<"load add:"<1){ + done = true; + break; + } + } + } + } + + if(is_local){ + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + } + else { + int v = g_data_[key].second; + g_data_[key] = std::make_pair(value, v+1); + } + return 1; + })); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + start = true; + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + uint256_t recer3 = AddressManager::AddressToSHAKey(transfer_receiver3); + EXPECT_EQ(data_[owner_key].first, 900); + EXPECT_EQ(data_[recer].first, 300); + EXPECT_EQ(data_[recer2].first, 300); +} + +TEST_F(StreamingECommitterTest, ExecConflictCommitContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + if(is_local){ + if(data_.find(address) == data_.end()){ + data_[address] = g_data_[address]; + } + } + if(is_local){ + load_time[address]++; + } + auto ret = is_local? data_[address]: g_data_[address]; + LOG(ERROR)<<"load add:"<1){ + done = true; + break; + } + } + } + } + + if(is_local){ + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + } + else { + int v = g_data_[key].second; + g_data_[key] = std::make_pair(value, v+1); + } + return 1; + })); + + EXPECT_CALL(*storage_, Reset).WillRepeatedly(Invoke([&](const uint256_t& key, const uint256_t& value, int64_t version, bool is_local) { + LOG(ERROR)<<"reset key:"< done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + start = true; + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + uint256_t recer3 = AddressManager::AddressToSHAKey(transfer_receiver3); + EXPECT_EQ(data_[owner_key].first, 400); + EXPECT_EQ(data_[recer].first, 800); + EXPECT_EQ(data_[recer2].first, 300); + +} + +// rollback two columns +TEST_F(StreamingECommitterTest, ExecConflictCommitContract2) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + std::set pre_ids; + controller_->SetPrecommitCallback([&](int64_t id){ + pre_ids.insert(id); + }); + + std::map ids; + EXPECT_CALL(*controller_, Load).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& address, int version) { + if(commit_id==2 && version>0){ + while(pre_ids.size()<5){ + LOG(ERROR)<<"======== load :"<LoadInternal(commit_id, address, version); + })); + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + Address transfer_receiver4 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver3)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver3)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"!!!!! get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==6){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + uint256_t recer3 = AddressManager::AddressToSHAKey(transfer_receiver3); + LOG(ERROR)<<"recr:"< +#include +#include + +#include "common/utils/utils.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +namespace { + + int GetHashKey(const uint256_t& address){ + // Get big-endian form + uint8_t arr[32] = {}; + memset(arr,0,sizeof(arr)); + intx::be::store(arr, address); + uint32_t v = 0; + for(int i = 0; i < 32; ++i){ + v += arr[i]; + } + return v%128; + } + + + void AppendRecord(const uint256_t& address, + int64_t commit_id, StreamingEController::CommitList * commit_list) { + int hash_idx = GetHashKey(address); + auto& commit_set = commit_list[hash_idx][address]; + if(!commit_set.empty()&& commit_set.back() > commit_id){ + //LOG(ERROR)<<"append to old data:"<(storage)){ + for(int i = 0; i < 32; i++){ + if((1<window_size_){ + window_size_ = (1< precommit_callback) { + precommit_callback_ = std::move(precommit_callback); +} + +void StreamingEController::Clear(){ + last_commit_id_=1; + current_commit_id_=1; + last_pre_commit_id_=0; + + assert(window_size_+1<=1024); + //is_redo_.resize(window_size_+1); + //is_done_.resize(window_size_+1); + changes_list_.resize(window_size_+1); + rechanges_list_.resize(window_size_+1); + + for(int i = 0; i < window_size_; ++i){ + changes_list_[i].clear(); + rechanges_list_[i].clear(); + is_redo_[i] = 0; + //is_done_[i] = false; + } + + for(int i = 0; i < 1024; ++i){ + commit_list_[i].clear(); + pre_commit_list_[i].clear(); + } +} + +std::vector& StreamingEController::GetRedo(){ + return redo_; +} + +std::vector& StreamingEController::GetDone(){ + return done_; +} + +class TimeTrack { +public: + TimeTrack(std::string name = ""){ + name_ = name; + start_time_ = GetCurrentTime(); + } + + ~TimeTrack(){ + uint64_t end_time = GetCurrentTime(); + LOG(ERROR) << name_ <<" run:" << (end_time - start_time_)<<"ms"; + } + + double GetRunTime(){ + uint64_t end_time = GetCurrentTime(); + return (end_time - start_time_) / 1000000.0; + } +private: + std::string name_; + uint64_t start_time_; +}; + + +// ======================================================== +void StreamingEController::StoreInternal(const int64_t commit_id, const uint256_t& address, const uint256_t& value, int version) { + Data data = Data(STORE, value); + AppendPreRecord(address, commit_id, data, version); + //LOG(ERROR)<<"store data commit id:"< lk(mutex_[hash_idx]); + std::unique_lock lock(mutex_[hash_idx]); + + auto& commit_set = pre_commit_list_[hash_idx][address]; + auto it = commit_set.find(commit_id); + if(it == commit_set.end() || it->second.commit_version != version){ + it = commit_set.insert(std::make_pair(commit_id,Data())).first; + if(it == commit_set.begin()){ + auto ret = storage_->Load(address, true); + data.old_data = ret.first; + data.version = ret.second; + //LOG(ERROR)<<"get from db:"<second.data; + data.version = pt->second.version; + //LOG(ERROR)<<"get from pre:"<first<<" ver:"<second.version; + } + } + else { + data.old_data = it->second.data; + data.version= it->second.version; + //LOG(ERROR)<<"get from self:"<first<<" ver:"<second.version<<" commit ver:"<second.commit_version; + } + + if(data.state == LOAD){ + data.data = data.old_data; + } + else { + data.version += 1; + } + //LOG(ERROR)<<"!!!!! append id:"<second = data; + } + + int idx = commit_id&window_size_; + auto& change_set = changes_list_[idx][address]; + if(change_set.empty()){ + change_set.push_back(data); + } + else { + int old_version = change_set.front().commit_version; + if(old_version != version){ + for(auto it : changes_list_[idx]){ + if(rechanges_list_[idx].find(it.first) == rechanges_list_[idx].end()){ + rechanges_list_[idx][it.first].push_back(it.second.front()); + } + } + changes_list_[idx].clear(); + } + + auto& change_set = changes_list_[idx][address]; + if(change_set.empty()){ + change_set.push_back(data); + } + else if(data.state != LOAD && !change_set.empty()){ + if(change_set.back().state != LOAD){ + change_set.pop_back(); + } + change_set.push_back(data); + } + assert(change_set.size()<3); + } + return; +} + + +// ========================================== + +void StreamingEController::AppendPreRecord(const uint256_t& address, int hash_idx, + const std::vector& commit_id) { + //std::lock_guard lk(mutex_[hash_idx]); + std::unique_lock lock(mutex_[hash_idx]); + auto& commit_set = pre_commit_list_[hash_idx][address]; + for(auto id : commit_id){ + //LOG(ERROR)<<"roll back id:"< lk(mutex_[idx]); + std::unique_lock lock(mutex_[idx]); + auto it = pre_commit_list_[idx].find(address); + if(it == pre_commit_list_[idx].end()){ + //LOG(ERROR)<<" remove address:"<first != commit_id){ + //LOG(ERROR)<< "address id::"<first; + return -2; + } + //LOG(ERROR)<< "address id::"<first; +} + + +void StreamingEController::Remove(int64_t commit_id){ + //LOG(ERROR)<<"remove:"< new_commit_ids; + for(auto it : rechanges_list_[idx]){ + const uint256_t& addr = it.first; + int64_t next_commit_id = RemovePrecommitRecord(addr, commit_id); + + //LOG(ERROR)<<"remove id:"< 0 && next_commit_id <= last_pre_commit_id_){ + //LOG(ERROR)<<"commit id:"<second; + if(commit_set.empty()){ + //LOG(ERROR)<<"commit set is empty:"< commit_id){ + //LOG(ERROR)<<"set header:"< lk(mutex_[idx]); + std::shared_lock lock(mutex_[idx]); + const auto& it = pre_commit_list_[idx].find(address); + if(it == pre_commit_list_[idx].end()){ + //LOG(ERROR)<<"no address:"<second; + if(commit_set.empty()){ + //LOG(ERROR)<<"commit set is empty:"<first < commit_id){ + // not the first candidate + //LOG(ERROR)<<"still have dep. commit id:"<first<<" address:"<first > commit_id){ + //LOG(ERROR)<<"set header:"<first<<" current:"<first == commit_id); + return true; +} + + +bool StreamingEController::CheckCommit(int64_t commit_id, bool is_pre){ + int idx = commit_id&window_size_; + //LOG(ERROR)<<"check commit "<GetVersion(it.first, is_pre); + //LOG(ERROR)<<"op log:"<Reset(address, data.data, data.version, true); + }else { + storage_->Reset(address, data.old_data, data.version, true); + } +} + + +void StreamingEController::RedoConflict(int64_t commit_id) { + //LOG(ERROR)<<"move conflict id:"<, std::greater>q; + std::set v; + q.push(commit_id); + v.insert(commit_id); + + while(!q.empty()){ + int64_t cur_id = q.top(); + q.pop(); + const auto& change_set = changes_list_[cur_id&window_size_]; + + for(const auto& it : change_set){ + const uint256_t& address = it.first; + int hash_idx = GetHashKey(address); + if(commit_list_[hash_idx].find(address) == commit_list_[hash_idx].end()){ + continue; + } + //LOG(ERROR)<<"check commit id:"<version; + auto& commit_set = commit_list_[hash_idx][address]; + + std::vector back_list; + while(!commit_set.empty() && commit_set.back() >= cur_id){ + int64_t back_id = commit_set.back(); + commit_set.pop_back(); + + back_list.push_back(back_id); + if(v.find(back_id) == v.end()){ + q.push(back_id); + v.insert(back_id); + } + if(back_id == cur_id) { + break; + } + } + //LOG(ERROR)<<"hahs list size:"<second.begin()); + } + if(cur_id == commit_id){ + back_list.push_back(commit_id); + } + AppendPreRecord(address, hash_idx, back_list); + } + } +} + + +bool StreamingEController::CheckPreCommit(int64_t commit_id) { + //LOG(ERROR)<<"check pre commit:"< commit_id){ + return false; + } + } + return true; +} + + +bool StreamingEController::PreCommit(int64_t commit_id){ + //LOG(ERROR)<<" precommit :"< new_commit_ids; + for(const auto& it : change_set){ + const uint256_t& address = it.first; + //LOG(ERROR)<<"get pre-op:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<StoreWithVersion(it.first, op.data, op.version, true); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, true); + done = true; + break; + } + } + + //LOG(ERROR)<<"append id:"<=-1); + if(next_commit_id> 0 && next_commit_id <= last_pre_commit_id_){ + //LOG(ERROR)<<"commit id:"<last_pre_commit_id_){ + assert(1==0); + } + */ + } + + for(int64_t redo_commit: new_commit_ids){ + RedoCommit(redo_commit, 1); + } + //LOG(ERROR)<<"done:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<StoreWithVersion(it.first, op.data, op.version, false); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, false); + done = true; + break; + } + } + RemoveRecord(address, commit_id, commit_list_); + } + + CommitDone(commit_id); + Remove(commit_id); + assert(last_commit_id_ == commit_id); + last_commit_id_++; + return true; +} + + +bool StreamingEController::Commit(int64_t commit_id){ + redo_.clear(); + done_.clear(); + is_redo_[commit_id&window_size_] = false; + //LOG(ERROR)<<"====================== commit id:"< +#include +#include +#include + +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/d_storage.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class StreamingEController : public ConcurrencyController { + public: + StreamingEController(DataStorage * storage, int window_size); + virtual ~StreamingEController(); + + // ============================== + virtual void Store(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + virtual uint256_t Load(const int64_t commit_id, const uint256_t& key, int version); + bool Remove(const int64_t commit_id, const uint256_t& key, int version); + + + // ============================== + typedef std::map > CommitList; + typedef std::map > PreCommitList; + + std::vector& GetRedo(); + std::vector& GetDone(); + + void PushCommit(int64_t commit_id, const ModifyMap& local_changes_){} + bool Commit(int64_t commit_id); + + void StoreInternal(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + uint256_t LoadInternal(const int64_t commit_id, const uint256_t& key, int version); + void SetPrecommitCallback( std::function precommit_callback); + + private: + void Clear(); + + + bool PreCommit(int64_t commit_id); + bool PostCommit(int64_t commit_id); + + void RedoConflict(int64_t commit_id); + bool CheckPreCommit(int64_t commit_id); + bool CheckFirstFromPreCommit(const uint256_t& address, int64_t commit_id); + bool CheckFirstFromCommit(const uint256_t& address, int64_t commit_id); + /* + bool PreCommitInternal(int64_t commit_id); + void MergeChangeList(int64_t commit_id); + + + bool CheckCommit(int64_t commit_id, const CommitList *commit_list, bool is_pre); + + const ModifyMap * GetChangeList(int64_t commit_id); + */ + void Remove(int64_t commit_id); + void CleanOldData(int64_t commit_id); + + int64_t RemovePrecommitRecord(const uint256_t& address, int64_t commit_id); + + bool CheckCommit(int64_t commit_id, bool is_pre); + void CommitDone(int64_t commit_id); + void RedoCommit(int64_t commit_id, int flag); + +/* + + bool IsRead(const uint256_t& address, int64_t commit_id); + + */ + + void RollBackData(const uint256_t& address, const Data& data); + + void AppendPreRecord(const uint256_t& address, + int64_t commit_id, Data& data, int version); + void AppendPreRecord(const uint256_t& address, int hash_idx, + const std::vector& commit_id); + + private: + int window_size_ = 1000; + + std::vector changes_list_,rechanges_list_; + + CommitList commit_list_[1024]; + int64_t last_commit_id_, current_commit_id_; + + PreCommitList pre_commit_list_[1024] GUARDED_BY(mutex_); + int64_t last_pre_commit_id_; + + std::atomic is_redo_[1024]; + std::vector redo_; + + //std::atomic is_done_[1024]; + std::vector done_; + + D_Storage * storage_; + //std::mutex mutex_[1024]; + mutable std::shared_mutex mutex_[1024]; + + + std::function precommit_callback_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/test_committer.cpp b/platform/consensus/ordering/fides/executor/paral_sm/test_committer.cpp new file mode 100644 index 000000000..e69912d0b --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/test_committer.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/test_committer.h" + +#include "glog/logging.h" +//#include "eEVM/processor.h" + +namespace resdb { +namespace contract { + +TestCommitter:: TestCommitter( + DataStorage* storage, + GlobalState * global_state):gs_(global_state) { + + controller_ = std::make_unique(storage); + executor_ = std::make_unique(); +} + +TestCommitter::~TestCommitter(){ +} + +std::vector> TestCommitter::ExecContract( + const std::vector& requests) { + + std::vector > resp_list; + for(const auto& request: requests){ + std::unique_ptr resp = std::make_unique(); + //auto start_time = GetCurrentTime(); + auto ret = ExecContract(request.caller_address, request.contract_address, + request.func_addr, + request.func_params, gs_); + resp->state = ret.status(); + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + } + else { + LOG(ERROR)<<"exec fail"; + resp->ret = -1; + } + resp->contract_address = request.contract_address; + resp->commit_id = request.commit_id; + + resp_list.push_back(std::move(resp)); + } + return resp_list; +} + +absl::StatusOr TestCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/test_committer.h b/platform/consensus/ordering/fides/executor/paral_sm/test_committer.h new file mode 100644 index 000000000..0d98bafba --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/test_committer.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include + +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/test_controller.h" +#include "service/contract/proto/func_params.pb.h" + +#include "absl/status/statusor.h" + +namespace resdb { +namespace contract { + +class TestCommitter : public ContractCommitter { + public: + TestCommitter( + DataStorage* storage, + GlobalState * global_state); + + virtual ~TestCommitter(); + + std::vector> ExecContract(const std::vector& request); + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + private: + std::unique_ptr controller_; + GlobalState* gs_; + std::unique_ptr executor_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/test_controller.cpp b/platform/consensus/ordering/fides/executor/paral_sm/test_controller.cpp new file mode 100644 index 000000000..97edd57ed --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/test_controller.cpp @@ -0,0 +1,35 @@ +#include "service/contract/executor/manager/test_controller.h" + +#include + +namespace resdb { +namespace contract { + +TestController::TestController(DataStorage * storage) : ConcurrencyController(storage){} + +void TestController::PushCommit(int64_t commit_id, const ModifyMap& local_changes) { + for(auto it : local_changes){ + bool done = false; + for(int i = it.second.size()-1; i >=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<Store(it.first, op.data); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first); + done = true; + break; + } + } + } + return ; +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/paral_sm/test_controller.h b/platform/consensus/ordering/fides/executor/paral_sm/test_controller.h new file mode 100644 index 000000000..a4371033a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/test_controller.h @@ -0,0 +1,19 @@ +#pragma once + +#include "service/contract/executor/manager/concurrency_controller.h" + +#include +#include + +namespace resdb { +namespace contract { + +class TestController : public ConcurrencyController { + public: + TestController(DataStorage * storage); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_); +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/test_data/BUILD b/platform/consensus/ordering/fides/executor/paral_sm/test_data/BUILD new file mode 100644 index 000000000..6f9052157 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/test_data/BUILD @@ -0,0 +1 @@ +exports_files(["contract.json", "kv.json"]) diff --git a/platform/consensus/ordering/fides/executor/paral_sm/test_data/compile.sh b/platform/consensus/ordering/fides/executor/paral_sm/test_data/compile.sh new file mode 100644 index 000000000..dfd25e66f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/test_data/compile.sh @@ -0,0 +1,5 @@ +# sudo add-apt-repository ppa:ethereum/ethereum +# sudo apt-get update +# sudo apt-get install solc +solc --evm-version homestead --combined-json bin,hashes --pretty-json --optimize kv.sol > kv.json + diff --git a/platform/consensus/ordering/fides/executor/paral_sm/test_data/contract.json b/platform/consensus/ordering/fides/executor/paral_sm/test_data/contract.json new file mode 100644 index 000000000..e9c0d972f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/test_data/contract.json @@ -0,0 +1,19 @@ +{ + "contracts": + { + "ERC20.sol:ERC20Token": + { + "bin": "608060405234801561001057600080fd5b506040516104423803806104428339818101604052602081101561003357600080fd5b50516000818155338152600160205260409020556103ec806100566000396000f3fe608060405234801561001057600080fd5b506004361061007e577c01000000000000000000000000000000000000000000000000000000006000350463095ea7b3811461008357806318160ddd146100c357806323b872dd146100dd57806370a0823114610113578063a9059cbb14610139578063dd62ed3e14610165575b600080fd5b6100af6004803603604081101561009957600080fd5b50600160a060020a038135169060200135610193565b604080519115158252519081900360200190f35b6100cb6101fa565b60408051918252519081900360200190f35b6100af600480360360608110156100f357600080fd5b50600160a060020a03813581169160208101359091169060400135610200565b6100cb6004803603602081101561012957600080fd5b5035600160a060020a03166102e6565b6100af6004803603604081101561014f57600080fd5b50600160a060020a038135169060200135610301565b6100cb6004803603604081101561017b57600080fd5b50600160a060020a038135811691602001351661038c565b336000818152600260209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b60005490565b600160a060020a038316600090815260016020526040812054821180159061024b5750600160a060020a03841660009081526002602090815260408083203384529091529020548211155b156102db57600160a060020a038085166000818152600160209081526040808320805488900390559387168083528483208054880190559282526002815283822033808452908252918490208054879003905583518681529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35060016102df565b5060005b9392505050565b600160a060020a031660009081526001602052604090205490565b3360009081526001602052604081205482116103845733600081815260016020908152604080832080548790039055600160a060020a03871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35060016101f4565b5060006101f4565b600160a060020a0391821660009081526002602090815260408083209390941682529190915220549056fea265627a7a72315820e4ae92c4517e475d9f77ac0bfcd10463a09239f34734fc0ab4d7966450fb428464736f6c63430005100032", + "hashes": + { + "allowance(address,address)": "dd62ed3e", + "approve(address,uint256)": "095ea7b3", + "balanceOf(address)": "70a08231", + "totalSupply()": "18160ddd", + "transfer(address,uint256)": "a9059cbb", + "transferFrom(address,address,uint256)": "23b872dd" + } + } + }, + "version": "0.5.16+commit.9c3226ce.Linux.g++" +} diff --git a/platform/consensus/ordering/fides/executor/paral_sm/test_data/kv.json b/platform/consensus/ordering/fides/executor/paral_sm/test_data/kv.json new file mode 100644 index 000000000..87891db72 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/test_data/kv.json @@ -0,0 +1,18 @@ +{ + "contracts": + { + "kv.sol:KV": + { + "bin": "608060405234801561001057600080fd5b5060405161052338038061052383398101604081905261002f91610044565b3360009081526020819052604090205561005d565b60006020828403121561005657600080fd5b5051919050565b6104b78061006c6000396000f3fe608060405234801561001057600080fd5b5060043610610073577c01000000000000000000000000000000000000000000000000000000006000350463239b83eb81146100785780633825d828146100a0578063beabacc8146100b3578063c2bc2efc146100c6578063cfc9c3f9146100fd575b600080fd5b61008b610086366004610359565b610110565b60405190151581526020015b60405180910390f35b61008b6100ae3660046103a4565b6101d6565b61008b6100c13660046103ce565b61021e565b6100ef6100d436600461040a565b600160a060020a031660009081526020819052604090205490565b604051908152602001610097565b61008b61010b3660046103ce565b6102a3565b600160a060020a0384166000908152602081905260408120548281111561015f57600160a060020a0386166000908152602081905260408120805485929061015990849061045b565b90915550505b61032081101561019c57600160a060020a0385166000908152602081905260408120805485929061019190849061046e565b909155506101ca9050565b600160a060020a038416600090815260208190526040812080548592906101c490849061046e565b90915550505b50600195945050505050565b600160a060020a0382166000908152602081905260408120546101f9818461046e565b600160a060020a03851660009081526020819052604090205550600190505b92915050565b600160a060020a03831660009081526020819052604081205482101561026c57600160a060020a0384166000908152602081905260408120805484929061026690849061045b565b90915550505b600160a060020a0383166000908152602081905260408120805484929061029490849061046e565b90915550600195945050505050565b3360009081526020819052604081208054908390836102c2838561045b565b909155505061032081101561030457600160a060020a038516600090815260208190526040812080548592906102f990849061046e565b909155506103329050565b600160a060020a0384166000908152602081905260408120805485929061032c90849061046e565b90915550505b506001949350505050565b8035600160a060020a038116811461035457600080fd5b919050565b6000806000806080858703121561036f57600080fd5b6103788561033d565b93506103866020860161033d565b92506103946040860161033d565b9396929550929360600135925050565b600080604083850312156103b757600080fd5b6103c08361033d565b946020939093013593505050565b6000806000606084860312156103e357600080fd5b6103ec8461033d565b92506103fa6020850161033d565b9150604084013590509250925092565b60006020828403121561041c57600080fd5b6104258261033d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156102185761021861042c565b808201808211156102185761021861042c56fea2646970667358221220cfe0598bf227525b3a229778738f57a355eb5f0f171527891e3413c58bbffbd964736f6c63430008130033", + "hashes": + { + "get(address)": "c2bc2efc", + "set(address,uint256)": "3825d828", + "transfer(address,address,uint256)": "beabacc8", + "transferif(address,address,address,uint256)": "239b83eb", + "transferto(address,address,uint256)": "cfc9c3f9" + } + } + }, + "version": "0.8.19+commit.7dd6d404.Linux.g++" +} diff --git a/platform/consensus/ordering/fides/executor/paral_sm/test_data/kv.sol b/platform/consensus/ordering/fides/executor/paral_sm/test_data/kv.sol new file mode 100644 index 000000000..f5bfed426 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/test_data/kv.sol @@ -0,0 +1,59 @@ +pragma solidity >= 0.5.0; + +// Transfer tokens from the contract owner +contract KV { + mapping (address => uint256) balances; + mapping (address => uint256) allow; + + constructor(uint256 s) public { + balances[msg.sender] = s; + } + + // Get the account balance of another account with address _owner + function get(address _owner) public view returns (uint256) { + return balances[_owner]; + } + + // Send _value amount of tokens to address _to + function set(address _to, uint256 _value) public returns (bool) { + uint256 values = balances[_to]; + balances[_to] = _value + values; + return true; + } + + // Send _value amount of tokens to address _to + function transfer(address _from, address _to, uint256 _value) public returns (bool) { + if (balances[_from] > _value) { + balances[_from] -= _value; + } + balances[_to] += _value; + return true; + } + + function transferif(address _from, address _to1, address _to2, uint256 _value) public returns (bool) { + uint256 value = balances[_from]; + + if (balances[_from] > _value) { + balances[_from] -= _value; + } + if (value < 800 ) { + balances[_to1] += _value; + } else { + balances[_to2] += _value; + } + return true; + } + + function transferto(address _to1, address _to2, uint256 _value) public returns (bool) { + uint256 value = balances[msg.sender]; + balances[msg.sender] -= _value; + if (value < 800 ) { + balances[_to1] += _value; + } else { + balances[_to2] += _value; + } + return true; + } + +} + diff --git a/platform/consensus/ordering/fides/executor/paral_sm/utils.h b/platform/consensus/ordering/fides/executor/paral_sm/utils.h new file mode 100644 index 000000000..2d243d66f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/utils.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "eEVM/address.h" + +namespace resdb { +namespace contract { + +typedef eevm::Address Address; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/xcommitter.h b/platform/consensus/ordering/fides/executor/paral_sm/xcommitter.h new file mode 100644 index 000000000..eaed943b4 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/xcommitter.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/contract_executor.h" +#include "service/contract/executor/x_manager/committer_context.h" +#include "service/contract/executor/x_manager/streaming_e_controller.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class StreamingECommitter : public ContractCommitter { + public: + StreamingECommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back = nullptr, + int worker_num = 2); + + ~StreamingECommitter(); + + void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info) { return {}; } + + void SetController(std::unique_ptr controller); + +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + + void CallBack(uint64_t commit_id); + + private: + std::unique_ptr controller_; + std::unique_ptr executor_; + DataStorage * storage_; + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::atomic first_id_, last_id_, id_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + std::vector> resp_list_; + std::vector is_done_; + + std::map> context_list_; + + const int worker_num_; + int window_size_; + std::function)> call_back_; + std::condition_variable cv_; + std::mutex mutex_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/xcontroller.cpp b/platform/consensus/ordering/fides/executor/paral_sm/xcontroller.cpp new file mode 100644 index 000000000..41e8a5bd6 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/xcontroller.cpp @@ -0,0 +1,605 @@ +#include "service/contract/executor/paral_sm/xcontroller.h" + +#include +#include +#include + +namespace resdb { +namespace contract { +namespace paral_sm { + +namespace { + + int GetHashKey(const uint256_t& address){ + // Get big-endian form + uint8_t arr[32] = {}; + memset(arr,0,sizeof(arr)); + intx::be::store(arr, address); + uint32_t v = 0; + for(int i = 0; i < 32; ++i){ + v += arr[i]; + } + return v%128; + } + + bool CheckFirstCommit(const uint256_t& address, int64_t commit_id, + const XController::CommitList *commit_list, bool is_pre){ + int idx = GetHashKey(address); + const auto& it = commit_list[idx].find(address); + if(it == commit_list[idx].end()){ + if(is_pre){ + LOG(ERROR)<<"no address:"<second; + if(commit_set.empty()){ + LOG(ERROR)<<"commit set is empty:"< commit_id){ + LOG(ERROR)<<"set header:"<<*commit_set.begin()<<" current:"< commit_id){ + LOG(ERROR)<<"append to old data:"<& commit_id, XController::CommitList * commit_list) { + auto& commit_set = commit_list[hash_idx][address]; + for(auto id : commit_id){ + //LOG(ERROR)<<"push front id:"<second; + std::stack tmp; + while(!set_it.empty()){ + if(set_it.front() == commit_id){ + break; + } + tmp.push(set_it.front()); + set_it.pop_front(); + } + set_it.pop_front(); + while(!tmp.empty()){ + set_it.push_front(tmp.top()); + tmp.pop(); + } + + if(set_it.empty()) { + //LOG(ERROR)<<"erase idx:"<(storage)){ + for(int i = 0; i < 32; i++){ + if((1<window_size_){ + window_size_ = (1<& XController::GetRedo(){ + return redo_; +} + +std::vector& XController::GetDone(){ + return done_; +} + +void XController::RedoCommit(int64_t commit_id, int flag) { + int idx = commit_id&window_size_; + + if(is_redo_[idx]==1){ + LOG(ERROR)<<"commit id has been redo:"< commit_id){ + return false; + } + } + return true; +} + + +bool XController::CheckCommit(int64_t commit_id, const CommitList * commit_list, + bool is_pre) { + const auto& change_set = changes_list_[commit_id&window_size_]; + if(change_set.empty()){ + LOG(ERROR)<<" no commit id record found:"<GetVersion(it.first, is_pre); + //LOG(ERROR)<<"op log:"<Reset(address, data.data, data.version, /*is_pre=*/true); + }else { + storage_->Reset(address, data.old_data, data.version, /*is_pre=*/true); + } +} + +// move id from commitlist back to precommitlist +void XController::RedoConflict(int64_t commit_id) { + //LOG(ERROR)<<"move conflict id:"<, std::greater>q; + std::set v; + q.push(commit_id); + v.insert(commit_id); + + while(!q.empty()){ + int64_t cur_id = q.top(); + q.pop(); + const auto& change_set = changes_list_[cur_id&window_size_]; + + for(const auto& it : change_set){ + const uint256_t& address = it.first; + int hash_idx = GetHashKey(address); + if(commit_list_[hash_idx].find(address) == commit_list_[hash_idx].end()){ + continue; + } + //LOG(ERROR)<<"check commit id:"<version; + auto& commit_set = commit_list_[hash_idx][address]; + + if(cur_id == commit_id){ + auto& precommit_set = pre_commit_list_[hash_idx][address]; + assert(*precommit_set.begin() == commit_id); + precommit_set.pop_front(); + } + + std::vector back_list; + while(!commit_set.empty() && commit_set.back() >= cur_id){ + int64_t back_id = commit_set.back(); + commit_set.pop_back(); + + back_list.push_back(back_id); + if(v.find(back_id) == v.end()){ + q.push(back_id); + v.insert(back_id); + } + if(back_id == cur_id) { + break; + } + } + //LOG(ERROR)<<"hahs list size:"<second.begin()); + } + if(cur_id == commit_id){ + back_list.push_back(commit_id); + } + AppendHeadRecord(address, hash_idx, back_list, pre_commit_list_); + /* + for(int64_t id : pre_commit_list_[hash_idx][address]){ + LOG(ERROR)<<" addr:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<Store(it.first, op.data, false); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, false); + done = true; + break; + } + } + RemoveRecord(address, commit_id, commit_list_); + } + + CommitDone(commit_id); + Remove(commit_id); + assert(last_commit_id_ == commit_id); + last_commit_id_++; + return true; +} + +bool XController::PreCommitInternal(int64_t commit_id){ + if(!CheckCommit(commit_id, pre_commit_list_, true)){ + //LOG(ERROR)<<"check commit fail:"< new_commit_ids; + for(const auto& it : change_set){ + const uint256_t& address = it.first; + //LOG(ERROR)<<"get pre-op:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<Store(it.first, op.data, true); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, true); + done = true; + break; + } + } + + //LOG(ERROR)<<"append id:"<=-1); + if(next_commit_id> 0 && next_commit_id <= last_pre_commit_id_){ + //LOG(ERROR)<<"commit id:"<last_pre_commit_id_){ + assert(1==0); + } + } + + + for(int64_t redo_commit: new_commit_ids){ + RedoCommit(redo_commit, 1); + } + return true; +} + +void XController::MergeChangeList(int64_t commit_id){ + int idx = commit_id&window_size_; + if(rechanges_list_[idx].empty()){ + return; + } + + std::set new_list; + for(const auto& new_addr: rechanges_list_[idx]) { + new_list.insert(new_addr.first); + } + + for(const auto& old_addr : changes_list_[idx]){ + if(new_list.find(old_addr.first) == new_list.end()){ + //int64_t next_commit_id = RemoveRecord(old_addr.first, commit_id, pre_commit_list_); + int64_t next_commit_id = RemoveFromRecord(old_addr.first, commit_id, pre_commit_list_); + + //LOG(ERROR)<<" old addr:"<=-1); + if(next_commit_id> 0 && next_commit_id <= last_pre_commit_id_ && next_commit_id > commit_id){ + //LOG(ERROR)<<"commit id:"< commit_id); + commit_set.push_front(commit_id); + } + else { + std::stack tmp; + while(!commit_set.empty() && commit_set.front() <= commit_id){ + tmp.push(commit_set.front()); + commit_set.pop_front(); + } + if(tmp.empty() || tmp.top() != commit_id){ + tmp.push(commit_id); + } + while(!tmp.empty()){ + commit_set.push_front(tmp.top()); + tmp.pop(); + } + //LOG(ERROR)<<"queue size:"<last_pre_commit_id_){ + assert(rechanges_list_[commit_id&window_size_].empty()); + + const auto & local_changes = changes_list_[commit_id&window_size_]; + //LOG(ERROR)<<"commit :"< +#include +#include +#include + +#include "service/contract/executor/paral_sm/concurrency_controller.h" +#include "service/contract/executor/paral_sm/d_storage.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace paral_sm { + +class XController : public ConcurrencyController { + public: + XController(DataStorage * storage, int window_size); + ~XController(); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_); + bool Commit(int64_t commit_id); + + std::vector& GetRedo(); + std::vector& GetDone(); + + typedef std::map > CommitList; + + private: + void Clear(); + + + bool PreCommit(int64_t commit_id); + bool PreCommitInternal(int64_t commit_id); + void MergeChangeList(int64_t commit_id); + + bool PostCommit(int64_t commit_id); + void RedoConflict(int64_t commit_id); + + bool CheckCommit(int64_t commit_id, const CommitList *commit_list, bool is_pre); + bool CheckPreCommit(int64_t commit_id); + + const ModifyMap * GetChangeList(int64_t commit_id); + void Remove(int64_t commit_id); + + + void CommitDone(int64_t commit_id); + void RedoCommit(int64_t commit_id, int flag); + + void RollBackData(const uint256_t& address, const Data& data); + + bool IsRead(const uint256_t& address, int64_t commit_id); + + private: + int window_size_ = 1000; + + std::vector changes_list_,rechanges_list_; + + CommitList commit_list_[1024]; + int64_t last_commit_id_, current_commit_id_; + + CommitList pre_commit_list_[1024]; + int64_t last_pre_commit_id_; + + std::atomic is_redo_[1024]; + std::vector redo_; + + //std::atomic is_done_[1024]; + std::vector done_; + + D_Storage * storage_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/xexecutor.cpp b/platform/consensus/ordering/fides/executor/paral_sm/xexecutor.cpp new file mode 100644 index 000000000..1032128f4 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/xexecutor.cpp @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/paral_sm/xexecutor.h" + +#include +#include + +#include "service/contract/executor/paral_sm/local_state.h" +#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + + +namespace resdb { +namespace contract { +namespace paral_sm { + +XExecutor:: XExecutor( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back, + int worker_num):storage_(storage), gs_(global_state), + worker_num_(worker_num), + window_size_(window_size), + call_back_(call_back) { + + //LOG(ERROR)<<"init window:"<(storage, window_size*2); + executor_ = std::make_unique(); + + resp_list_.resize(window_size_); + is_done_.resize(window_size_); + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + first_id_ = 0; + last_id_ = 1; + is_stop_ = false; + id_ = 1; + + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request= request_queue_.Pop(); + if (request== nullptr) { + continue; + } + + //std::unique_ptr request = std::move(*request_ptr); + + LocalState local_state(controller_.get()); + local_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &local_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + //LOG(ERROR)<<"========= get resp commit id:"<GetContractExecuteInfo()->commit_id<<" param:"<< + // request->GetContractExecuteInfo()->func_params.DebugString(); + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=request->RedoTime(); + } + local_state.Flesh(request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->commit_id); + } + else { + LOG(ERROR)<<"commit :"<commit_id<<" fail"; + resp->ret = -1; + assert(resp->ret>=0); + } + request->SetResult(std::move(resp)); + resp_queue_.Push(std::move(request)); + } + })); + } + + response_ = std::thread([&]() { + while (!is_stop_) { + ResponseProcess(); + } + }); +} + +void XExecutor::SetExecuteCallBack(std::function)> func) { + call_back_ = std::move(func); +} + +XExecutor::~XExecutor(){ + //LOG(ERROR)<<"desp"; + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } + if(response_.joinable()){ + response_.join(); + } +} + +/* +void XExecutor::CallBack(uint64_t commit_id){ + //LOG(ERROR)<<"call back:"< lk(mutex_); + cv_.notify_all(); + } + //LOG(ERROR)<<"call back done:"< lk(mutex_); + cv_.wait_for(lk, std::chrono::microseconds(timeout_ms), [&] { + return id_ - first_id_ lk(mutex_); + cv_.wait_for(lk, std::chrono::microseconds(timeout_ms), [&] { + return first_id_>0&&first_id_%500==0; + //return id_ - first_id_commit_id; + int idx = resp->commit_id % window_size_; + //LOG(ERROR)<<"recv :"< q; + q.push(resp_commit_id); + while(!q.empty()){ + int64_t next_id = q.front(); + q.pop(); + + bool ret = controller_->Commit(next_id); + std::vector next_commit = controller_->GetRedo(); + //LOG(ERROR)<<"redo size:"<SetRedo(); + //LOG(ERROR)<<"redo :"<(context_ptr)); + } + else { + q.push(new_next); + } + } + + std::vector done_list = controller_->GetDone(); + for(int64_t done_id : done_list) { + //LOG(ERROR)<<"get doen id:"<commit_id; + //LOG(ERROR)<<" !!!!! commit new resp:"<Commit(current_commit_id); + if(!ret){ + //LOG(ERROR)<<"redo size:"<GetRedo().size(); + if(controller_->GetRedo().size()){ + assert(controller_->GetRedo()[0] == current_commit_id); + //redo_list.push(commit_id); + //LOG(ERROR)<<"commit redo:"<SetRedo(); + //LOG(ERROR)<<"redo :"<(context_ptr)); + } + } + else { + std::vector list = controller_->GetRedo(); + assert(list.empty()); + } + + std::vector done_list = controller_->GetDone(); + for(int64_t done_id : done_list) { + //LOG(ERROR)<<"get doen id:"<& requests) { + for(auto& request: requests) { + if(!WaitNext()){ + return; + } + request_queue_.Push(std::make_unique(request)); + } + + return ; +} + +absl::StatusOr XExecutor::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/paral_sm/xexecutor.h b/platform/consensus/ordering/fides/executor/paral_sm/xexecutor.h new file mode 100644 index 000000000..4334c113d --- /dev/null +++ b/platform/consensus/ordering/fides/executor/paral_sm/xexecutor.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/paral_sm/global_state.h" +#include "service/contract/executor/paral_sm/xcontroller.h" +#include "service/contract/executor/paral_sm/contract_committer.h" +#include "service/contract/executor/paral_sm/contract_executor.h" +#include "service/contract/executor/paral_sm/committer_context.h" +#include "service/contract/executor/paral_sm/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace paral_sm { + +class XExecutor : public ContractCommitter { + public: + XExecutor( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back = nullptr, + int worker_num = 2); + + ~XExecutor(); + + void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info) { return {}; } +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + + void CallBack(uint64_t commit_id); + + private: + std::unique_ptr controller_; + std::unique_ptr executor_; + DataStorage * storage_; + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::atomic first_id_, last_id_, id_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + std::vector> resp_list_; + std::vector is_done_; + + std::map> context_list_; + + const int worker_num_; + int window_size_; + std::function)> call_back_; + std::condition_variable cv_; + std::mutex mutex_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/service/BUILD b/platform/consensus/ordering/fides/executor/service/BUILD new file mode 100644 index 000000000..46776a78a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/service/BUILD @@ -0,0 +1,26 @@ +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "contract_transaction_manager", + srcs = ["contract_transaction_manager.cpp"], + hdrs = ["contract_transaction_manager.h"], + deps = [ + "//platform/config:resdb_config_utils", + "//service/contract/executor/manager:address_manager", + "//service/contract/executor/manager:contract_manager", + "//service/contract/proto:rpc_cc_proto", + "//service/utils:server_factory", + ], +) + +cc_test( + name = "contract_transaction_manager_test", + srcs = ["contract_transaction_manager_test.cpp"], + data = [ + "//service/contract/executor/service/test_data:contract.json", + ], + deps = [ + ":contract_transaction_manager", + "//common/test:test_main", + ], +) diff --git a/platform/consensus/ordering/fides/executor/service/contract_transaction_manager.cpp b/platform/consensus/ordering/fides/executor/service/contract_transaction_manager.cpp new file mode 100644 index 000000000..acc365cc7 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/service/contract_transaction_manager.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/service/contract_transaction_manager.h" + +#include + +namespace resdb { +namespace contract { + +ContractTransactionManager::ContractTransactionManager(void) + : contract_manager_(std::make_unique(std::make_unique())), + address_manager_(std::make_unique()) {} + +std::unique_ptr ContractTransactionManager::ExecuteData( + const std::string& client_request) { + Request request; + Response response; + + if (!request.ParseFromString(client_request)) { + LOG(ERROR) << "parse data fail in ContractTransactionManager"; + return nullptr; + } + + int ret = 0; + if (request.cmd() == Request::CREATE_ACCOUNT) { + absl::StatusOr account_or = CreateAccount(); + if (account_or.ok()) { + response.mutable_account()->Swap(&(*account_or)); + } else { + ret = -1; + } + } else if (request.cmd() == Request::DEPLOY) { + absl::StatusOr contract_or = Deploy(request); + if (contract_or.ok()) { + response.mutable_contract()->Swap(&(*contract_or)); + } else { + ret = -1; + } + } else if (request.cmd() == Request::EXECUTE) { + auto res_or = Execute(request); + if (res_or.ok()) { + response.set_res(*res_or); + } else { + ret = -1; + } + } + + response.set_ret(ret); + + std::unique_ptr resp_str = std::make_unique(); + if (!response.SerializeToString(resp_str.get())) { + return nullptr; + } + + return resp_str; +} + +absl::StatusOr ContractTransactionManager::CreateAccount() { + std::string address = + AddressManager::AddressToHex(address_manager_->CreateRandomAddress()); + Account account; + account.set_address(address); + return account; +} + +absl::StatusOr ContractTransactionManager::Deploy( + const Request& request) { + Address caller_address = + AddressManager::HexToAddress(request.caller_address()); + if (!address_manager_->Exist(caller_address)) { + LOG(ERROR) << "caller doesn't have an account"; + return absl::InvalidArgumentError("Account not exist."); + } + + Address contract_address = + contract_manager_->DeployContract(caller_address, request.deploy_info()); + + if (contract_address > 0) { + Contract contract; + contract.set_owner_address(request.caller_address()); + contract.set_contract_address( + AddressManager::AddressToHex(contract_address)); + contract.set_contract_name(request.deploy_info().contract_name()); + return contract; + } + return absl::InternalError("Deploy Contract fail."); +} + +absl::StatusOr ContractTransactionManager::Execute( + const Request& request) { + Address caller_address = + AddressManager::HexToAddress(request.caller_address()); + if (!address_manager_->Exist(caller_address)) { + LOG(ERROR) << "caller doesn't have an account"; + return absl::InvalidArgumentError("Account not exist."); + } + + return contract_manager_->ExecContract( + caller_address, AddressManager::HexToAddress(request.contract_address()), + request.func_params()); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/service/contract_transaction_manager.h b/platform/consensus/ordering/fides/executor/service/contract_transaction_manager.h new file mode 100644 index 000000000..33638c2f4 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/service/contract_transaction_manager.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "platform/config/resdb_config_utils.h" +#include "platform/consensus/execution/transaction_manager.h" +#include "service/contract/executor/manager/address_manager.h" +#include "service/contract/executor/manager/contract_manager.h" +#include "service/contract/proto/func_params.pb.h" +#include "service/contract/proto/rpc.pb.h" + +namespace resdb { +namespace contract { + +class ContractTransactionManager : public TransactionManager { + public: + ContractTransactionManager(void); + virtual ~ContractTransactionManager() = default; + + std::unique_ptr ExecuteData(const std::string& request) override; + + private: + absl::StatusOr CreateAccount(); + absl::StatusOr Deploy(const Request& request); + absl::StatusOr Execute(const Request& request); + + private: + std::unique_ptr contract_manager_; + std::unique_ptr address_manager_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/service/contract_transaction_manager_test.cpp b/platform/consensus/ordering/fides/executor/service/contract_transaction_manager_test.cpp new file mode 100644 index 000000000..e0d59e186 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/service/contract_transaction_manager_test.cpp @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/service/contract_transaction_manager.h" + +#include +#include + +#include + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/service/"; + +std::string ToString(const Request& request) { + std::string ret; + request.SerializeToString(&ret); + return ret; +} + +class ContractTransactionManagerTest : public Test { + public: + ContractTransactionManagerTest() { + std::string contract_path = test_dir + "test_data/contract.json"; + + std::ifstream contract_fstream(contract_path); + if (!contract_fstream) { + throw std::runtime_error(fmt::format( + "Unable to open contract definition file {}", contract_path)); + } + + nlohmann::json definition = nlohmann::json::parse(contract_fstream); + contracts_json_ = definition["contracts"]; + } + + Account CreateAccount() { + Request request; + Response response; + + request.set_cmd(Request::CREATE_ACCOUNT); + std::unique_ptr ret = executor_.ExecuteData(ToString(request)); + EXPECT_TRUE(ret != nullptr); + response.ParseFromString(*ret); + return response.account(); + } + + absl::StatusOr Deploy(const Account& account, + DeployInfo deploy_info) { + Request request; + Response response; + + request.set_caller_address(account.address()); + *request.mutable_deploy_info() = deploy_info; + request.set_cmd(Request::DEPLOY); + + std::unique_ptr ret = executor_.ExecuteData(ToString(request)); + EXPECT_TRUE(ret != nullptr); + + response.ParseFromString(*ret); + if (response.ret() == 0) { + return response.contract(); + } else { + return absl::InternalError("DeployFail."); + } + } + + absl::StatusOr Execute(const std::string& caller_address, + const std::string& contract_address, + const Params& params) { + Request request; + Response response; + + request.set_caller_address(caller_address); + request.set_contract_address(contract_address); + request.set_cmd(Request::EXECUTE); + *request.mutable_func_params() = params; + + std::unique_ptr ret = executor_.ExecuteData(ToString(request)); + EXPECT_TRUE(ret != nullptr); + + response.ParseFromString(*ret); + + if (response.ret() == 0) { + return eevm::to_uint256(response.res()); + } else { + return absl::InternalError("DeployFail."); + } + } + + protected: + nlohmann::json contracts_json_; + ContractTransactionManager executor_; +}; + +TEST_F(ContractTransactionManagerTest, ExecContract) { + // create an account. + Account account = CreateAccount(); + EXPECT_FALSE(account.address().empty()); + + std::string contract_name = "ERC20.sol:ERC20Token"; + std::string contract_code = contracts_json_[contract_name]["bin"]; + nlohmann::json func_hashes = contracts_json_[contract_name]["hashes"]; + + // deploy + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_code); + deploy_info.set_contract_name(contract_name); + + for (auto& func : func_hashes.items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + deploy_info.add_init_param("1000"); + + absl::StatusOr contract_or = Deploy(account, deploy_info); + EXPECT_TRUE(contract_or.ok()); + Contract contract = *contract_or; + + // query owner should return 1000 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(account.address()); + + auto result = + Execute(account.address(), contract.contract_address(), func_params); + EXPECT_EQ(*result, 0x3e8); + } + + Account transfer_receiver = CreateAccount(); + EXPECT_FALSE(account.address().empty()); + // receiver 0 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(transfer_receiver.address()); + + auto result = + Execute(account.address(), contract.contract_address(), func_params); + EXPECT_EQ(*result, 0); + } + + // transfer 400 to receiver + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(transfer_receiver.address()); + func_params.add_param("400"); + + auto result = + Execute(account.address(), contract.contract_address(), func_params); + EXPECT_EQ(*result, 1); + } + + // query owner should return 600 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(account.address()); + + auto result = + Execute(account.address(), contract.contract_address(), func_params); + EXPECT_EQ(*result, 600); + } + + // receiver 400 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(transfer_receiver.address()); + + auto result = + Execute(account.address(), contract.contract_address(), func_params); + EXPECT_EQ(*result, 400); + } +} + +TEST_F(ContractTransactionManagerTest, DeployFail) { + // create an account. + Account account = CreateAccount(); + EXPECT_FALSE(account.address().empty()); + + std::string contract_name = "ERC20.sol:ERC20Token"; + std::string contract_code = contracts_json_[contract_name]["bin"]; + nlohmann::json func_hashes = contracts_json_[contract_name]["hashes"]; + + // deploy + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_code); + deploy_info.set_contract_name(contract_name); + + for (auto& func : func_hashes.items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + // deploy_info.add_init_param("1000"); + + absl::StatusOr contract_or = Deploy(account, deploy_info); + EXPECT_FALSE(contract_or.ok()); +} + +TEST_F(ContractTransactionManagerTest, NoFunc) { + // create an account. + Account account = CreateAccount(); + EXPECT_FALSE(account.address().empty()); + + std::string contract_name = "ERC20.sol:ERC20Token"; + std::string contract_code = contracts_json_[contract_name]["bin"]; + nlohmann::json func_hashes = contracts_json_[contract_name]["hashes"]; + + // deploy + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_code); + deploy_info.set_contract_name(contract_name); + + for (auto& func : func_hashes.items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + deploy_info.add_init_param("1000"); + + absl::StatusOr contract_or = Deploy(account, deploy_info); + EXPECT_TRUE(contract_or.ok()); + Contract contract = *contract_or; + + { + Params func_params; + func_params.set_func_name("balanceOf()"); + func_params.add_param(account.address()); + + auto result = + Execute(account.address(), contract.contract_address(), func_params); + EXPECT_FALSE(result.ok()); + } +} + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/service/test_data/BUILD b/platform/consensus/ordering/fides/executor/service/test_data/BUILD new file mode 100644 index 000000000..65e3dc3d9 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/service/test_data/BUILD @@ -0,0 +1 @@ +exports_files(["contract.json"]) diff --git a/platform/consensus/ordering/fides/executor/service/test_data/contract.json b/platform/consensus/ordering/fides/executor/service/test_data/contract.json new file mode 100644 index 000000000..e9c0d972f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/service/test_data/contract.json @@ -0,0 +1,19 @@ +{ + "contracts": + { + "ERC20.sol:ERC20Token": + { + "bin": "608060405234801561001057600080fd5b506040516104423803806104428339818101604052602081101561003357600080fd5b50516000818155338152600160205260409020556103ec806100566000396000f3fe608060405234801561001057600080fd5b506004361061007e577c01000000000000000000000000000000000000000000000000000000006000350463095ea7b3811461008357806318160ddd146100c357806323b872dd146100dd57806370a0823114610113578063a9059cbb14610139578063dd62ed3e14610165575b600080fd5b6100af6004803603604081101561009957600080fd5b50600160a060020a038135169060200135610193565b604080519115158252519081900360200190f35b6100cb6101fa565b60408051918252519081900360200190f35b6100af600480360360608110156100f357600080fd5b50600160a060020a03813581169160208101359091169060400135610200565b6100cb6004803603602081101561012957600080fd5b5035600160a060020a03166102e6565b6100af6004803603604081101561014f57600080fd5b50600160a060020a038135169060200135610301565b6100cb6004803603604081101561017b57600080fd5b50600160a060020a038135811691602001351661038c565b336000818152600260209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b60005490565b600160a060020a038316600090815260016020526040812054821180159061024b5750600160a060020a03841660009081526002602090815260408083203384529091529020548211155b156102db57600160a060020a038085166000818152600160209081526040808320805488900390559387168083528483208054880190559282526002815283822033808452908252918490208054879003905583518681529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35060016102df565b5060005b9392505050565b600160a060020a031660009081526001602052604090205490565b3360009081526001602052604081205482116103845733600081815260016020908152604080832080548790039055600160a060020a03871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35060016101f4565b5060006101f4565b600160a060020a0391821660009081526002602090815260408083209390941682529190915220549056fea265627a7a72315820e4ae92c4517e475d9f77ac0bfcd10463a09239f34734fc0ab4d7966450fb428464736f6c63430005100032", + "hashes": + { + "allowance(address,address)": "dd62ed3e", + "approve(address,uint256)": "095ea7b3", + "balanceOf(address)": "70a08231", + "totalSupply()": "18160ddd", + "transfer(address,uint256)": "a9059cbb", + "transferFrom(address,address,uint256)": "23b872dd" + } + } + }, + "version": "0.5.16+commit.9c3226ce.Linux.g++" +} diff --git a/platform/consensus/ordering/fides/executor/x_manager/2pl_committer.cpp b/platform/consensus/ordering/fides/executor/x_manager/2pl_committer.cpp new file mode 100644 index 000000000..c73212873 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/2pl_committer.cpp @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/2pl_committer.h" +#include "service/contract/executor/x_manager/executor_state.h" + +#include +#include + +#include "common/utils/utils.h" +#include "eEVM/exception.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +//#define Debug + +namespace resdb { +namespace contract { +namespace x_manager { + +namespace { + +class TimeTrack { +public: + TimeTrack(std::string name = ""){ + name_ = name; + start_time_ = GetCurrentTime(); + } + + ~TimeTrack(){ + uint64_t end_time = GetCurrentTime(); + //LOG(ERROR) << name_ <<" run:" << (end_time - start_time_)<<"ms"; + } + + double GetRunTime(){ + uint64_t end_time = GetCurrentTime(); + return (end_time - start_time_) / 1000000.0; + } +private: + std::string name_; + uint64_t start_time_; +}; + +} + +TwoPLCommitter:: TwoPLCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + int worker_num):gs_(global_state), + worker_num_(worker_num), + window_size_(window_size) { + + //LOG(ERROR)<<"init window:"<(storage, window_size); + executor_ = std::make_unique(); + + resp_list_.resize(window_size_); + is_done_.resize(window_size_); + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + first_id_ = 0; + last_id_ = 1; + is_stop_ = false; + id_ = 1; + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request_ptr = request_queue_.Pop(); + if (request_ptr == nullptr) { + continue; + } + ExecutionContext * request = *request_ptr; + + TimeTrack track; + ExecutorState executor_state(controller_.get(), request->GetContractExecuteInfo()->commit_id); + executor_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id, + request->RedoTime()); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &executor_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=request->RedoTime(); + } + resp->runtime = track.GetRunTime()*1000; + } + else { + //LOG(ERROR)<<"commit :"<commit_id<<" fail"; + resp->ret = -1; + } + resp_queue_.Push(std::move(resp)); + } + })); + } +} + + +TwoPLCommitter::~TwoPLCommitter(){ + //LOG(ERROR)<<"desp"; + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + +void TwoPLCommitter::AddTask(int64_t commit_id, std::unique_ptr context){ + context_list_[commit_id] = std::move(context); +} + +ExecutionContext* TwoPLCommitter::GetTaskContext(int64_t commit_id){ + return context_list_[commit_id].get(); +} + +void TwoPLCommitter::AsyncExecContract(std::vector& requests) { + + return ; +} + +std::vector> TwoPLCommitter::ExecContract( + std::vector& requests) { + + controller_->Clear(); + int id = 1; + std::vector> tmp_resp_list; + for(auto& request: requests) { + request.commit_id = id++; + auto context = std::make_unique(request); + auto context_ptr = context.get(); + context_ptr->start_time = GetCurrentTime(); + + AddTask(request.commit_id, std::move(context)); + request_queue_.Push(std::make_unique(context_ptr)); + tmp_resp_list.push_back(nullptr); + } + + tmp_resp_list.push_back(nullptr); + std::vector> resp_list; + + int process_num = id-1; + while(process_num>0) { + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + + int64_t resp_id= resp->commit_id; + int ret = resp->ret; + #ifdef Debug + LOG(ERROR)<<"resp:"<Commit(resp_id); + if(!commit_ret){ + controller_->Clear(resp_id); + auto context_ptr = GetTaskContext(resp_id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo:"<(context_ptr)); + } + const auto& redo_list = controller_->GetRedo(); + for(int64_t id : redo_list) { + controller_->Clear(id); + auto context_ptr = GetTaskContext(id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo:"<(context_ptr)); + } + + const auto& done_list = controller_->GetDone(); + for(int id : done_list){ + //tmp_resp_list[id]->rws = *controller_->GetChangeList(id); + //LOG(ERROR)<<"done :"<rws.size(); + resp_list.push_back(std::move(tmp_resp_list[id])); + process_num--; + continue; + } + } + else { + controller_->Clear(resp_id); + auto context_ptr = GetTaskContext(resp_id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo :"<(context_ptr)); + } + } + return resp_list; +// LOG(ERROR)<<"last id:"< TwoPLCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + //LOG(ERROR)<<"start:"<ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/2pl_committer.h b/platform/consensus/ordering/fides/executor/x_manager/2pl_committer.h new file mode 100644 index 000000000..f1f5ea732 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/2pl_committer.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/contract_executor.h" +#include "service/contract/executor/x_manager/committer_context.h" +#include "service/contract/executor/x_manager/2pl_controller.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class TwoPLCommitter : public ContractCommitter { + public: + TwoPLCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + int worker_num = 2); + + ~TwoPLCommitter(); + + //void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info); + + void SetController(std::unique_ptr controller); + +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + + void CallBack(uint64_t commit_id); + + private: + std::unique_ptr controller_; + //std::unique_ptr controller_; + std::unique_ptr executor_; + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::atomic first_id_, last_id_, id_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + std::vector> resp_list_; + std::vector is_done_; + + std::map> context_list_; + + const int worker_num_; + int window_size_; + std::function)> call_back_; + std::condition_variable cv_; + std::mutex mutex_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/2pl_controller.cpp b/platform/consensus/ordering/fides/executor/x_manager/2pl_controller.cpp new file mode 100644 index 000000000..2c7edbb9d --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/2pl_controller.cpp @@ -0,0 +1,297 @@ +#include "service/contract/executor/x_manager/2pl_controller.h" + +#include +#include +#include + +#include "eEVM/exception.h" + +#include "common/utils/utils.h" + +//#define CDebug + +namespace resdb { +namespace contract { +namespace x_manager { + +TwoPLController::TwoPLController(DataStorage * storage, int window_size) : + ConcurrencyController(storage), window_size_(window_size), storage_(storage){ + for(int i = 0; i < 32; i++){ + if((1<window_size_){ + window_size_ = (1<second != commit_id){ + // LOG(ERROR)<<"append address:"<Load(address, false); + data.data = ret.first; + data.version = ret.second; +#ifdef CDebug + LOG(ERROR)<<"LOAD from db:"<<" address:"<GetVersion(it.first, false); + if(op.state == STORE){ + /* + if(op.version+1 != v){ + LOG(ERROR)<<"state:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + //LOG(ERROR)<<"load"; + break; + case STORE: + //LOG(ERROR)<<"commit addr:"<Store(it.first, op.data); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, false); + done = true; + break; + } + } + } + } + ReleaseLock(commit_id); + done_.push_back(commit_id); + #ifdef CDebug + LOG(ERROR)<<"commit done:"<< commit_id; + #endif + return true; +} + + +bool TwoPLController::Commit(int64_t commit_id){ + #ifdef CDebug + LOG(ERROR)<<"commit id:"< &TwoPLController::GetRedo(){ + return redo_; +} +const std::vector &TwoPLController::GetDone(){ + return done_; +} + +} +} +} + diff --git a/platform/consensus/ordering/fides/executor/x_manager/2pl_controller.h b/platform/consensus/ordering/fides/executor/x_manager/2pl_controller.h new file mode 100644 index 000000000..a105e2e39 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/2pl_controller.h @@ -0,0 +1,108 @@ +#pragma once + +#include +#include +#include +#include + +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/data_storage.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class TwoPLController : public ConcurrencyController { + public: + TwoPLController(DataStorage * storage, int window_size); + virtual ~TwoPLController(); + + // ============================== + virtual void Store(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + virtual uint256_t Load(const int64_t commit_id, const uint256_t& key, int version); + bool Remove(const int64_t commit_id, const uint256_t& key, int version); + + + // ============================== + typedef std::map > CommitList; + + const std::vector& GetDone(); + const std::vector &GetRedo(); + + void PushCommit(int64_t commit_id, const ModifyMap& local_changes_){} + bool Commit(int64_t commit_id); + + void StoreInternal(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + uint256_t LoadInternal(const int64_t commit_id, const uint256_t& key, int version); + + ConcurrencyController::ModifyMap * GetChangeList(int64_t commit_id); + + void Clear(); +void Clear(int64_t commit_id); + + private: + //void Clear(); + + bool CommitUpdates(int64_t commit_id); + + bool CheckCommit(int64_t commit_id); + + void AppendPreRecord(const uint256_t& address, + int64_t commit_id, Data& data); + + void RemovePreRecord(const uint256_t& address, + int64_t commit_id); + + enum LockType { + READ = 1, + WRITE = 2 + }; + + bool TryLock(const uint256_t& address, int64_t owner, LockType type); + void ReleaseLock(int64_t commit_id); + void ReleaseLock(int64_t commit_id, const uint256_t& address); + + void Abort(const int64_t commit_id); + +void AddRedo(int64_t commit_id); + std::vector FetchAbort(); + + private: + int window_size_ = 1000; + + struct DataInfo { + int64_t commit_id; + int type; + Data data; + int version; + DataInfo(){} + DataInfo(int64_t commit_id, int type, Data&data) : commit_id(commit_id), type(type), data(data){} + }; + + std::vector changes_list_; + //std::vector> changes_list_; + typedef std::map> > PreCommitList; + PreCommitList pre_commit_list_ GUARDED_BY(mutex_); + std::map> last_; + //PreCommitList pre_commit_list_[4096] GUARDED_BY(mutex_); + + std::set pd_; + std::vector redo_; + std::vector done_; + DataStorage* storage_; + std::vector wait_; + std::mutex mutex_[2048], abort_mutex_; + std::mutex g_mutex_, db_mutex_; + std::map > lock_[2048]; + bool aborted_[2048]; + bool is_redo_[2048]; + bool finish_[2048]; + bool committed_[2048]; + std::vector abort_list_; + std::map lock_table_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/BUILD b/platform/consensus/ordering/fides/executor/x_manager/BUILD new file mode 100644 index 000000000..414b9b8ce --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/BUILD @@ -0,0 +1,576 @@ +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "utils", + hdrs = ["utils.h"], + deps = [ + "//third_party:evm_lib", + ], +) + +cc_library( + name = "address_manager", + srcs = ["address_manager.cpp"], + hdrs = ["address_manager.h"], + deps = [ + ":utils", + "//common:comm", + ], +) + +cc_test( + name = "address_manager_test", + srcs = ["address_manager_test.cpp"], + deps = [ + ":address_manager", + "//common/test:test_main", + ], +) + +cc_library( + name = "data_storage", + srcs = ["data_storage.cpp"], + hdrs = ["data_storage.h"], + deps = [ + ":utils", + "//common:comm", + ], +) + +cc_library( + name = "leveldb_storage", + srcs = ["leveldb_storage.cpp"], + hdrs = ["leveldb_storage.h"], + deps = [ + ":data_storage", + "//storage:res_leveldb", + "//common:comm", + ], +) + + + +cc_library( + name = "mock_data_storage", + hdrs = ["mock_data_storage.h"], + deps = [ + ":data_storage", + "//common/test:test" + ], +) + +cc_library( + name = "mock_d_storage", + hdrs = ["mock_d_storage.h"], + deps = [ + ":d_storage", + "//common/test:test" + ], +) + + +cc_library( + name = "d_storage", + srcs = ["d_storage.cpp"], + hdrs = ["d_storage.h"], + deps = [ + ":data_storage", + "//common:comm", + ], +) + +cc_library( + name = "leveldb_d_storage", + srcs = ["leveldb_d_storage.cpp"], + hdrs = ["leveldb_d_storage.h"], + deps = [ + ":d_storage", + "//storage:res_leveldb", + "//common:comm", + ], +) + + +cc_library( + name = "leveldb", + srcs = ["leveldb.cpp"], + hdrs = ["leveldb.h"], + deps = [ + ":data_storage", + "//common:comm", + "//storage:res_leveldb" + ], +) + +cc_library( + name = "global_view", + srcs = ["global_view.cpp"], + hdrs = ["global_view.h"], + deps = [ + ":data_storage", + "//common:comm", + ], +) + +cc_library( + name = "db_view", + srcs = ["db_view.cpp"], + hdrs = ["db_view.h"], + deps = [ + ":concurrency_controller", + ":streaming_e_controller", + "//common:comm", + ], +) + +cc_library( + name = "executor_state", + srcs = ["executor_state.cpp"], + hdrs = ["executor_state.h"], + deps = [ + ":evm_state", + ":utils", + ":db_view", + "//common:comm", + ], +) + +cc_library( + name = "evm_state", + hdrs = ["evm_state.h"], + deps = [ + ":utils", + "//common:comm", + ], +) + +cc_library( + name = "global_state", + srcs = ["global_state.cpp"], + hdrs = ["global_state.h"], + deps = [ + ":evm_state", + ":utils", + ":global_view", + "//common:comm", + ], +) + +cc_library( + name = "concurrency_controller", + srcs = ["concurrency_controller.cpp"], + hdrs = ["concurrency_controller.h"], + deps = [ + ":data_storage", + ], +) + +cc_library( + name = "streaming_e_controller", + srcs = ["streaming_e_controller.cpp"], + hdrs = ["streaming_e_controller.h"], + deps = [ + ":concurrency_controller", + ":d_storage", + "//platform/common/queue:lock_free_queue", + "//common:comm", + "//common/utils:utils", + ], +) + +cc_library( + name = "e_controller", + srcs = ["e_controller.cpp"], + hdrs = ["e_controller.h"], + deps = [ + ":concurrency_controller", + ":d_storage", + "//platform/common/queue:lock_free_queue", + "//common:comm", + "//common/utils:utils", + ], +) + +cc_library( + name = "mock_e_controller", + hdrs = ["mock_e_controller.h"], + deps = [ + ":streaming_e_controller", + "//common/test:test" + ], +) + +cc_library( + name = "x_controller", + srcs = ["x_controller.cpp"], + hdrs = ["x_controller.h"], + deps = [ + ":concurrency_controller", + ":d_storage", + "//platform/common/queue:lock_free_queue", + "//common:comm", + "//common/utils:utils", + ], +) + +cc_library( + name = "fx_controller", + srcs = ["fx_controller.cpp"], + hdrs = ["fx_controller.h"], + deps = [ + ":concurrency_controller", + ":d_storage", + "//platform/common/queue:lock_free_queue", + "//common:comm", + "//common/utils:utils", + ], +) + +cc_library( + name = "dx_controller", + srcs = ["dx_controller.cpp"], + hdrs = ["dx_controller.h"], + deps = [ + ":concurrency_controller", + ":d_storage", + "//platform/common/queue:lock_free_queue", + "//common:comm", + "//common/utils:utils", + ], +) + + +cc_library( + name = "contract_executor", + srcs = ["contract_executor.cpp"], + hdrs = ["contract_executor.h"], + deps = [ + ":evm_state", + ":concurrency_controller", + "//common:comm", + "//service/contract/proto:func_params_cc_proto", + "//service/contract/executor/common:contract_execute_info", + ], +) + +cc_library( + name = "committer_context", + srcs = ["committer_context.cpp"], + hdrs = ["committer_context.h"], + deps = [ + ":contract_committer", + ], +) + +cc_library( + name = "contract_committer", + hdrs = ["contract_committer.h"], + deps = [ + ":contract_executor", + "//service/contract/proto:func_params_cc_proto", + "//service/contract/executor/common:contract_execute_info", + ], +) + +cc_library( + name = "streaming_e_committer", + srcs = ["streaming_e_committer.cpp"], + hdrs = ["streaming_e_committer.h"], + deps = [ + ":contract_committer", + ":contract_executor", + ":executor_state", + ":committer_context", + ":streaming_e_controller", + ":global_state", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + #"//platform/common/queue:priority_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "e_committer", + srcs = ["e_committer.cpp"], + hdrs = ["e_committer.h"], + deps = [ + ":contract_committer", + ":contract_executor", + ":executor_state", + ":committer_context", + ":e_controller", + ":global_state", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "seq_committer", + srcs = ["seq_committer.cpp"], + hdrs = ["seq_committer.h"], + deps = [ + ":contract_committer", + ":contract_executor", + ":executor_state", + ":committer_context", + ":global_state", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + + +cc_test( + name = "e_committer_test", + srcs = ["e_committer_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + "//service/contract/executor/manager/test_data:kv.json", + ], + deps = [ + ":contract_deployer", + ":address_manager", + ":mock_data_storage", + ":e_committer", + "//common/test:test_main", + ], +) + +cc_library( + name = "2pl_committer", + srcs = ["2pl_committer.cpp"], + hdrs = ["2pl_committer.h"], + deps = [ + ":contract_committer", + ":contract_executor", + ":executor_state", + ":committer_context", + ":2pl_controller", + ":global_state", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "2pl_controller", + srcs = ["2pl_controller.cpp"], + hdrs = ["2pl_controller.h"], + deps = [ + ":concurrency_controller", + ":d_storage", + "//platform/common/queue:lock_free_queue", + "//common:comm", + "//common/utils:utils", + ], +) + +cc_library( + name = "x_committer", + srcs = ["x_committer.cpp"], + hdrs = ["x_committer.h"], + deps = [ + ":contract_committer", + ":contract_executor", + ":executor_state", + ":committer_context", + ":x_controller", + ":global_state", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "fx_committer", + srcs = ["fx_committer.cpp"], + hdrs = ["fx_committer.h"], + deps = [ + ":contract_committer", + ":contract_executor", + ":executor_state", + ":committer_context", + ":fx_controller", + ":global_state", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "dx_committer", + srcs = ["dx_committer.cpp"], + hdrs = ["dx_committer.h"], + deps = [ + ":contract_committer", + ":contract_executor", + ":executor_state", + ":committer_context", + ":dx_controller", + ":global_state", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_test( + name = "x_committer_test", + srcs = ["x_committer_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + "//service/contract/executor/manager/test_data:kv.json", + ], + deps = [ + ":contract_deployer", + ":address_manager", + ":mock_data_storage", + ":x_committer", + "//common/test:test_main", + ], +) + + +cc_test( + name = "streaming_e_committer_test", + srcs = ["streaming_e_committer_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + "//service/contract/executor/manager/test_data:kv.json", + ], + deps = [ + ":contract_deployer", + ":address_manager", + ":mock_d_storage", + ":mock_e_controller", + ":streaming_e_committer", + "//common/test:test_main", + ], +) + + +cc_library( + name = "contract_deployer", + srcs = ["contract_deployer.cpp"], + hdrs = ["contract_deployer.h"], + deps = [ + ":concurrency_controller", + ":contract_committer", + ":global_state", + ":address_manager", + ], +) + +cc_test( + name = "contract_deployer_test", + srcs = ["contract_deployer_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + ], + deps = [ + ":test_committer", + ":contract_deployer", + "//common/test:test_main", + ], +) + +cc_library( + name = "contract_manager", + srcs = ["contract_manager.cpp"], + hdrs = ["contract_manager.h"], + deps = [ + ":contract_deployer", + ":e_committer", + ":x_committer", + ":dx_committer", + ":seq_committer", + ":fx_committer", + ":streaming_e_committer", + ":2pl_committer", + ":x_verifier", + ":global_state", + ":address_manager", + ":utils", + "//common:comm", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_test( + name = "contract_manager_test", + srcs = ["contract_manager_test.cpp"], + data = [ + "//service/contract/executor/manager/test_data:contract.json", + ], + deps = [ + ":contract_manager", + "//common/test:test_main", + ], +) + +cc_library( + name = "contract_verifier", + hdrs = ["contract_verifier.h"], + srcs = ["contract_verifier.cpp"], + deps = [ + ":contract_executor", + ":contract_committer", + ":committer_context", + ":concurrency_controller", + "//service/contract/proto:func_params_cc_proto", + ], +) + +cc_library( + name = "local_view", + srcs = ["local_view.cpp"], + hdrs = ["local_view.h"], + deps = [ + ":concurrency_controller", + "//common:comm", + ], +) + +cc_library( + name = "local_state", + srcs = ["local_state.cpp"], + hdrs = ["local_state.h"], + deps = [ + ":evm_state", + ":utils", + ":local_view", + "//common:comm", + ], +) +cc_library( + name = "v_controller", + srcs = ["v_controller.cpp"], + hdrs = ["v_controller.h"], + deps = [ + ":concurrency_controller", + "//platform/common/queue:lock_free_queue", + "//common:comm", + ], +) + +cc_library( + name = "x_verifier", + srcs = ["x_verifier.cpp"], + hdrs = ["x_verifier.h"], + deps = [ + ":contract_verifier", + ":local_state", + ":global_state", + ":v_controller", + "//common/utils:utils", + "//platform/common/queue:lock_free_queue", + "//service/contract/proto:func_params_cc_proto", + ], +) diff --git a/platform/consensus/ordering/fides/executor/x_manager/address_manager.cpp b/platform/consensus/ordering/fides/executor/x_manager/address_manager.cpp new file mode 100644 index 000000000..874226b30 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/address_manager.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/address_manager.h" + +#include + +#include "eEVM/util.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +Address AddressManager::CreateRandomAddress() { + std::vector raw(20); + std::generate(raw.begin(), raw.end(), []() { return rand(); }); + Address address = eevm::from_big_endian(raw.data(), raw.size()); + users_.insert(address); + return address; +} + +bool AddressManager::CreateAddress(const Address& address) { + if(users_.find(address) != users_.end()){ + return false; + } + users_.insert(address); + return true; +} + +bool AddressManager::Exist(const Address& address) { + return users_.find(address) != users_.end(); +} + +Address AddressManager::CreateContractAddress(const Address& owner) { + return eevm::generate_address(owner, 0u); +} + +std::string AddressManager::AddressToHex(const Address& address) { + return eevm::to_hex_string(address); +} + +Address AddressManager::HexToAddress(const std::string& address) { + return eevm::to_uint256(address); +} + +uint256_t AddressManager::AddressToSHAKey(const Address& address) { + std::vectorcode; + code.resize(64u); + eevm::to_big_endian(address, code.data()); + //code[63]=1; + //LOG(ERROR)<<"code size:"<(code.size()), h); + //LOG(ERROR)<<"get h:"< + +#include "service/contract/executor/x_manager/utils.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class AddressManager { + public: + AddressManager() {} + + // Create an address holding a 20 byte value + Address CreateRandomAddress(); + bool CreateAddress(const Address& address); + bool Exist(const Address& address); + + static Address CreateContractAddress(const Address& owner); + + static std::string AddressToHex(const Address& address); + static Address HexToAddress(const std::string& address); + + static uint256_t AddressToSHAKey(const Address& address); + + private: + std::set
users_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/address_manager_test.cpp b/platform/consensus/ordering/fides/executor/x_manager/address_manager_test.cpp new file mode 100644 index 000000000..cb7d7454c --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/address_manager_test.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/address_manager.h" + +#include +#include + +#include "eEVM/util.h" + +namespace resdb { +namespace contract { +namespace { + +TEST(AddressManagerTest, CreateAddress) { + Address address = AddressManager().CreateRandomAddress(); + std::array raw; + eevm::to_big_endian(address, raw.data()); + Address m = eevm::from_big_endian(raw.data() + 12, raw.size() - 12); + EXPECT_EQ(m, address); +} + +TEST(AddressManagerTest, CreateContractAddress) { + Address address = AddressManager().CreateRandomAddress(); + + Address contract_address = AddressManager::CreateContractAddress(address); + + std::array raw; + eevm::to_big_endian(contract_address, raw.data()); + Address m = eevm::from_big_endian(raw.data() + 12, raw.size() - 12); + EXPECT_EQ(m, contract_address); +} + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/committer_context.cpp b/platform/consensus/ordering/fides/executor/x_manager/committer_context.cpp new file mode 100644 index 000000000..764a3a53e --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/committer_context.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/committer_context.h" + +#include "glog/logging.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +ExecutionContext::ExecutionContext(const ContractExecuteInfo & info ) { + info_ = std::make_unique(info); +} + +const ContractExecuteInfo * ExecutionContext::GetContractExecuteInfo() const { + return info_.get(); +} + +ContractExecuteInfo * ExecutionContext::GetContractExecuteInfo() { + return info_.get(); +} + +void ExecutionContext::SetResult(std::unique_ptr result) { + result_ = std::move(result); +} + +bool ExecutionContext::IsRedo() { + return is_redo_; +} + +void ExecutionContext::SetRedo(){ + is_redo_++; +} + +int ExecutionContext::RedoTime() { + return is_redo_; +} + + +std::unique_ptr ExecutionContext::FetchResult() { + return std::move(result_); +} + +} // namespace contract +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/committer_context.h b/platform/consensus/ordering/fides/executor/x_manager/committer_context.h new file mode 100644 index 000000000..5f868da91 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/committer_context.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "service/contract/executor/x_manager/contract_committer.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class ExecutionContext { +public: + ExecutionContext(const ContractExecuteInfo & info ) ; + const ContractExecuteInfo * GetContractExecuteInfo() const; + ContractExecuteInfo * GetContractExecuteInfo(); + + void SetRedo(); + bool IsRedo(); + int RedoTime(); + + void SetResult(std::unique_ptr result); + std::unique_ptr FetchResult(); + + int64_t start_time = 0; + private: + int is_redo_ = 0; + std::unique_ptr result_; + std::unique_ptr info_; +}; + +} // namespace contract +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/concurrency_controller.cpp b/platform/consensus/ordering/fides/executor/x_manager/concurrency_controller.cpp new file mode 100644 index 000000000..137ccd7b8 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/concurrency_controller.cpp @@ -0,0 +1,17 @@ +#include "service/contract/executor/x_manager/concurrency_controller.h" + +#include + +namespace resdb { +namespace contract { +namespace x_manager { + +ConcurrencyController::ConcurrencyController(DataStorage * storage) : storage_(storage){} + +const DataStorage * ConcurrencyController::GetStorage() const { + return storage_; +} + +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/concurrency_controller.h b/platform/consensus/ordering/fides/executor/x_manager/concurrency_controller.h new file mode 100644 index 000000000..fef2cfa54 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/concurrency_controller.h @@ -0,0 +1,53 @@ +#pragma once + +#include "service/contract/executor/x_manager/data_storage.h" + +#include +#include + +namespace resdb { +namespace contract { +namespace x_manager { + +enum State{ + LOAD = 0, + STORE = 1, + REMOVE = 2, +}; + +struct Data{ + State state; + uint256_t data; + int64_t version; + uint256_t old_data; + int commit_version; + bool has_read = false; + bool invalid = false; + Data(){} + Data(const State& state):state(state){} + Data(const State& state, const uint256_t& data, int64_t version = 0) + :state(state), data(data), version(version){} + Data(const State& state, const uint256_t& data, int64_t version, const uint256_t& old_data) + :state(state), data(data), version(version), old_data(old_data){} + bool operator != (const Data& d) const{ + return d.state != this->state || d.data != this->data || d.version != this->version; + } +}; + +class ConcurrencyController { + public: + ConcurrencyController(DataStorage * storage); + + typedef std::map> ModifyMap; + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_) = 0; + + const DataStorage * GetStorage() const; + + protected: + DataStorage * storage_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/contract_committer.h b/platform/consensus/ordering/fides/executor/x_manager/contract_committer.h new file mode 100644 index 000000000..80911cd1a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/contract_committer.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include + +#include "service/contract/executor/x_manager/contract_executor.h" + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "eEVM/address.h" + +#include "service/contract/proto/func_params.pb.h" +#include "service/contract/executor/common/contract_execute_info.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +/* +struct ContractExecuteInfo { + eevm::Address caller_address; + eevm::Address contract_address; + std::string func_addr; + Params func_params; + int64_t commit_id; + uint64_t user_id; + ContractExecuteInfo(){} + ContractExecuteInfo( + eevm::Address caller_address, + eevm::Address contract_address, + std::string func_addr, + Params func_params, + int64_t commit_id): caller_address(caller_address), contract_address(contract_address), func_addr(func_addr), func_params(func_params), commit_id(commit_id){} +}; +*/ + +class ContractCommitter { + public: + ContractCommitter() = default; + virtual ~ContractCommitter() = default; + + virtual std::vector> ExecContract(std::vector& request) = 0; + + virtual void AsyncExecContract(std::vector& request){}; + + virtual absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) = 0; + + virtual void SetExecuteCallBack(std::function)> ){}; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/contract_deployer.cpp b/platform/consensus/ordering/fides/executor/x_manager/contract_deployer.cpp new file mode 100644 index 000000000..8c34d5757 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/contract_deployer.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/contract_deployer.h" + +#include "service/contract/executor/x_manager/address_manager.h" + +#include +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { +namespace x_manager { +namespace { + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } + +void AppendArgToInput(std::vector& code, const uint256_t& arg) { + const auto pre_size = code.size(); + code.resize(pre_size + 32u); + eevm::to_big_endian(arg, code.data() + pre_size); + LOG(ERROR)<<"add arg:"<& code, const std::string& arg) { + AppendArgToInput(code, eevm::to_uint256(arg)); +} + +} + +ContractDeployer::ContractDeployer(ContractCommitter * committer, GlobalState * gs) + : committer_(committer), gs_(gs){} + +std::string ContractDeployer::GetFuncAddress(const Address& contract_address, + const std::string& func_name) { + //LOG(ERROR)<<" deployer:"<create(contract_address, 0u, contract_constructor); + absl::StatusOr result = committer_->ExecContract( + owner_address, contract_address, + "", + {}, gs_); + + if(result.ok()){ + // set the initialized class context code. + contract.acc.set_code(eevm::to_bytes(*result)); + + for (const auto& info : deploy_info.func_info()) { + SetFuncAddress(contract_address, info); + } + return contract.acc.get_address(); + } else { + gs_->remove(contract_address); + return 0; + } + } catch (...) { + LOG(ERROR) << "Deploy throw expection"; + return 0; + } +} + +bool ContractDeployer::DeployContract(const Address& owner_address, + const DeployInfo& deploy_info, const Address& contract_address) { + LOG(ERROR)<<"deploy address:"<create(contract_address, 0u, contract_constructor); + + LOG(ERROR)<<"create:"; + absl::StatusOr result = committer_->ExecContract( + owner_address, contract_address, + "", + {}, gs_); + + LOG(ERROR)<<"deploy result:"<remove(contract_address); + return false; + } + } catch (...) { + LOG(ERROR) << "Deploy throw expection"; + return false; + } +} + +Address ContractDeployer::DeployContract(const Address& owner_address, + const nlohmann::json& contract_json, const std::vector& init_params){ + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json["bin"]); + + for (auto& func : contract_json["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + for(const uint256_t& param : init_params){ + deploy_info.add_init_param(U256ToString(param)); + } + + return DeployContract(owner_address, deploy_info); +} + +bool ContractDeployer::DeployContract(const Address& owner_address, + const nlohmann::json& contract_json, const std::vector& init_params, const Address& contract_address){ + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json["bin"]); + + for (auto& func : contract_json["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + for(const uint256_t& param : init_params){ + deploy_info.add_init_param(U256ToString(param)); + } + + return DeployContract(owner_address, deploy_info, contract_address); +} + +absl::StatusOr ContractDeployer::GetContract( + const Address& address) { + if (!gs_->Exists(address)) { + return absl::InvalidArgumentError("Contract not exist."); + } + + return gs_->get(address); +} + +} // namespace contract +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/contract_deployer.h b/platform/consensus/ordering/fides/executor/x_manager/contract_deployer.h new file mode 100644 index 000000000..84f100360 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/contract_deployer.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class ContractDeployer { + public: + ContractDeployer(ContractCommitter * committer, GlobalState * gs); + + public: + Address DeployContract(const Address& owner_address, + const DeployInfo& deploy_info); + bool DeployContract(const Address& owner_address, + const DeployInfo& deploy_info, const Address& contract_address); + + Address DeployContract(const Address& owner_address, + const nlohmann::json& contract_json, const std::vector& init_params); + bool DeployContract(const Address& owner_address, + const nlohmann::json& contract_json, const std::vector& init_params, const Address& contract_address); + + absl::StatusOr GetContract(const Address& address); + std::string GetFuncAddress(const Address& contract_address, + const std::string& func_name); + + private: + void SetFuncAddress(const Address& contract_address, const FuncInfo& func); + + private: + ContractCommitter* committer_; + GlobalState* gs_; + std::map> func_address_; +}; + +} // namespace contract +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/contract_deployer_test.cpp b/platform/consensus/ordering/fides/executor/x_manager/contract_deployer_test.cpp new file mode 100644 index 000000000..41be4ae2c --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/contract_deployer_test.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/contract_deployer.h" + +#include +#include + +#include + +#include "service/contract/executor/manager/address_manager.h" +#include "service/contract/executor/manager/test_committer.h" + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } + +class ContractDeployerTest : public Test { + public: + ContractDeployerTest() : owner_address_(get_random_address()) { + + storage_ = std::make_unique(); + gs_ = std::make_unique(storage_.get()); + execotor_ = std::make_unique(storage_.get(), gs_.get()); + + + + LOG(ERROR)<<"owner:"< storage_; + std::unique_ptr gs_; + std::unique_ptrexecotor_; +}; + +TEST_F(ContractDeployerTest, NoContract) { + ContractDeployer deployer(execotor_.get(), gs_.get()); + auto account = deployer.GetContract(1234); + EXPECT_FALSE(account.ok()); +} + +TEST_F(ContractDeployerTest, DeployContract) { + ContractDeployer deployer(execotor_.get(), gs_.get()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + deployer.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = deployer.GetContract(contract_address); + EXPECT_TRUE(account.ok()); +} + +TEST_F(ContractDeployerTest, DeployContractFromJson) { + ContractDeployer deployer(execotor_.get(), gs_.get()); + + Address contract_address = + deployer.DeployContract(owner_address_, contract_json_, {1000}); + EXPECT_GT(contract_address, 0); + auto account = deployer.GetContract(contract_address); + EXPECT_TRUE(account.ok()); +} + + + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/contract_executor.cpp b/platform/consensus/ordering/fides/executor/x_manager/contract_executor.cpp new file mode 100644 index 000000000..2346d7f67 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/contract_executor.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/contract_executor.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +void AppendArgToInput(std::vector& code, const uint256_t& arg) { + const auto pre_size = code.size(); + code.resize(pre_size + 32u); + eevm::to_big_endian(arg, code.data() + pre_size); +} + +void AppendArgToInput(std::vector& code, const std::string& arg) { + AppendArgToInput(code, eevm::to_uint256(arg)); +} + +absl::StatusOr ContractExecutor::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + + std::vector inputs; + if(!func_addr.empty()){ + inputs = eevm::to_bytes(func_addr); + } + for (const std::string& param : func_param.param()) { + AppendArgToInput(inputs, param); + } + + auto result = Execute(caller_address, contract_address, inputs, state); + + if (result.ok()) { + return eevm::to_hex_string(*result); + } + else { + //LOG(ERROR)<<"execute fail:"<> ContractExecutor::Execute( + const Address& caller_address, const Address& contract_address, + const std::vector& input, + EVMState * state) { + // Ignore any logs produced by this transaction + eevm::NullLogHandler ignore; + eevm::Transaction tx(caller_address, ignore); + + + // Record a trace to aid debugging + eevm::Trace tr; + eevm::Processor p(*state); + + // Run the transaction + try { + const auto exec_result = + p.run(tx, caller_address, state->get(contract_address), input, 0u, &tr); + + if (exec_result.er != eevm::ExitReason::returned) { + // Print the trace if nothing was returned + if (exec_result.er == eevm::ExitReason::threw) { + return absl::InternalError( + fmt::format("Execution error: {}", exec_result.exmsg)); + } + return absl::InternalError("Deployment did not return"); + } + return exec_result.output; + } catch (...) { + return absl::InternalError(fmt::format("Execution error:")); + } +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/contract_executor.h b/platform/consensus/ordering/fides/executor/x_manager/contract_executor.h new file mode 100644 index 000000000..6962c7b1e --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/contract_executor.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/executor/x_manager/evm_state.h" +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/common/contract_execute_info.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +/* +struct ExecuteResp { + int ret; + absl::Status state; + int64_t commit_id; + Address contract_address; + ConcurrencyController :: ModifyMap rws; + std::string result; + int retry_time = 0; + uint64_t user_id = 0; + double runtime = 0; +}; +*/ + +class ContractExecutor { + public: + ContractExecutor() = default; + + ~ContractExecutor() = default; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + absl::StatusOr> Execute( + const Address& owner_address, const Address& contract_address, + const std::vector& func_params, EVMState * state); +}; + +} // namespace contract +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/contract_executor_test.cpp b/platform/consensus/ordering/fides/executor/x_manager/contract_executor_test.cpp new file mode 100644 index 000000000..3c14e08c5 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/contract_executor_test.cpp @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/multi_contract_executor.h" +#include "service/contract/executor/manager/contract_manager.h" + +#include +#include + +#include + +#include "service/contract/executor/manager/address_manager.h" + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +uint256_t GetAddressHash(uint256_t address){ + std::vectorcode; + code.resize(64u); + eevm::to_big_endian(address, code.data()); + code[63]=1; + + uint8_t h[32]; + eevm::keccak_256(code.data(), static_cast(code.size()), h); + return eevm::from_big_endian(h, sizeof(h)); +} + + +class MultiContractExecutorTest : public Test { + public: + MultiContractExecutorTest() : owner_address_(get_random_address()) { + std::string contract_path = test_dir + "test_data/contract.json"; + LOG(ERROR)<<"test dir:"< storage = std::make_unique(); + DataStorage * storage_ptr = storage.get(); + ContractManager manager(std::move(storage)); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + LOG(ERROR)<<"owner address:"<Load(owner_key).first, 1000); + } + +/* + // receiver 0 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(transfer_receiver)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 0); + + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 0); + } + + // transfer 400 to receiver + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(400)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 400); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + + // owner 600 + { + Address caller = get_random_address(); + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = manager.ExecContract(caller, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 600); + + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 400); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + + // transfer 200 to receiver2 from receiver + { + Params func_params; + func_params.set_func_name("approve(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_ptr->Load(transfer2_key).first, 0); + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 400); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + { + Params func_params; + func_params.set_func_name("transferFrom(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_ptr->Load(transfer2_key).first, 100); + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 300); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + */ +} +/* + +TEST_F(MultiContractExecutorTest, ExecMultiContractNoConflict) { + + std::unique_ptr storage = std::make_unique(); + DataStorage * storage_ptr = storage.get(); + ContractManager manager(std::move(storage)); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + uint256_t owner_key = GetAddressHash(owner_address_); + uint256_t transfer_key = GetAddressHash(transfer_receiver); + uint256_t transfer2_key = GetAddressHash(transfer_receiver2); + uint256_t transfer3_key = GetAddressHash(transfer_receiver3); + + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(400)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 400); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 600); + } + + // transfer 200 to receiver2 from receiver + { + Params func_params; + func_params.set_func_name("approve(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(200)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } + + std::vector info; + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver3)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("transferFrom(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(200)); + + info.push_back(ContractExecuteInfo(transfer_receiver, contract_address, "", func_params, 0)); + } + std::vector> resp = manager.ExecContract(info); + EXPECT_EQ(storage_ptr->Load(transfer2_key).first, 200); + EXPECT_EQ(storage_ptr->Load(transfer3_key).first, 100); + + LOG(ERROR)<<"resp size:"<ret, 0); + EXPECT_EQ(resp[1]->ret, 0); + + EXPECT_EQ(HexToInt(resp[0]->result), 1); + EXPECT_EQ(HexToInt(resp[1]->result), 1); +} + +TEST_F(MultiContractExecutorTest, ExecMultiContractHaveConflict) { + + std::unique_ptr storage = std::make_unique(); + DataStorage * storage_ptr = storage.get(); + ContractManager manager(std::move(storage)); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + uint256_t owner_key = GetAddressHash(owner_address_); + uint256_t transfer_key = GetAddressHash(transfer_receiver); + uint256_t transfer2_key = GetAddressHash(transfer_receiver2); + uint256_t transfer3_key = GetAddressHash(transfer_receiver3); + + std::vector info; + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address, "", func_params, 0)); + } + + std::vector> resp = manager.ExecContract(info); + EXPECT_EQ(storage_ptr->Load(owner_key).first, 800); + EXPECT_EQ(storage_ptr->Load(transfer_key).first, 100); + EXPECT_EQ(storage_ptr->Load(transfer2_key).first, 100); + + LOG(ERROR)<<"resp size:"<ret, 0); + EXPECT_EQ(resp[1]->ret, 0); + + EXPECT_EQ(HexToInt(resp[0]->result), 1); + EXPECT_EQ(HexToInt(resp[1]->result), 1); +} +*/ + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/contract_manager.cpp b/platform/consensus/ordering/fides/executor/x_manager/contract_manager.cpp new file mode 100644 index 000000000..6a8873eb0 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/contract_manager.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/contract_manager.h" + +#include "service/contract/executor/x_manager/address_manager.h" +#include "service/contract/executor/x_manager/streaming_e_committer.h" +#include "service/contract/executor/x_manager/e_committer.h" +#include "service/contract/executor/x_manager/x_committer.h" +#include "service/contract/executor/x_manager/dx_committer.h" +#include "service/contract/executor/x_manager/fx_committer.h" +#include "service/contract/executor/x_manager/2pl_committer.h" +#include "service/contract/executor/x_manager/seq_committer.h" +#include "service/contract/executor/x_manager/x_verifier.h" + +#include +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +ContractManager::ContractManager(std::unique_ptr storage, + int worker_num, Options op){ + storage_ = std::move(storage); + gs_ = std::make_unique(storage_.get()); + + if(op == Streaming){ + committer_ = std::make_unique(storage_.get(), gs_.get(), 1500, nullptr, worker_num); + } + else if(op == TwoPL){ + committer_ = std::make_unique(storage_.get(), gs_.get(), 1500, worker_num); + } + else if(op == X){ + committer_ = std::make_unique(storage_.get(), gs_.get(), 1500, worker_num); + } + else if(op == FX){ + committer_ = std::make_unique(storage_.get(), gs_.get(), 1500, worker_num); + } + else if(op == SEQ){ + committer_ = std::make_unique(storage_.get(), gs_.get(), 1500, worker_num); + } + else if(op == DX){ + committer_ = std::make_unique(storage_.get(), gs_.get(), 1500, worker_num); + } + else { + committer_ = std::make_unique(storage_.get(), gs_.get(), 1500, worker_num); + } + + deployer_ = std::make_unique(committer_.get(), gs_.get()); + verifier_ = std::make_unique(storage_.get(), gs_.get(), worker_num); +} + +void ContractManager::SetExecuteCallBack(std::function resp)> func) { + committer_->SetExecuteCallBack(std::move(func)); +} + +Address ContractManager::DeployContract(const Address& owner_address, + const DeployInfo& deploy_info) { + return deployer_->DeployContract(owner_address, deploy_info); +} + +bool ContractManager::DeployContract(const Address& owner_address, + const DeployInfo& deploy_info, + const Address& contract_address) { + return deployer_->DeployContract(owner_address, deploy_info, contract_address); +} + +absl::StatusOr ContractManager::GetContract(const Address& address) { + return deployer_->GetContract(address); +} + +std::vector> ContractManager::ExecContract(std::vector& execute_info) { + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i+1; + } + return committer_->ExecContract(execute_info); +} + +void ContractManager::AsyncExecContract(std::vector& execute_info) { + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name()<<" idx:"<AsyncExecContract(execute_info); +} + + +absl::StatusOr ContractManager::ExecContract( + const Address& caller_address, const Address& contract_address, + const Params& func_param) { + std::string func_addr = + deployer_->GetFuncAddress(contract_address, func_param.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << func_param.func_name(); + return absl::InvalidArgumentError("Func not exist."); + } + + absl::StatusOr result = committer_->ExecContract( + caller_address, contract_address, + func_addr, + func_param, gs_.get()); + if(result.ok()){ + return *result; + } + return result.status(); +} + +bool ContractManager::VerifyContract( + std::vector& ordered_info, + std::vector rws_list) { + return true; + for(int i = 0; i < ordered_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(ordered_info[i].contract_address, ordered_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << ordered_info[i].func_params.func_name(); + ordered_info[i].contract_address = 0; + continue; + } + ordered_info[i].func_addr = func_addr; + } + return verifier_->VerifyContract(ordered_info, rws_list); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/contract_manager.h b/platform/consensus/ordering/fides/executor/x_manager/contract_manager.h new file mode 100644 index 000000000..e16ef015d --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/contract_manager.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/contract_deployer.h" +#include "service/contract/executor/x_manager/contract_verifier.h" +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class ContractManager { + public: + enum Options { + Streaming = 1, + None = 2, + X = 3, + TwoPL = 4, + FX = 5, + SEQ = 6, + DX = 7, + }; + ContractManager(std::unique_ptr storage, + int worker_num = 2, Options op = Streaming ); + + public: + Address DeployContract(const Address& owner_address, + const DeployInfo& deploy_info); + + bool DeployContract(const Address& owner_address, + const DeployInfo& deploy_info, + const Address& contract_address); + + absl::StatusOr GetContract(const Address& address); + + absl::StatusOr ExecContract(const Address& caller_address, + const Address& contract_address, + const Params& func_param); + + std::vector> ExecContract(std::vector& execute_info); + + void AsyncExecContract(std::vector& execute_info); + + void SetExecuteCallBack(std::function resp)> func); + + bool VerifyContract( + std::vector& ordered_info, + std::vector rws_list); + private: + std::string GetFuncAddress(const Address& contract_address, + const std::string& func_name); + void SetFuncAddress(const Address& contract_address, const FuncInfo& func); + + private: + std::unique_ptr storage_; + std::unique_ptr gs_; + std::unique_ptr committer_; + std::unique_ptr deployer_; + std::unique_ptr verifier_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/contract_manager_test.cpp b/platform/consensus/ordering/fides/executor/x_manager/contract_manager_test.cpp new file mode 100644 index 000000000..759a24666 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/contract_manager_test.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/contract_manager.h" + +#include +#include + +#include + +#include "service/contract/executor/manager/address_manager.h" + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +class ContractManagerTest : public Test { + public: + ContractManagerTest() : owner_address_(get_random_address()) { + LOG(ERROR)<<"owner:"<()); + auto account = manager.GetContract(1234); + EXPECT_FALSE(account.ok()); +} + +TEST_F(ContractManagerTest, DeployContract) { + ContractManager manager(std::make_unique()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); +} + +TEST_F(ContractManagerTest, InitContract) { + ContractManager manager(std::make_unique()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + LOG(ERROR)<<" deploy done:"<()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + // owner 1000 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1000); + } + + // receiver 0 + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(transfer_receiver)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 0); + } + + // transfer 400 to receiver + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(400)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } + + // receiver 400 + { + Address caller = get_random_address(); + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(transfer_receiver)); + + auto result = manager.ExecContract(caller, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 400); + } + // owner 600 + { + Address caller = get_random_address(); + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = manager.ExecContract(caller, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 600); + } + + // transfer 200 to receiver2 from receiver + { + Params func_params; + func_params.set_func_name("approve(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(200)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } + { + Params func_params; + func_params.set_func_name("transferFrom(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(200)); + + auto result = + manager.ExecContract(transfer_receiver, contract_address, func_params); + EXPECT_EQ(HexToInt(*result), 1); + } +} + +TEST_F(ContractManagerTest, NoFunc) { + ContractManager manager(std::make_unique()); + + DeployInfo deploy_info; + deploy_info.set_contract_bin(contract_json_["bin"]); + for (auto& func : contract_json_["hashes"].items()) { + FuncInfo* new_func = deploy_info.add_func_info(); + new_func->set_func_name(func.key()); + new_func->set_hash(func.value()); + } + + deploy_info.add_init_param(U256ToString(1000)); + + Address contract_address = + manager.DeployContract(owner_address_, deploy_info); + EXPECT_GT(contract_address, 0); + auto account = manager.GetContract(contract_address); + EXPECT_TRUE(account.ok()); + + // owner 1000 + { + Params func_params; + func_params.set_func_name("balanceOf()"); + func_params.add_param(U256ToString(owner_address_)); + + auto result = + manager.ExecContract(owner_address_, contract_address, func_params); + EXPECT_FALSE(result.ok()); + } +} + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/contract_verifier.cpp b/platform/consensus/ordering/fides/executor/x_manager/contract_verifier.cpp new file mode 100644 index 000000000..8400a4f8a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/contract_verifier.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/contract_verifier.h" + +namespace resdb { +namespace contract { +namespace x_manager { + + +ContractVerifier:: ContractVerifier(){ + executor_ = std::make_unique(); +} + +ContractVerifier::~ContractVerifier(){ +} + +std::vector> ContractVerifier::ExecContract(std::vector& request ){ + return std::vector>(); +} + +absl::StatusOr ContractVerifier::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb + diff --git a/platform/consensus/ordering/fides/executor/x_manager/contract_verifier.h b/platform/consensus/ordering/fides/executor/x_manager/contract_verifier.h new file mode 100644 index 000000000..0c11c997c --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/contract_verifier.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "absl/status/statusor.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/committer_context.h" +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/contract_executor.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class ContractVerifier : public ContractCommitter { + public: + ContractVerifier(); + virtual ~ContractVerifier(); + + virtual bool VerifyContract( + const std::vector& request_list, + const std::vector& rws_list) = 0; + + std::vector> ExecContract( + std::vector& request )override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) override; + + protected: + std::unique_ptr executor_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/d_storage.cpp b/platform/consensus/ordering/fides/executor/x_manager/d_storage.cpp new file mode 100644 index 000000000..09a27bbc8 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/d_storage.cpp @@ -0,0 +1,173 @@ +#include "service/contract/executor/x_manager/d_storage.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +namespace { + + int GetHashKey(const uint256_t& address){ + // Get big-endian form + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%1024; + } + +void InternalReset(const uint256_t& key, const uint256_t& value, int64_t version, + std::map > * db, std::shared_mutex * mutex ) { + + std::unique_lock lock(*mutex); + (*db)[key] = std::make_pair(value,version); +} + +int64_t InternalStore(const uint256_t& key, const uint256_t& value, + std::map > * db, std::shared_mutex * mutex ) { + + std::unique_lock lock(*mutex); + int64_t v = (*db)[key].second; + (*db)[key] = std::make_pair(value,v+1); + return v+1; +} + +std::pair InternalLoad(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex){ + + std::shared_lock lock(*mutex); + auto e = db->find(key); + if (e == db->end()) + return std::make_pair(0,0); + return e->second; +} + +bool InternalRemove(const uint256_t& key, + std::map > * db, + std::shared_mutex * mutex) { + + std::unique_lock lock(*mutex); + auto e = db->find(key); + if (e == db->end()) + return false; + db->erase(e); + return true; +} + +bool InternalExist(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + return db->find(key) != db->end(); +} + +int64_t InternalGetVersion(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + auto it = db->find(key); + if( it == db->end()){ + return 0; + } + return it->second.second; +} + +} + +int64_t D_Storage::StoreWithVersion(const uint256_t& key, const uint256_t& value, int version, bool is_local) { +//LOG(ERROR)<<"storage key:"< D_Storage::Load(const uint256_t& key, bool is_local_view) const { + //LOG(ERROR)<<"load key:"<second.second)<<" key:"< +#include + +#include "service/contract/executor/x_manager/data_storage.h" + +#include "eEVM/util.h" + +namespace resdb { +namespace contract { + +class D_Storage : public DataStorage { + +public: + virtual int64_t Store(const uint256_t& key, const uint256_t& value, bool is_local); + virtual int64_t StoreWithVersion(const uint256_t& key, const uint256_t& value, int version, bool is_local); + virtual std::pair Load(const uint256_t& key, bool is_from_local_view) const; + virtual bool Remove(const uint256_t& key, bool is_local); + virtual bool Exist(const uint256_t& key, bool is_local) const; + + virtual int64_t GetVersion(const uint256_t& key, bool is_local) const; + + virtual void Reset(const uint256_t& key, const uint256_t& value, int64_t version, bool is_local); + +protected: + std::map > c_s_[1024]; + mutable std::shared_mutex mutex_[1024]; + + std::map > g_s_[1024]; + mutable std::shared_mutex g_mutex_[1024]; + +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/data_storage.cpp b/platform/consensus/ordering/fides/executor/x_manager/data_storage.cpp new file mode 100644 index 000000000..4b0f0b632 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/data_storage.cpp @@ -0,0 +1,81 @@ +#include "service/contract/executor/x_manager/data_storage.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +namespace { + + int GetHashKey(const uint256_t& address){ + // Get big-endian form + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%1024; + } +} + +int64_t DataStorage::Store(const uint256_t& key, const uint256_t& value, bool) { +int idx = GetHashKey(key); + + std::unique_lock lock(mutex_[idx]); + //LOG(ERROR)<<"store key:"< DataStorage::Load(const uint256_t& key, bool) const { +int idx = GetHashKey(key); + std::shared_lock lock(mutex_[idx]); + //LOG(ERROR)<<"load key:"<second; +} + +bool DataStorage::Remove(const uint256_t& key, bool) { +int idx = GetHashKey(key); + std::unique_lock lock(mutex_[idx]); + auto e = s[idx].find(key); + if (e == s[idx].end()) + return false; + s[idx].erase(e); + return true; +} + +bool DataStorage::Exist(const uint256_t& key, bool) const { +int idx = GetHashKey(key); + std::shared_lock lock(mutex_[idx]); + return s[idx].find(key) != s[idx].end(); +} + +int64_t DataStorage::GetVersion(const uint256_t& key, bool) const{ +int idx = GetHashKey(key); + std::shared_lock lock(mutex_[idx]); + auto it = s[idx].find(key); + if( it == s[idx].end()){ + return 0; + } + return it->second.second; +} + +int64_t DataStorage::StoreWithVersion(const uint256_t& key, const uint256_t& value, int version, bool ) { +int idx = GetHashKey(key); + std::unique_lock lock(mutex_[idx]); + s[idx][key] = std::make_pair(value,version); + return 0; +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/data_storage.h b/platform/consensus/ordering/fides/executor/x_manager/data_storage.h new file mode 100644 index 000000000..de68345e0 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/data_storage.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +#include "eEVM/util.h" + +namespace resdb { +namespace contract { + +class DataStorage { + +public: + DataStorage() = default; + virtual ~DataStorage() = default; + + virtual int64_t Store(const uint256_t& key, const uint256_t& value, bool is_local = false); + virtual std::pair Load(const uint256_t& key, bool is_local_view = false) const; + virtual bool Remove(const uint256_t& key, bool is_local = false); + virtual bool Exist(const uint256_t& key, bool is_local = false) const; + virtual int64_t StoreWithVersion(const uint256_t& key, const uint256_t& value, int version, bool is_local = false); + + virtual int64_t GetVersion(const uint256_t& key, bool is_local = false) const; + + virtual void Reset(const uint256_t& key, const uint256_t& value, int64_t version, bool is_local = false) {} + virtual void Flush(){}; + +protected: + std::map > s[4096]; + mutable std::shared_mutex mutex_[4096]; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/db_view.cpp b/platform/consensus/ordering/fides/executor/x_manager/db_view.cpp new file mode 100644 index 000000000..dac5612da --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/db_view.cpp @@ -0,0 +1,42 @@ +#include "service/contract/executor/x_manager/db_view.h" + +#include "eEVM/util.h" + +#include + +namespace resdb { +namespace contract { +namespace x_manager { + +DBView::DBView(ConcurrencyController * controller, int64_t commit_id, int version) + :controller_(static_cast(controller)), + commit_id_(commit_id), version_(version){ + } + +void DBView::store(const uint256_t& key, const uint256_t& value) { + //LOG(ERROR)<<"store:"<Store(commit_id_, key, value, version_); +} + +uint256_t DBView::load(const uint256_t& key) { + //LOG(ERROR)<<"laod:"<Load(commit_id_, key, version_); +} + +bool DBView::remove(const uint256_t& key) { + //LOG(ERROR)<<"remove key:"<Remove(commit_id_, key, version_); +} + +/* +void DBView::Flesh(int64_t commit_id) { + commit_id_ = commit_id; + //LOG(ERROR)<<"commit push:"<PushCommit(commit_id, local_changes_); + local_changes_.clear(); +} +*/ + + +}} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/db_view.h b/platform/consensus/ordering/fides/executor/x_manager/db_view.h new file mode 100644 index 000000000..7eac21da5 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/db_view.h @@ -0,0 +1,42 @@ +#pragma once + +#include + +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/streaming_e_controller.h" +#include "eEVM/storage.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class DBView : public eevm::Storage { + +public: + DBView(ConcurrencyController * controller, int64_t commit_id, int version); + virtual ~DBView() = default; + + void store(const uint256_t& key, const uint256_t& value) override; + uint256_t load(const uint256_t& key) override; + bool remove(const uint256_t& key) override; + + // for 2PL, once it is done, all the commit will be pushed to + // the controller to judge if it can be committed. + // During the flesh, all the changes will be removed. + void Flesh(int64_t commit_id) {} + // Commit the changes. If there is a conflict, return false. + // Make sure all other committers have pushed their changes before calling Commit. + //bool Commit(); + // Remove all the changes. + //void Abort(); + +private: + StreamingEController * controller_; + int64_t commit_id_; + int version_; + std::map> local_changes_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/dx_committer.cpp b/platform/consensus/ordering/fides/executor/x_manager/dx_committer.cpp new file mode 100644 index 000000000..cb1ebc363 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/dx_committer.cpp @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/dx_committer.h" +#include "service/contract/executor/x_manager/executor_state.h" + +#include +#include + +#include "common/utils/utils.h" +#include "eEVM/exception.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +//#define Debug + +namespace resdb { +namespace contract { +namespace x_manager { + +namespace { + +class TimeTrack { +public: + TimeTrack(std::string name = ""){ + name_ = name; + start_time_ = GetCurrentTime(); + } + + ~TimeTrack(){ + uint64_t end_time = GetCurrentTime(); + //LOG(ERROR) << name_ <<" run:" << (end_time - start_time_)<<"ms"; + } + + double GetRunTime(){ + uint64_t end_time = GetCurrentTime(); + return (end_time - start_time_) / 1000000.0; + } +private: + std::string name_; + uint64_t start_time_; +}; + +} + +DXCommitter:: DXCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + int worker_num):gs_(global_state), + worker_num_(worker_num), + window_size_(window_size) { + + //LOG(ERROR)<<"init window:"<(storage, window_size); + //controller_ = std::make_unique(storage, window_size*2); + executor_ = std::make_unique(); + + resp_list_.resize(window_size_); + is_done_.resize(window_size_); + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + //context_list_.resize(window_size_); + //tmp_resp_list_.resize(window_size_); + first_id_ = 0; + last_id_ = 1; + is_stop_ = false; + id_ = 1; + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request_ptr = request_queue_.Pop(); + if (request_ptr == nullptr) { + continue; + } + ExecutionContext * request = *request_ptr; + + TimeTrack track; + ExecutorState executor_state(controller_.get(), request->GetContractExecuteInfo()->commit_id); + executor_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id, + request->RedoTime()); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &executor_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=request->RedoTime(); + } + resp->runtime = track.GetRunTime()*1000; + } + else { + //LOG(ERROR)<<"commit :"<commit_id<<" fail"; + resp->ret = -1; + } + resp_queue_.Push(std::move(resp)); + } + })); + } +} + + +DXCommitter::~DXCommitter(){ + //LOG(ERROR)<<"desp"; + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + +void DXCommitter::AddTask(int64_t commit_id, std::unique_ptr context){ + context_list_[commit_id] = std::move(context); +} + +ExecutionContext* DXCommitter::GetTaskContext(int64_t commit_id){ + return context_list_[commit_id].get(); +} + +void DXCommitter::AsyncExecContract(std::vector& requests) { + + return ; +} + +std::vector> DXCommitter::ExecContract( + std::vector& requests) { + + controller_->Clear(); + int id = 1; + int window = 200; + + std::vector> tmp_resp_list; + std::queue> wq; + + for(auto& request: requests) { + request.commit_id = id++; + auto context = std::make_unique(request); + auto context_ptr = context.get(); + context_ptr->start_time = GetCurrentTime(); + + AddTask(request.commit_id, std::move(context)); + if(window == 0){ + wq.push(std::make_unique(context_ptr)); + } + else { + request_queue_.Push(std::make_unique(context_ptr)); + window--; + } + tmp_resp_list.push_back(nullptr); + } + + tmp_resp_list.push_back(nullptr); + std::vector> resp_list; + + int process_num = id-1; + //LOG(ERROR)<<"wait num:"<0) { + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + + int64_t resp_id= resp->commit_id; + int ret = resp->ret; + #ifdef Debug + LOG(ERROR)<<"resp:"<Commit(resp_id); + if(!commit_ret){ + controller_->Clear(resp_id); + auto context_ptr = GetTaskContext(resp_id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo:"<(context_ptr)); + } + const auto& redo_list = controller_->GetRedo(); + for(int64_t id : redo_list) { + controller_->Clear(id); + auto context_ptr = GetTaskContext(id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo:"<(context_ptr)); + } + + const auto& done_list = controller_->GetDone(); + for(int id : done_list){ + //tmp_resp_list[id]->rws = *controller_->GetChangeList(id); + tmp_resp_list[id]->delay = controller_->GetDelay(id)/1000.0; + //LOG(ERROR)<<"done :"<rws.size(); + resp_list.push_back(std::move(tmp_resp_list[id])); + process_num--; + if(!wq.empty()){ + auto nt = std::move(wq.front()); + wq.pop(); + request_queue_.Push(std::move(nt)); + } + continue; + } + //resp_list.push_back(std::move(tmp_resp_list[resp_id])); + //process_num--; + //continue; + } + else { + controller_->Clear(resp_id); + auto context_ptr = GetTaskContext(resp_id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo :"<(context_ptr)); + } + } + return resp_list; +// LOG(ERROR)<<"last id:"< DXCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + //LOG(ERROR)<<"start:"<ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/dx_committer.h b/platform/consensus/ordering/fides/executor/x_manager/dx_committer.h new file mode 100644 index 000000000..7f530d195 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/dx_committer.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/contract_executor.h" +#include "service/contract/executor/x_manager/committer_context.h" +#include "service/contract/executor/x_manager/streaming_e_controller.h" +#include "service/contract/executor/x_manager/dx_controller.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class DXCommitter : public ContractCommitter { + public: + DXCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + int worker_num = 2); + + ~DXCommitter(); + + //void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info); + + void SetController(std::unique_ptr controller); + +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + + void CallBack(uint64_t commit_id); + + private: + std::unique_ptr controller_; + //std::unique_ptr controller_; + std::unique_ptr executor_; + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::atomic first_id_, last_id_, id_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + std::vector> resp_list_; + std::vector is_done_; + + std::map> context_list_; + + const int worker_num_; + int window_size_; + std::function)> call_back_; + std::condition_variable cv_; + std::mutex mutex_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/dx_controller.cpp b/platform/consensus/ordering/fides/executor/x_manager/dx_controller.cpp new file mode 100644 index 000000000..b290aa927 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/dx_controller.cpp @@ -0,0 +1,1759 @@ +#include "service/contract/executor/x_manager/dx_controller.h" + +#include +#include +#include + +#include "eEVM/exception.h" + +#include "common/utils/utils.h" + +//#define CDebug +//#define DDebug + +namespace resdb { +namespace contract { +namespace x_manager { +namespace { +int GetHashKey(const uint256_t& address){ + + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%2048; + } + } + + +DXController::DXController(DataStorage * storage, int window_size) : + ConcurrencyController(storage), window_size_(window_size), storage_(storage){ + for(int i = 0; i < 32; i++){ + if((1<window_size_){ + window_size_ = (1< DXController::GetChangeList(int64_t commit_id){ + // read lock + //return std::move(changes_list_[commit_id]); + return nullptr; +} + +void DXController::Clear(int64_t commit_id){ +#ifdef CDebug + LOG(ERROR)<<"CLEAR id:"<& change_set, const Data& data){ + if(change_set.empty()){ + change_set.push_back(data); + } + else if(data.state != LOAD){ + if(change_set.back().state != LOAD){ + change_set.pop_back(); + } + change_set.push_back(data); + } + assert(change_set.size()<3); +} + +int DXController::GetLastR(const uint256_t& address, int addr_idx){ + #ifdef CDebug + LOG(ERROR)<<"get last r, lp size:"<second; + if(lp.empty()){ + //LOG(ERROR)<<"no last:"<second; + if(lp.empty()){ + //LOG(ERROR)<<"no last:"< q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + if(x==to) { + //LOG(ERROR)<<"access from:"< DXController::GetReach(int from){ + std::queue q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + for(int ch : child_[x]){ + if(v.find(ch) == v.end()){ + v.insert(ch); + q.push(ch); + } + } + } + //assert(reach_[to][from]==false); + return v; +} + +std::set DXController::GetReach(int from, int to){ + std::queue q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + if(x==to) { + //LOG(ERROR)<<"access from:"< q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + LOG(ERROR)<<"reach from:"< new_f; + std::vector new_cf; + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + #ifdef CDebug + LOG(ERROR)<<"connect idx:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"< r = GetReach(last_idx); + for(int cf: new_cf){ + if(r.find(cf) != r.end()){ + // cycle + #ifdef CDebug + LOG(ERROR)<<"have cycle after change:"< new_f; + std::vector new_cf; + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + #ifdef CDebug + LOG(ERROR)<<"connect idx:"<second){ + if(f==0){ + int addr_idx_e = addr_idx&window_size_; + auto& mp = root_addr_[addr_idx_e][address]; + int sz = mp.size(); + //LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + #ifdef CDebug + LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(committed_[cf]){ + continue; + } + if(cf == last_idx){ + continue; + } + + //assert(cf != last_idx); + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"<second.erase(ait->second.find(f)); + } + pre_[idx].insert(last_idx); + child_[last_idx].insert(idx); + if(!new_cf.empty()){ + std::set r = GetReach(last_idx); + for(int cf: new_cf){ + if(r.find(cf) != r.end()){ + // cycle +#ifdef CDebug + LOG(ERROR)<<"have cycle after change:"<second.insert(cf); + addr_child_[cf][address].insert(last_idx); + addr_pre_[last_idx][address].insert(cf); + child_[cf].insert(last_idx); + pre_[last_idx].insert(cf); + } + } + + pre_[idx].insert(last_idx); + child_[last_idx].insert(idx); + #ifdef CDebug + LOG(ERROR)<<"connect :"<Load(address, false); + data.version = ret.second+1; + */ + data.version = 0; + Connect(commit_id, 0, address, addr_id, data.state!=STORE); + //assert(ret.second<=1); + } + else { + data.version = addr_changes_list_[last_r][addr_id].data.version+1; + bool ret = Connect(commit_id, last_r, address, addr_id, false); + if(!ret){ + LOG(ERROR)<<"connect commit:"<Load(address, false); + //LOG(ERROR)<<"load storage:"<Load(address, false); + // data.data = ret.first; + // data.version = ret.second; + bool ret = Connect(commit_id, 0, address, addr_id, data.state!=STORE); + assert(ret); + // assert(ret.second<=1); + } + else { + { + if(Reach(commit_id, last_w)){ + //assert(1==0); + //std::set rs = GetReach(commit_id, last_w); + // cycle? + #ifdef CDebug + // LOG(ERROR)<<"commit id:"<0){ + data.data = addr_changes_list_[last_w][addr_id].data.data; + data.version = addr_changes_list_[last_w][addr_id].data.version; + } + } + } + } + + //AddDataToChangeList(changes_list_[commit_id][address], data); + #ifdef CDebug + //LOG(ERROR)<<"add commit id:"< q; + q.push(commit_id); + + std::vector v(window_size_+1); + for(int i = 0; i <= window_size_; i++) v[i] = 0; + v[commit_id] = 1; + + while(!q.empty()){ + int x = q.front(); + q.pop(); + auto& cs = changes_list_[x][address]; + if(!cs.empty() && x != commit_id){ + if(cs.back().state == STORE){ + return x; + } + } + for(int f : addr_pre_[x][address]) { + if(v[f]==0){ + v[f] = 1; + q.push(f); + } + } + } + return -1; +} + +int DXController::FindR(int64_t commit_id, const uint256_t& address, int addr_idx) { + + std::queue q; + q.push(commit_id); + + std::vector v(window_size_+1); + for(int i = 0; i <= window_size_; i++) v[i] = 0; + v[commit_id] = 1; + + while(!q.empty()){ + int x = q.front(); + q.pop(); + auto& cs = changes_list_[x][address]; + if(!cs.empty()){ + if(cs.front().state == LOAD){ + return x; + } + } + for(int f : pre_[x]) { + if(v[f]==0){ + v[f] = 1; + q.push(f); + } + } + } + return -1; +} + + +bool DXController::AddOldNode(const uint256_t& address, int addr_idx, + int64_t commit_id, Data& data) { + + #ifdef CDebug + //LOG(ERROR)<<"add old node address:"<Load(address, false); + data.version = ret.second+1; + */ + data.version = 0; + Connect(commit_id, 0, address, addr_idx, data.state!=STORE); + //assert(ret.second==0); + } + else { + if(Reach(commit_id, last_r)){ + //LOG(ERROR)<<"commit id:"<Load(address, false); + data.data = ret.first; + data.version = ret.second; + } + bool ret = Connect(commit_id, 0, address, addr_idx, data.state!=STORE); + assert(ret); + //assert(ret.second==0); + } + else { + if(Reach(commit_id, last_w)){ + //assert(1==0); + //std::set rs = GetReach(commit_id, last_w); + // cycle? + #ifdef CDebug + // LOG(ERROR)<<"commit id:"<0){ + data.data = addr_changes_list_[last_w][addr_idx].data.data; + data.version = addr_changes_list_[last_w][addr_idx].data.version; + } + } + } + } + else { + if(data.state == STORE){ + if(change_set.back().state == LOAD){ + data.version = change_set.back().version+1; + } + else { + data.version = change_set.back().version; + } + } + else { + data.data = change_set.back().data; + data.version = change_set.back().version; + } + if(data.state == STORE){ + ConnectSelf(commit_id, commit_id, address, addr_idx); + if(aborted_[commit_id]){ + AbortNode(commit_id); + return false; + } + has_w = has_write_[commit_id]; + } + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + + if(lrp.find(commit_id) != lrp.end()){ + if(data.state == STORE){ + lwp.insert(commit_id); + } + } + else if( lwp.find(commit_id) != lwp.end()){ + if(data.state == LOAD){ + lrp.insert(commit_id); + } + } + } +#ifdef CDebug +LOG(ERROR)<<"has w:"<0 && data.state == STORE){ + AbortNodeFrom(commit_id, address); + } + } + +// AddDataToChangeList(change_set, data); + #ifdef CDebug + //LOG(ERROR)<<"add commit id:"<"; + PrintReach(i,j); + PrintReach(j,i); + assert(1==0); + } + } + } + #endif + /* + for(int i = 1; i < 500; ++i){ + for(auto it : addr_pre_[i]){ + auto address = it.first; + for(int c : it.second){ + if(c==0)continue; + if(addr_child_[c][address].find(i) == addr_child_[c][address].end()){ + LOG(ERROR)<<" id:"<GetVersion(it.first, false); + if(op.state == STORE){ + /* + if(op.version+1 != v){ + LOG(ERROR)<<"state:"<0){ + if(pre_[commit_id].size()==1 && *pre_[commit_id].begin() == 0){ + } + else { + #ifdef CDebug + for(int f : pre_[commit_id]){ + LOG(ERROR)<<" wait for pre:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + //LOG(ERROR)<<"load"; + break; + case STORE: + //LOG(ERROR)<<"commit:"<StoreWithVersion(it.first, op.data, op.version, false); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, false); + done = true; + break; + } + } + } + + //LOG(ERROR)<<" commit id done:"< &DXController::GetRedo(){ + return redo_; +} +const std::vector &DXController::GetDone(){ + return done_; +} + +uint64_t DXController::GetDelay(int64_t commit_id) { + return commit_delay_[commit_id]; +} + +} +} +} + diff --git a/platform/consensus/ordering/fides/executor/x_manager/dx_controller.h b/platform/consensus/ordering/fides/executor/x_manager/dx_controller.h new file mode 100644 index 000000000..88b636f32 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/dx_controller.h @@ -0,0 +1,141 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/data_storage.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class DXController : public ConcurrencyController { + public: + DXController(DataStorage * storage, int window_size); + virtual ~DXController(); + + // ============================== + virtual void Store(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + virtual uint256_t Load(const int64_t commit_id, const uint256_t& key, int version); + bool Remove(const int64_t commit_id, const uint256_t& key, int version); + + + // ============================== + typedef std::map > CommitList; + + const std::vector& GetDone(); + const std::vector &GetRedo(); + + void PushCommit(int64_t commit_id, const ModifyMap& local_changes_){} + bool Commit(int64_t commit_id); + + void StoreInternal(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + uint256_t LoadInternal(const int64_t commit_id, const uint256_t& key, int version); + + std::unique_ptr GetChangeList(int64_t commit_id); + + void Clear(); +void Clear(int64_t commit_id); + uint64_t GetDelay(int64_t commit_id); + + private: + + bool CommitUpdates(int64_t commit_id); + + bool CheckCommit(int64_t commit_id); + + void AppendPreRecord(const uint256_t& address, + int64_t commit_id, Data& data); + + int GetLastR(const uint256_t& address, int addr_id); + int GetLastW(const uint256_t& address, int addr_id); + int GetLastWOnly(const uint256_t& address, int addr_id); + int FindW(int64_t commit_id, const uint256_t& address, int addr_id); + int FindR(int64_t commit_id, const uint256_t& address, int addr_id); + + bool Connect(int idx, int last_idx, const uint256_t& address, int addr_idx, bool is_read); + void ConnectSelf(int idx, int last_idx, const uint256_t& address, int addr_idx); + bool AddNewNode(const uint256_t& address, int addr_idx, int64_t commit_id, Data& data); + bool AddOldNode(const uint256_t& address, int addr_idx, int64_t commit_id, Data& data); + void AddDataToChangeList(std::vector& change_set, const Data& data); + + void RecursiveAbort(int64_t idx, const uint256_t& address); + void AbortNodeFrom(int64_t idx, const uint256_t& address); + void AbortNode(int64_t idx); + bool ContainRead(int commit_id, const uint256_t &address); + + void RemoveNode(int64_t commit_id); + + void Abort(const int64_t commit_id); + bool Reach(int from, int to); + bool PrintReach(int from, int to); + std::set GetReach(int from, int to); + std::set GetReach(int from); + + int GetDep(int from, int to); + void AddRedo(int64_t commit_id); + + int AddressToId(const uint256_t& key); + uint256_t& GetAddress(int key); + + void ResetReach(int64_t commit_id); +void Update(const std::vector& commit_id) ; + private: + int window_size_ = 1000; + + struct DataInfo { + int64_t commit_id; + int type; + Data data; + int version; + DataInfo():type(0){} + DataInfo(int64_t commit_id, int type, Data&data) : commit_id(commit_id), type(type), data(data){} + }; + + //typedef std::map>> KeyMap; + std::vector changes_list_; + std::vector> addr_changes_list_; + //std::vector> changes_list_; + + std::set pd_; + std::vector redo_; + std::vector done_; + DataStorage* storage_; + std::vector wait_; + std::mutex mutex_[2048], abort_mutex_; + std::mutex g_mutex_, k_mutex_[2048]; + std::map > lock_[2048]; + bool aborted_[2048]; + bool is_redo_[2048]; + bool finish_[2048]; + bool committed_[2048]; + bool has_write_[2048]; + std::vector abort_list_; + std::set pre_[2048]; + std::set child_[2048]; + std::bitset<2048> reach_[2048]; + + std::map> addr_pre_[2048]; + std::map> addr_child_[2048]; + std::map> root_addr_[2048]; + std::unordered_map > lastr_, lastw_; + + std::unordered_map> check_; + std::set check_abort_; + std::vector post_abort_, pending_check_; + std::map key_[2048]; + std::unordered_map akey_; + std::atomic key_id_; + bool ds_ = false; + uint64_t commit_time_[2048], commit_delay_[2048]; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/e_committer.cpp b/platform/consensus/ordering/fides/executor/x_manager/e_committer.cpp new file mode 100644 index 000000000..075a12b4b --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/e_committer.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/e_committer.h" +#include "service/contract/executor/x_manager/executor_state.h" + +#include +#include + +#include "common/utils/utils.h" +#include "eEVM/exception.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +//#define Debug + +namespace resdb { +namespace contract { +namespace x_manager { + +namespace { + +class TimeTrack { +public: + TimeTrack(std::string name = ""){ + name_ = name; + start_time_ = GetCurrentTime(); + } + + ~TimeTrack(){ + uint64_t end_time = GetCurrentTime(); + //LOG(ERROR) << name_ <<" run:" << (end_time - start_time_)<<"ms"; + } + + double GetRunTime(){ + uint64_t end_time = GetCurrentTime(); + return (end_time - start_time_) / 1000000.0; + } +private: + std::string name_; + uint64_t start_time_; +}; + +} + +ECommitter:: ECommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + int worker_num):gs_(global_state), + worker_num_(worker_num), + window_size_(window_size) { + + //LOG(ERROR)<<"init window:"<(storage, window_size); + //controller_ = std::make_unique(storage, window_size*2); + executor_ = std::make_unique(); + + resp_list_.resize(window_size_); + is_done_.resize(window_size_); + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + //context_list_.resize(window_size_); + //tmp_resp_list_.resize(window_size_); + first_id_ = 0; + last_id_ = 1; + is_stop_ = false; + id_ = 1; + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request_ptr = request_queue_.Pop(); + if (request_ptr == nullptr) { + continue; + } + ExecutionContext * request = *request_ptr; + + TimeTrack track; + ExecutorState executor_state(controller_.get(), request->GetContractExecuteInfo()->commit_id); + executor_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id, + request->RedoTime()); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &executor_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=request->RedoTime(); + } + resp->runtime = track.GetRunTime()*1000; + } + else { + //LOG(ERROR)<<"commit :"<commit_id<<" fail"; + resp->ret = -1; + } + resp_queue_.Push(std::move(resp)); + } + })); + } +} + + +ECommitter::~ECommitter(){ + //LOG(ERROR)<<"desp"; + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + +void ECommitter::AddTask(int64_t commit_id, std::unique_ptr context){ + context_list_[commit_id] = std::move(context); +} + +ExecutionContext* ECommitter::GetTaskContext(int64_t commit_id){ + return context_list_[commit_id].get(); +} + +void ECommitter::AsyncExecContract(std::vector& requests) { + + return ; +} + +int num = 0; +std::vector> ECommitter::ExecContract( + std::vector& requests) { + + controller_->Clear(); + int id = 0; + std::vector> tmp_resp_list; + for(auto& request: requests) { + request.commit_id = id++; + auto context = std::make_unique(request); + auto context_ptr = context.get(); + context_ptr->start_time = GetCurrentTime(); + + AddTask(request.commit_id, std::move(context)); + request_queue_.Push(std::make_unique(context_ptr)); + tmp_resp_list.push_back(nullptr); + } + + std::vector> resp_list; + + int process_num = id; + //LOG(ERROR)<<"wait num:"<0) { + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + + int64_t resp_id= resp->commit_id; + int ret = resp->ret; + #ifdef Debug + LOG(ERROR)<<"resp:"<Commit(resp_id); + if(!commit_ret){ + controller_->Clear(resp_id); + auto context_ptr = GetTaskContext(resp_id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo:"<(context_ptr)); + } + const auto& redo_list = controller_->GetRedo(); + for(int64_t id : redo_list) { + controller_->Clear(id); + auto context_ptr = GetTaskContext(id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo:"<(context_ptr)); + } + + const auto& done_list = controller_->GetDone(); + for(int id : done_list){ + //tmp_resp_list[id]->rws = *controller_->GetChangeList(id); + tmp_resp_list[id]->delay = controller_->GetDelay(id)/1000.0; + //LOG(ERROR)<<"get delay:"<delay<<" runtime:"<runtime; + //LOG(ERROR)<<"done :"<rws.size(); + resp_list.push_back(std::move(tmp_resp_list[id])); + process_num--; + continue; + } + //resp_list.push_back(std::move(tmp_resp_list[resp_id])); + //process_num--; + //continue; + } + else { + controller_->Clear(resp_id); + auto context_ptr = GetTaskContext(resp_id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo :"<(context_ptr)); + } + } + return resp_list; +// LOG(ERROR)<<"last id:"< ECommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + //LOG(ERROR)<<"start:"<ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/e_committer.h b/platform/consensus/ordering/fides/executor/x_manager/e_committer.h new file mode 100644 index 000000000..f0fa8aa2a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/e_committer.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/contract_executor.h" +#include "service/contract/executor/x_manager/committer_context.h" +#include "service/contract/executor/x_manager/streaming_e_controller.h" +#include "service/contract/executor/x_manager/e_controller.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class ECommitter : public ContractCommitter { + public: + ECommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + int worker_num = 2); + + ~ECommitter(); + + //void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info); + + void SetController(std::unique_ptr controller); + +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + + void CallBack(uint64_t commit_id); + + private: + std::unique_ptr controller_; + //std::unique_ptr controller_; + std::unique_ptr executor_; + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::atomic first_id_, last_id_, id_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + std::vector> resp_list_; + std::vector is_done_; + + std::map> context_list_; + + const int worker_num_; + int window_size_; + std::function)> call_back_; + std::condition_variable cv_; + std::mutex mutex_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/e_committer_test.cpp b/platform/consensus/ordering/fides/executor/x_manager/e_committer_test.cpp new file mode 100644 index 000000000..8d102270b --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/e_committer_test.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/e_committer.h" + +#include + +#include "service/contract/executor/x_manager/mock_data_storage.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/contract_deployer.h" +#include "service/contract/executor/x_manager/address_manager.h" +#include "service/contract/proto/func_params.pb.h" + +#include +#include + +namespace resdb { +namespace contract { +namespace x_manager { +namespace { + +using ::testing::Test; +using ::testing::Invoke; + +const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + std::string(getenv("TEST_WORKSPACE")) + + "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +class ECommitterTest : public Test { + public: + ECommitterTest() : owner_address_(get_random_address()) { + std::string contract_path = test_dir + "test_data/contract.json"; + + std::ifstream contract_fstream(contract_path); + if (!contract_fstream) { + throw std::runtime_error(fmt::format( + "Unable to open contract definition file {}", contract_path)); + } + + const auto contracts_definition = nlohmann::json::parse(contract_fstream); + const auto all_contracts = contracts_definition["contracts"]; + const auto contract_code = all_contracts["ERC20.sol:ERC20Token"]; + storage_ = std::make_unique(); + contract_json_ = contract_code; + + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool) { + LOG(ERROR)<<"load:"<(storage_.get()); + + committer_ = std::make_unique(storage_.get(), gs_.get(), 1024); + + contract_address_ = AddressManager::CreateContractAddress(owner_address_); + deployer_ = std::make_unique(committer_.get(), gs_.get()); + contract_address_ = deployer_->DeployContract(owner_address_, contract_json_, {1000}); + } + + std::vector> ExecContract(std::vector& execute_info) { + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i+1; + } + return committer_->ExecContract(execute_info); + } + + protected: + Address owner_address_; + Address contract_address_; + nlohmann::json contract_json_; + std::unique_ptr storage_; + std::unique_ptr gs_; + std::unique_ptrcommitter_; + std::map> data_; + std::unique_ptr deployer_; +}; + +TEST_F(ECommitterTest, ExecContract) { + // owner 1000 + std::vector info; + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + std::vector> resp = ExecContract(info); + EXPECT_EQ(resp.size(), 1); + EXPECT_EQ(resp[0]->ret, 0); + } +} + +// get a +// a->b +TEST_F(ECommitterTest, TwoTxnNoConflict) { + Address transfer_receiver = get_random_address(); + + // owner 1000 + std::vector info; + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(transfer_receiver)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + std::vector> resp = ExecContract(info); + EXPECT_EQ(resp.size(), 2); + + for(int i = 0; i < 2; ++i){ + EXPECT_EQ(resp[i]->ret, 0); + if(resp[i]->commit_id == 0){ + EXPECT_EQ(HexToInt(resp[i]->result), 1000); + } + else { + EXPECT_EQ(HexToInt(resp[i]->result), 0); + } + } + } +} + +TEST_F(ECommitterTest, TwoTxnConflict) { + Address transfer_receiver = get_random_address(); + + // owner 1000 + std::vector info; + { + Params func_params; + func_params.set_func_name("balanceOf(address)"); + func_params.add_param(U256ToString(owner_address_)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + std::vector> resp = ExecContract(info); + EXPECT_EQ(resp.size(), 2); + for(int i = 0; i < 2; ++i){ + if(resp[i]->commit_id == 1){ + EXPECT_EQ(resp[i]->ret, 0); + EXPECT_EQ(HexToInt(resp[i]->result), 1); + } + } + } +} + +/* +// a->b +TEST_F(ECommitterTest, TwoTxnConflict1) { + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address) { + if(start){ + load_time[address]++; + } + return data_[address]; + })); + + EXPECT_CALL(*storage_, Store).WillRepeatedly(Invoke([&](const uint256_t& key, const uint256_t& value,bool) { + if(start) { + bool done = false; + while(!done){ + for(auto it : load_time){ + if(it.second>1){ + done = true; + break; + } + } + } + } + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + })); + + Init(); + start = true; + + // owner 1000 + std::vector info; + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + std::vector> resp = ExecContract(info); + EXPECT_EQ(resp.size(), 2); + EXPECT_EQ(resp[0]->ret, 0); + EXPECT_EQ(HexToInt(resp[0]->result), 1); + EXPECT_EQ(resp[1]->ret, 0); + EXPECT_EQ(HexToInt(resp[1]->result), 1); + } + //EXPECT_EQ(committer_->GetExecutionState()->commit_time,2); + //EXPECT_EQ(committer_->GetExecutionState()->redo_time,1); +} +*/ + +} // namespace +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/e_controller.cpp b/platform/consensus/ordering/fides/executor/x_manager/e_controller.cpp new file mode 100644 index 000000000..f9392f3d0 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/e_controller.cpp @@ -0,0 +1,685 @@ +#include "service/contract/executor/x_manager/e_controller.h" + +#include +#include +#include + +#include "eEVM/exception.h" + +#include "common/utils/utils.h" + +//#define CDebug + +namespace resdb { +namespace contract { +namespace x_manager { + +namespace { + + int GetHashKey(const uint256_t& address){ + return 0; + // Get big-endian form + /* + uint8_t arr[32] = {}; + memset(arr,0,sizeof(arr)); + intx::be::store(arr, address); + uint32_t v = 0; + for(int i = 0; i < 32; ++i){ + v += arr[i]; + } + */ + + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%1; + } +} +EController::EController(DataStorage * storage, int window_size) : + ConcurrencyController(storage), window_size_(window_size), storage_(storage){ + for(int i = 0; i < 32; i++){ + if((1<window_size_){ + window_size_ = (1< lk(abort_mutex_); + //LOG(ERROR)<<"abort:"< EController::FetchAbort(){ + std::vector p; + { + std::lock_guard lk(abort_mutex_); + p = abort_list_; + abort_list_.clear(); + } + return p; +} + +void EController::Clear(int64_t commit_id){ +#ifdef CDebug + //LOG(ERROR)<<"CLEAR id:"< lk(mutex_[hash_idx]); + std::unique_lock lock(g_mutex_); + //std::unique_lock lock(mutex_[hash_idx]); + + + auto& commit_set = pre_commit_list_[address]; + #ifdef CDebug + LOG(ERROR)<<"append commit set:"<> tmp; + while(!commit_set.empty()){ + auto& it = commit_set.back(); + if( !committed_[it->commit_id] && (it->commit_id > commit_id|| it->version==-1)){ + //LOG(ERROR)<<"get data front address:"<commit_id<<" committed:"<commit_id]; + //LOG(ERROR)<<"push :"<commit_id<<" version:"<version; + if(it->commit_id != commit_id){ + tmp.push(std::move(it)); + } + commit_set.pop_back(); + } + else { + break; + } + } + + + if(data.state == LOAD){ + if(commit_set.empty()){ + auto cache_it = cache_data_.find(address); + if(cache_it == cache_data_.end()){ + auto ret = storage_->Load(address, false); + data.data = ret.first; + data.version = ret.second; + //LOG(ERROR)<<"get from db commit id:"<second.first; + data.version = cache_it->second.second; + } + #ifdef CDebug + LOG(ERROR)<<"LOAD from db:"<<" version:"<data.data; + data.version = it->data.version; + #ifdef CDebug + LOG(ERROR)<<"LOAD from :"<commit_id<<" version:"<< it->data.version<<" address:"<version; + #endif + } + } + else { + if(commit_set.empty()){ + } + else { + auto& it = commit_set.back(); + data.version = it->data.version+1; + #ifdef CDebug + LOG(ERROR)<<"LOAD from :"<commit_id<<" version:"<data.version<<" address:"<commit_id == commit_id){ + it->type |= type; + it->data = data; + //assert(it->version==0); + } + else { + commit_set.push_back(std::make_unique(commit_id, type, data)); + commit_set.back()->version = 0; + } + //LOG(ERROR)<<"back type:"<type; + } + else { + commit_set.push_back(std::make_unique(commit_id, type, data)); + commit_set.back()->version = 0; + } + + bool flag = true; + while(!tmp.empty()){ + int ok = 1; + if(data.state == STORE && flag){ + if(tmp.top()->type & 1 ){ +#ifdef CDebug + LOG(ERROR)<<"abbort:"<commit_id<<" from:"<commit_id); + } + else if(tmp.top()->type&2){ + flag = false; + } + } + if(ok){ + commit_set.push_back(std::move(tmp.top())); + } + tmp.pop(); + } + //LOG(ERROR)<<"add size:"< lk(mutex_[hash_idx]); + //std::unique_lock lock(g_mutex_); + //std::unique_lock lock(mutex_[hash_idx]); + + + auto& commit_set = pre_commit_list_[address]; + //LOG(ERROR)<<"remove commit set:"<> tmp; + while(!commit_set.empty()){ + auto& it = commit_set.back(); + if(it->commit_id != commit_id){ + //LOG(ERROR)<<"push queue:"<commit_id<<" address:"<commit_id == commit_id){ + type = it->type; + //LOG(ERROR)<<"remove old data:"<type&1){ + tmp.top()->version=-1; + #ifdef CDebug + LOG(ERROR)<<"abort :"<commit_id<<" from release:"<commit_id); + } + else if((tmp.top()->type&2)){ + flag = false; + } + } + if(ok){ + commit_set.push_back(std::move(tmp.top())); + } + tmp.pop(); + } + //LOG(ERROR)<<"add size:"<GetVersion(it.first, false); + if(op.state == STORE){ + if(op.version+1 != v){ + LOG(ERROR)<<"state:"< lock_index; + //std::set locked; + std::vector >> tmp_data; + //(std::make_pair(op.data, op.version)); + { + std::unique_lock lock1(g_mutex_); + //std::vector>> lock_list; + /* + for(const auto& it : change_set){ + const auto& address = it.first; + int hash_idx = GetHashKey(address); + lock_index.push_back(hash_idx); + } + */ + + for(const auto& it : change_set){ + const auto& address = it.first; + auto& commit_set = pre_commit_list_[address]; + std::unique_ptr last_commit = nullptr; + while(!commit_set.empty()){ + auto &it = commit_set.front(); + if(committed_[it->commit_id]){ + last_commit = std::move(commit_set.front()); + commit_set.pop_front(); + } + else { + break; + } + } + assert(!commit_set.empty()); + /* + if(last_commit){ + LOG(ERROR)<<"get last commit:"<commit_id<<" commit id:"<commit_id != commit_id){ + wait_[commit_id] = true; +#ifdef CDebug + if(commit_set.empty()){ + LOG(ERROR)<<"not the first one: empty:"<commit_id<<" wait for:"<commit_id]<<" address:"<commit_id]){ + commit_set.pop_front(); + } + else { + break; + } + } + std::unique_ptr last_commit = std::move(commit_set.front()); + commit_set.pop_front(); + if(commit_set.empty()){ + } + else { + //LOG(ERROR)<<" commit id:"<commit_id<<" wait:"<commit_id]; + assert(commit_set.front()->commit_id != commit_id); + if(wait_[commit_set.front()->commit_id]){ + pd_.insert(commit_set.front()->commit_id); + } + } + commit_set.push_front(std::move(last_commit)); + } + committed_[commit_id] = true; + /* + if(!CheckCommit(commit_id)){ + LOG(ERROR)<<"check commit fail:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + //LOG(ERROR)<<"load"; + break; + case STORE: + { + if(op.version==0){ + //storage_->Store(it.first, op.data); + cache_data_[it.first] = std::make_pair(op.data, 1); + tmp_data.push_back(std::make_pair(it.first, std::make_pair(op.data, 0))); + //LOG(ERROR)<<"save to cache commit id:"<GetVersion(it.first, false); + if(op.version >v){ + //cache_data_[it.first] = std::make_pair(op.data, op.version); + //tmp_data.push_back(std::make_pair(it.first, std::make_pair(op.data, op.version))); + storage_->StoreWithVersion(it.first, op.data, op.version); + //LOG(ERROR)<<"save to cache commit id:"<second.second; + if(op.version >v){ + //cache_data_[it.first] = std::make_pair(op.data, op.version); + //tmp_data.push_back(std::make_pair(it.first, std::make_pair(op.data, op.version))); + storage_->StoreWithVersion(it.first, op.data, op.version); + //LOG(ERROR)<<"save to cache commit id:"<Remove(it.first, false); + done = true; + break; + } + } + } + + } + + for(auto& v : tmp_data){ + if(v.second.second==0){ + storage_->Store(v.first, v.second.first); + } + else { + storage_->StoreWithVersion(v.first, v.second.first, v.second.second, false); + } + } + + done_.push_back(commit_id); + #ifdef CDebug + LOG(ERROR)<<"commit done:"<< commit_id; + #endif + return true; +} + + +bool EController::Commit(int64_t commit_id){ + #ifdef CDebug + LOG(ERROR)<<"commit id:"< list = FetchAbort(); + for(int64_t id : list){ + AddRedo(id); + } + //LOG(ERROR)<<"commit time:"< &EController::GetRedo(){ + return redo_; +} + +const std::vector &EController::GetDone(){ + return done_; +} + +uint64_t EController::GetDelay(int64_t commit_id) { + return commit_delay_[commit_id]; +} + +} +} +} + diff --git a/platform/consensus/ordering/fides/executor/x_manager/e_controller.h b/platform/consensus/ordering/fides/executor/x_manager/e_controller.h new file mode 100644 index 000000000..208720bef --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/e_controller.h @@ -0,0 +1,112 @@ +#pragma once + +#include +#include +#include +#include + +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/data_storage.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class EController : public ConcurrencyController { + public: + EController(DataStorage * storage, int window_size); + virtual ~EController(); + + // ============================== + virtual void Store(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + virtual uint256_t Load(const int64_t commit_id, const uint256_t& key, int version); + bool Remove(const int64_t commit_id, const uint256_t& key, int version); + + + // ============================== + typedef std::map > CommitList; + + const std::vector& GetDone(); + const std::vector &GetRedo(); + + void PushCommit(int64_t commit_id, const ModifyMap& local_changes_){} + bool Commit(int64_t commit_id); + + void StoreInternal(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + uint256_t LoadInternal(const int64_t commit_id, const uint256_t& key, int version); + + ConcurrencyController::ModifyMap * GetChangeList(int64_t commit_id); + + void Clear(); + void Clear(int64_t commit_id); + + uint64_t GetDelay(int64_t commit_id); + + private: + //void Clear(); + + bool CommitUpdates(int64_t commit_id); + + bool CheckCommit(int64_t commit_id); + + void AppendPreRecord(const uint256_t& address, + int64_t commit_id, Data& data); + + void RemovePreRecord(const uint256_t& address, + int64_t commit_id); + + enum LockType { + READ = 1, + WRITE = 2 + }; + + bool TryLock(const uint256_t& address, int64_t owner, LockType type); + void ReleaseLock(int64_t commit_id); + void ReleaseLock(int64_t commit_id, const uint256_t& address); + + void Abort(const int64_t commit_id); + +void AddRedo(int64_t commit_id); + std::vector FetchAbort(); + + + private: + int window_size_ = 1000; + + struct DataInfo { + int64_t commit_id; + int type; + Data data; + int version; + DataInfo(){} + DataInfo(int64_t commit_id, int type, Data&data) : commit_id(commit_id), type(type), data(data){} + }; + + std::vector changes_list_; + //std::vector> changes_list_; + typedef std::map> > PreCommitList; + PreCommitList pre_commit_list_ GUARDED_BY(mutex_); + std::map> last_; + //PreCommitList pre_commit_list_[4096] GUARDED_BY(mutex_); + + std::set pd_; + std::vector redo_; + std::vector done_; + DataStorage* storage_; + std::vector wait_; + std::mutex mutex_[2048], abort_mutex_; + std::mutex g_mutex_, db_mutex_; + std::map > lock_[2048]; + bool aborted_[2048]; + bool is_redo_[2048]; + bool finish_[2048]; + bool committed_[2048]; + std::vector abort_list_; + std::map > cache_data_; + uint64_t commit_time_[2048], commit_delay_[2048]; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/evm_state.h b/platform/consensus/ordering/fides/executor/x_manager/evm_state.h new file mode 100644 index 000000000..ccd0d9500 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/evm_state.h @@ -0,0 +1,23 @@ +#pragma once + +#include "eEVM/globalstate.h" + +namespace resdb { +namespace contract { + +class EVMState : public eevm::GlobalState { +public: + EVMState() = default; + virtual ~EVMState() = default; + +protected: + const eevm::Block& get_current_block() override { return block_; } + uint256_t get_block_hash(uint8_t offset) override { return 0; } + +private: + // Unused. + eevm::Block block_; +}; + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/executor_state.cpp b/platform/consensus/ordering/fides/executor/x_manager/executor_state.cpp new file mode 100644 index 000000000..7e9348801 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/executor_state.cpp @@ -0,0 +1,75 @@ +#include "service/contract/executor/x_manager/executor_state.h" + +#include + +namespace resdb { +namespace contract { +namespace x_manager { + +using eevm::Address; +using eevm::AccountState; +using eevm::Code; +using eevm::SimpleAccount; + + ExecutorState::ExecutorState(ConcurrencyController * controller, int64_t commit_id) : controller_(controller) { + } + + bool ExecutorState::Exists(const eevm::Address& addr) { + return accounts.find(addr) != accounts.cend(); + } + + void ExecutorState::remove(const Address& addr) { + accounts.erase(addr); + } + + AccountState ExecutorState::get(const Address& addr) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()) + return acc->second; + + return create(addr, 0, {}); + } + + AccountState ExecutorState::create( + const Address& addr, const uint256_t& balance, const Code& code) { + Insert({SimpleAccount(addr, balance, code), DBView(controller_, 0, 0)}); + return get(addr); + } + + const eevm::SimpleAccount& ExecutorState::GetAccount(const eevm::Address& addr) { + const auto acc = accounts.find(addr); + return acc->second.first; + } + + void ExecutorState::Set(const eevm::SimpleAccount& acc, int64_t commit_id, int version) { + Insert({acc, DBView(controller_, commit_id, version)}); + } + + void ExecutorState::Insert(const StateEntry& p) { + const auto ib = accounts.insert(std::make_pair(p.first.get_address(), p)); + + assert(ib.second); + } + + bool ExecutorState::Flesh(const Address& addr, int commit_id) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()){ + acc->second.second.Flesh(commit_id); + return true; + } + return false; + } + +/* + bool ExecutorState::Commit(const eevm::Address& addr) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()){ + return acc->second.second.Commit(); + } + return false; + } + */ + +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/executor_state.h b/platform/consensus/ordering/fides/executor/x_manager/executor_state.h new file mode 100644 index 000000000..2e3603617 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/executor_state.h @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include "service/contract/executor/x_manager/db_view.h" +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/evm_state.h" + +#include "eEVM/simple/simpleaccount.h" + +namespace resdb { +namespace contract { +namespace x_manager { + + class ExecutorState : public EVMState { + public: + using StateEntry = std::pair; + + public: + ExecutorState(ConcurrencyController * controller, int64_t commit_id); + virtual ~ExecutorState() = default; + + virtual void remove(const eevm::Address& addr) override; + + // Get contract by contract address. + eevm::AccountState get(const eevm::Address& addr) override; + + bool Exists(const eevm::Address& addr); + + // Flesh the local view to the controller with a commit id. + // Once all the contracts have fleshed their changes, they should call commit. + // Return false if contract not exists. + bool Flesh(const eevm::Address& addr, int commit_id); + // Commit the changes using the commit id from the flesh. + //bool Commit(const eevm::Address& addr); + + // Create an account for the contract, which the balance is 0. + eevm::AccountState create( + const eevm::Address& addr, const uint256_t& balance, const eevm::Code& code) override; + + const eevm::SimpleAccount& GetAccount(const eevm::Address& addr) ; + void Set(const eevm::SimpleAccount& acc, int64_t commit_id, int version); + + protected: + void Insert(const StateEntry& p); + + private: + std::map accounts; + ConcurrencyController * controller_; + }; + +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/fx_committer.cpp b/platform/consensus/ordering/fides/executor/x_manager/fx_committer.cpp new file mode 100644 index 000000000..fcdc15780 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/fx_committer.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/fx_committer.h" +#include "service/contract/executor/x_manager/executor_state.h" + +#include +#include + +#include "common/utils/utils.h" +#include "eEVM/exception.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +//#define Debug + +namespace resdb { +namespace contract { +namespace x_manager { + +namespace { + +class TimeTrack { +public: + TimeTrack(std::string name = ""){ + name_ = name; + start_time_ = GetCurrentTime(); + } + + ~TimeTrack(){ + uint64_t end_time = GetCurrentTime(); + //LOG(ERROR) << name_ <<" run:" << (end_time - start_time_)<<"ms"; + } + + double GetRunTime(){ + uint64_t end_time = GetCurrentTime(); + return (end_time - start_time_) / 1000000.0; + } +private: + std::string name_; + uint64_t start_time_; +}; + +} + +FXCommitter:: FXCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + int worker_num):gs_(global_state), + worker_num_(worker_num), + window_size_(window_size) { + + //LOG(ERROR)<<"init window:"<(storage, window_size); + //controller_ = std::make_unique(storage, window_size*2); + executor_ = std::make_unique(); + + resp_list_.resize(window_size_); + is_done_.resize(window_size_); + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + //context_list_.resize(window_size_); + //tmp_resp_list_.resize(window_size_); + first_id_ = 0; + last_id_ = 1; + is_stop_ = false; + id_ = 1; + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request_ptr = request_queue_.Pop(); + if (request_ptr == nullptr) { + continue; + } + ExecutionContext * request = *request_ptr; + if(request->GetContractExecuteInfo()->func_params.is_only()){ + controller_->SetOnly(request->GetContractExecuteInfo()->commit_id); + } + + TimeTrack track; + ExecutorState executor_state(controller_.get(), request->GetContractExecuteInfo()->commit_id); + executor_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id, + request->RedoTime()); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &executor_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=request->RedoTime(); + } + resp->runtime = track.GetRunTime()*1000; + } + else { + //LOG(ERROR)<<"commit :"<commit_id<<" fail"; + resp->ret = -1; + } + resp_queue_.Push(std::move(resp)); + } + })); + } +} + + +FXCommitter::~FXCommitter(){ + //LOG(ERROR)<<"desp"; + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + +void FXCommitter::AddTask(int64_t commit_id, std::unique_ptr context){ + context_list_[commit_id] = std::move(context); +} + +ExecutionContext* FXCommitter::GetTaskContext(int64_t commit_id){ + return context_list_[commit_id].get(); +} + +void FXCommitter::AsyncExecContract(std::vector& requests) { + return ; +} + +std::vector> FXCommitter::ExecContract( + std::vector& requests) { + + controller_->Clear(); + int id = 1; + std::vector> tmp_resp_list; + for(auto& request: requests) { + request.commit_id = id++; + auto context = std::make_unique(request); + auto context_ptr = context.get(); + context_ptr->start_time = GetCurrentTime(); + + AddTask(request.commit_id, std::move(context)); + request_queue_.Push(std::make_unique(context_ptr)); + tmp_resp_list.push_back(nullptr); + } + + tmp_resp_list.push_back(nullptr); + std::vector> resp_list; + + int process_num = id-1; + //LOG(ERROR)<<"wait num:"<0) { + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + + int64_t resp_id= resp->commit_id; + int ret = resp->ret; + #ifdef Debug + LOG(ERROR)<<"resp:"<Commit(resp_id); + if(!commit_ret){ + controller_->Clear(resp_id); + auto context_ptr = GetTaskContext(resp_id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo:"<(context_ptr)); + } + const auto& redo_list = controller_->GetRedo(); + for(int64_t id : redo_list) { + controller_->Clear(id); + auto context_ptr = GetTaskContext(id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo:"<(context_ptr)); + } + + const auto& done_list = controller_->GetDone(); + for(int id : done_list){ + //tmp_resp_list[id]->rws = *controller_->GetChangeList(id); + tmp_resp_list[id]->delay = controller_->GetDelay(id)/1000.0; + //LOG(ERROR)<<"done :"<rws.size(); + resp_list.push_back(std::move(tmp_resp_list[id])); + process_num--; + continue; + } + //resp_list.push_back(std::move(tmp_resp_list[resp_id])); + //process_num--; + //continue; + } + else { + controller_->Clear(resp_id); + auto context_ptr = GetTaskContext(resp_id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo :"<(context_ptr)); + } + } + return resp_list; +// LOG(ERROR)<<"last id:"< FXCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + //LOG(ERROR)<<"start:"<ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/fx_committer.h b/platform/consensus/ordering/fides/executor/x_manager/fx_committer.h new file mode 100644 index 000000000..0afea0b94 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/fx_committer.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/contract_executor.h" +#include "service/contract/executor/x_manager/committer_context.h" +#include "service/contract/executor/x_manager/streaming_e_controller.h" +#include "service/contract/executor/x_manager/fx_controller.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class FXCommitter : public ContractCommitter { + public: + FXCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + int worker_num = 2); + + ~FXCommitter(); + + //void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info); + + void SetController(std::unique_ptr controller); + +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + + void CallBack(uint64_t commit_id); + + private: + std::unique_ptr controller_; + //std::unique_ptr controller_; + std::unique_ptr executor_; + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::atomic first_id_, last_id_, id_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + std::vector> resp_list_; + std::vector is_done_; + + std::map> context_list_; + + const int worker_num_; + int window_size_; + std::function)> call_back_; + std::condition_variable cv_; + std::mutex mutex_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/fx_controller.cpp b/platform/consensus/ordering/fides/executor/x_manager/fx_controller.cpp new file mode 100644 index 000000000..f1d854fbe --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/fx_controller.cpp @@ -0,0 +1,1835 @@ +#include "service/contract/executor/x_manager/fx_controller.h" + +#include +#include +#include + +#include "eEVM/exception.h" + +#include "common/utils/utils.h" + +//#define CDebug +//#define DDebug + +namespace resdb { +namespace contract { +namespace x_manager { + +namespace { +int GetHashKey(const uint256_t& address){ + + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%2048; + } +} + + +FXController::FXController(DataStorage * storage, int window_size) : + ConcurrencyController(storage), window_size_(window_size), storage_(storage){ + for(int i = 0; i < 32; i++){ + if((1<window_size_){ + window_size_ = (1< FXController::GetChangeList(int64_t commit_id){ + // read lock + //return std::move(changes_list_[commit_id]); + return nullptr; +} + +void FXController::Clear(int64_t commit_id){ +#ifdef CDebug + LOG(ERROR)<<"CLEAR id:"<& change_set, const Data& data){ + if(change_set.empty()){ + change_set.push_back(data); + } + else if(data.state != LOAD){ + if(change_set.back().state != LOAD){ + change_set.pop_back(); + } + change_set.push_back(data); + } + assert(change_set.size()<3); +} + +int FXController::GetLastR(const uint256_t& address, int addr_idx){ + #ifdef CDebug + LOG(ERROR)<<"get last r, lp size:"<second; + if(lp.empty()){ + //LOG(ERROR)<<"no last:"<second; + if(lp.empty()){ + //LOG(ERROR)<<"no last:"< q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + if(x==to) { + //LOG(ERROR)<<"access from:"< FXController::GetReach(int from){ + std::queue q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + for(int ch : child_[x]){ + if(v.find(ch) == v.end()){ + v.insert(ch); + q.push(ch); + } + } + } + //assert(reach_[to][from]==false); + return v; +} + +std::set FXController::GetReach(int from, int to){ + std::queue q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + if(x==to) { + //LOG(ERROR)<<"access from:"< q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + LOG(ERROR)<<"reach from:"< new_f; + std::vector new_cf; + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + #ifdef CDebug + LOG(ERROR)<<"connect idx:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"< r = GetReach(last_idx); + for(int cf: new_cf){ + if(r.find(cf) != r.end()){ + // cycle + #ifdef CDebug + LOG(ERROR)<<"have cycle after change:"<second.upper_bound(idx); + if(data_idx == it->second.begin()){ + } + else { + --data_idx; +#ifdef CDebug + LOG(ERROR)<<"find adress :"<Load(address, false); + data.data = ret.first; + data.version = ret.second; +} + +void FXController::AddDataSnap(int commit_idx, const uint256_t& address, const uint256_t& data, int64_t version) { + std::unique_lock lock(s_mutex_); +#ifdef CDebug + LOG(ERROR)<<"add snap data idx:"< new_f; + std::vector new_cf; + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + #ifdef CDebug + LOG(ERROR)<<"connect idx:"<second){ + if(f==0){ + int addr_idx_e = addr_idx&window_size_; + auto& mp = root_addr_[addr_idx_e][address]; + int sz = mp.size(); + //LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + #ifdef CDebug + LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(committed_[cf]){ + continue; + } + if(cf == last_idx){ + continue; + } + + //assert(cf != last_idx); + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"<second.erase(ait->second.find(f)); + } + pre_[idx].insert(last_idx); + child_[last_idx].insert(idx); + if(!new_cf.empty()){ + std::set r = GetReach(last_idx); + for(int cf: new_cf){ + if(r.find(cf) != r.end()){ + // cycle +#ifdef CDebug + LOG(ERROR)<<"have cycle after change:"<second.insert(cf); + addr_child_[cf][address].insert(last_idx); + addr_pre_[last_idx][address].insert(cf); + child_[cf].insert(last_idx); + pre_[last_idx].insert(cf); + } + } + + pre_[idx].insert(last_idx); + child_[last_idx].insert(idx); + #ifdef CDebug + LOG(ERROR)<<"connect :"<Load(address, false); + data.version = ret.second+1; + */ + data.version = 0; + Connect(commit_id, 0, address, addr_id, data.state!=STORE); + //assert(ret.second<=1); + } + else { + data.version = addr_changes_list_[last_r][addr_id].data.version+1; + bool ret = Connect(commit_id, last_r, address, addr_id, false); + if(!ret){ + LOG(ERROR)<<"connect commit:"<Load(address, false); + //LOG(ERROR)<<"load storage:"<Load(address, false); + // data.data = ret.first; + // data.version = ret.second; + bool ret = Connect(commit_id, 0, address, addr_id, data.state!=STORE); + assert(ret); + // assert(ret.second<=1); + } + else { + { + if(Reach(commit_id, last_w)){ + //assert(1==0); + //std::set rs = GetReach(commit_id, last_w); + // cycle? + #ifdef CDebug + // LOG(ERROR)<<"commit id:"<0){ + data.data = addr_changes_list_[last_w][addr_id].data.data; + data.version = addr_changes_list_[last_w][addr_id].data.version; + } + } + } + } + + //AddDataToChangeList(changes_list_[commit_id][address], data); + #ifdef CDebug + //LOG(ERROR)<<"add commit id:"< q; + q.push(commit_id); + + std::vector v(window_size_+1); + for(int i = 0; i <= window_size_; i++) v[i] = 0; + v[commit_id] = 1; + + while(!q.empty()){ + int x = q.front(); + q.pop(); + auto& cs = changes_list_[x][address]; + if(!cs.empty() && x != commit_id){ + if(cs.back().state == STORE){ + return x; + } + } + for(int f : addr_pre_[x][address]) { + if(v[f]==0){ + v[f] = 1; + q.push(f); + } + } + } + return -1; +} + +int FXController::FindR(int64_t commit_id, const uint256_t& address, int addr_idx) { + + std::queue q; + q.push(commit_id); + + std::vector v(window_size_+1); + for(int i = 0; i <= window_size_; i++) v[i] = 0; + v[commit_id] = 1; + + while(!q.empty()){ + int x = q.front(); + q.pop(); + auto& cs = changes_list_[x][address]; + if(!cs.empty()){ + if(cs.front().state == LOAD){ + return x; + } + } + for(int f : pre_[x]) { + if(v[f]==0){ + v[f] = 1; + q.push(f); + } + } + } + return -1; +} + + +bool FXController::AddOldNode(const uint256_t& address, int addr_idx, + int64_t commit_id, Data& data) { + + #ifdef CDebug + //LOG(ERROR)<<"add old node address:"<Load(address, false); + data.version = ret.second+1; + */ + data.version = 0; + Connect(commit_id, 0, address, addr_idx, data.state!=STORE); + //assert(ret.second==0); + } + else { + if(Reach(commit_id, last_r)){ + //LOG(ERROR)<<"commit id:"<Load(address, false); + data.data = ret.first; + data.version = ret.second; + } + bool ret = Connect(commit_id, 0, address, addr_idx, data.state!=STORE); + assert(ret); + //assert(ret.second==0); + } + else { + if(Reach(commit_id, last_w)){ + //assert(1==0); + //std::set rs = GetReach(commit_id, last_w); + // cycle? + #ifdef CDebug + // LOG(ERROR)<<"commit id:"<0){ + data.data = addr_changes_list_[last_w][addr_idx].data.data; + data.version = addr_changes_list_[last_w][addr_idx].data.version; + } + } + } + } + else { + if(data.state == STORE){ + if(change_set.back().state == LOAD){ + data.version = change_set.back().version+1; + } + else { + data.version = change_set.back().version; + } + } + else { + data.data = change_set.back().data; + data.version = change_set.back().version; + } + if(data.state == STORE){ + ConnectSelf(commit_id, commit_id, address, addr_idx); + if(aborted_[commit_id]){ + AbortNode(commit_id); + return false; + } + has_w = has_write_[commit_id]; + } + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + + if(lrp.find(commit_id) != lrp.end()){ + if(data.state == STORE){ + lwp.insert(commit_id); + } + } + else if( lwp.find(commit_id) != lwp.end()){ + if(data.state == LOAD){ + lrp.insert(commit_id); + } + } + } +#ifdef CDebug +LOG(ERROR)<<"has w:"<0 && data.state == STORE){ + AbortNodeFrom(commit_id, address); + } + } + +// AddDataToChangeList(change_set, data); + #ifdef CDebug + //LOG(ERROR)<<"add commit id:"<"; + PrintReach(i,j); + PrintReach(j,i); + assert(1==0); + } + } + } + #endif + /* + for(int i = 1; i < 500; ++i){ + for(auto it : addr_pre_[i]){ + auto address = it.first; + for(int c : it.second){ + if(c==0)continue; + if(addr_child_[c][address].find(i) == addr_child_[c][address].end()){ + LOG(ERROR)<<" id:"<GetVersion(it.first, false); + if(op.state == STORE){ + /* + if(op.version+1 != v){ + LOG(ERROR)<<"state:"<0){ + if(pre_[commit_id].size()==1 && *pre_[commit_id].begin() == 0){ + } + else { + #ifdef CDebug + for(int f : pre_[commit_id]){ + LOG(ERROR)<<" wait for pre:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + //LOG(ERROR)<<"load"; + break; + case STORE: + //LOG(ERROR)<<"commit:"<StoreWithVersion(it.first, op.data, op.version, false); + AddDataSnap(commit_idx_, it.first, op.data, op.version); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, false); + done = true; + break; + } + } + } + + for(const auto& it : change_set){ + last_commit_ = commit_idx_; + } + commit_idx_++; + +} + + done_.push_back(commit_id); + #ifdef CDebug + LOG(ERROR)<<"commit done:"<< commit_id; + #endif + return true; +} + + +bool FXController::Commit(int64_t commit_id){ +#ifdef CDebug + LOG(ERROR)<<"commit id:"< &FXController::GetRedo(){ + return redo_; +} +const std::vector &FXController::GetDone(){ + return done_; +} +uint64_t FXController::GetDelay(int64_t commit_id) { +return commit_delay_[commit_id]; +} + +} +} +} + diff --git a/platform/consensus/ordering/fides/executor/x_manager/fx_controller.cpp.bak2 b/platform/consensus/ordering/fides/executor/x_manager/fx_controller.cpp.bak2 new file mode 100644 index 000000000..f2996b7c4 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/fx_controller.cpp.bak2 @@ -0,0 +1,1648 @@ +#include "service/contract/executor/x_manager/fx_controller.h" + +#include +#include +#include + +#include "eEVM/exception.h" + +#include "common/utils/utils.h" + +//#define CDebug +//#define DDebug + +namespace resdb { +namespace contract { +namespace x_manager { + +namespace { +int GetHashKey(const uint256_t& address){ + + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%2048; + } + +} + + +FXController::FXController(DataStorage * storage, int window_size) : + ConcurrencyController(storage), window_size_(window_size), storage_(storage){ + for(int i = 0; i < 32; i++){ + if((1<window_size_){ + window_size_ = (1< FXController::GetChangeList(int64_t commit_id){ + // read lock + //return std::move(changes_list_[commit_id]); + return nullptr; +} + +void FXController::Clear(int64_t commit_id){ +#ifdef CDebug + LOG(ERROR)<<"CLEAR id:"<& change_set, const Data& data){ + if(change_set.empty()){ + change_set.push_back(data); + } + else if(data.state != LOAD){ + if(change_set.back().state != LOAD){ + change_set.pop_back(); + } + change_set.push_back(data); + } + assert(change_set.size()<3); +} + +int FXController::GetLastR(const uint256_t& address, int addr_idx){ + + auto git = graph_[addr_idx%2048].find(addr_idx); + if(git == graph_[addr_idx%2048].end()){ + return -1; + } + + GraphInfo *g = &git->second; + + #ifdef CDebug + LOG(ERROR)<<"get last r, lp size:"<lastr_.empty()){ + //LOG(ERROR)<<"no last:"<lastw_.empty()){ + return -1; + } + return *g->lastw_.begin(); + } + + return *g->lastr_.begin(); +} + +int FXController::GetLastW(const uint256_t& address, int addr_idx){ +#ifdef CDebug + LOG(ERROR)<<"get last w, lp size:"<second; + + if(g->lastw_.empty()){ + //LOG(ERROR)<<"no last:"<lastr_.empty()){ + return -1; + } + return *g->lastr_.begin(); + } + return *g->lastw_.begin(); +} + +int FXController::GetLastWOnly(const uint256_t& address, int addr_idx){ + return GetLastW(address, addr_idx); +} + + +void FXController::Abort(int64_t commit_id){ + if(aborted_[commit_id]){ + return; + } + aborted_[commit_id] = true; + //LOG(ERROR)<<"abort :"<lastr_; + auto& lwp = g->lastw_; + if(lrp.find(commit_id) != lrp.end()){ + is_lastr = true; + is_last = true; + } + if(lwp.find(commit_id) != lwp.end()){ + is_lastw = true; + is_last = true; + } + //LOG(ERROR)<<"commit id:"< q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + if(x==to) { + //LOG(ERROR)<<"access from:"< FXController::GetReach(int from){ + std::queue q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + for(int ch : child_[x]){ + if(v.find(ch) == v.end()){ + v.insert(ch); + q.push(ch); + } + } + } + //assert(reach_[to][from]==false); + return v; +} + +std::set FXController::GetReach(int from, int to){ + std::queue q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + if(x==to) { + //LOG(ERROR)<<"access from:"< q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + LOG(ERROR)<<"reach from:"< new_f; + std::vector new_cf; + auto git = graph_[addr_idx%2048].find(addr_idx); + assert(git != graph_[addr_idx%2048].end()); + GraphInfo * g = &git->second; + + auto& lrp = g->lastr_; + auto& lwp = g->lastw_; + #ifdef CDebug + LOG(ERROR)<<"connect idx:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"< r = GetReach(last_idx); + for(int cf: new_cf){ + if(r.find(cf) != r.end()){ + // cycle + #ifdef CDebug + LOG(ERROR)<<"have cycle after change:"<second; + + int addr_idx_e = addr_idx&window_size_; + if(last_idx==0){ + if(!is_read){ + ds_ = true; + g->lastw_.insert(idx); + } + else { + g->lastr_.insert(idx); + } + addr_pre_[idx][address].insert(last_idx); + root_addr_[addr_idx_e][address].insert(idx); + #ifdef CDebug + LOG(ERROR)<<"connect add last:"<lastr_; + auto& lwp = g->lastw_; + { + auto it = lrp.find(last_idx); + if(it != lrp.end()){ + lrp.erase(it); + } + } + { + auto it = lwp.find(last_idx); + if(it != lwp.end()){ + lwp.erase(it); + } + } + if(is_read){ + lrp.insert(idx); + } + else { + ds_ = true; + lwp.insert(idx); + } + addr_pre_[idx][address].insert(last_idx); + addr_child_[last_idx][address].insert(idx); + return true; + } + + ds_ = true; + std::vector new_f; + std::vector new_cf; + auto& lrp = g->lastr_; + auto& lwp = g->lastw_; + #ifdef CDebug + LOG(ERROR)<<"connect idx:"<second){ + if(f==0){ + int addr_idx_e = addr_idx&window_size_; + auto& mp = root_addr_[addr_idx_e][address]; + int sz = mp.size(); + //LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + #ifdef CDebug + LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(committed_[cf]){ + continue; + } + if(cf == last_idx){ + continue; + } + + //assert(cf != last_idx); + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"<second.erase(ait->second.find(f)); + } + pre_[idx].insert(last_idx); + child_[last_idx].insert(idx); + if(!new_cf.empty()){ + std::set r = GetReach(last_idx); + for(int cf: new_cf){ + if(r.find(cf) != r.end()){ + // cycle +#ifdef CDebug + LOG(ERROR)<<"have cycle after change:"<second.insert(cf); + addr_child_[cf][address].insert(last_idx); + addr_pre_[last_idx][address].insert(cf); + child_[cf].insert(last_idx); + pre_[last_idx].insert(cf); + } + } + + pre_[idx].insert(last_idx); + child_[last_idx].insert(idx); + #ifdef CDebug + LOG(ERROR)<<"connect :"<Load(address, false); + data.version = ret.second+1; + */ + data.version = 0; + Connect(commit_id, 0, address, addr_id, data.state!=STORE); + //assert(ret.second<=1); + } + else { + data.version = addr_changes_list_[last_r][addr_id].data.version+1; + bool ret = Connect(commit_id, last_r, address, addr_id, false); + if(!ret){ + LOG(ERROR)<<"connect commit:"<Load(address, false); + //LOG(ERROR)<<"load storage:"<Load(address, false); + // data.data = ret.first; + // data.version = ret.second; + bool ret = Connect(commit_id, 0, address, addr_id, data.state!=STORE); + assert(ret); + // assert(ret.second<=1); + } + else { + { + if(Reach(commit_id, last_w)){ + //assert(1==0); + //std::set rs = GetReach(commit_id, last_w); + // cycle? + #ifdef CDebug + // LOG(ERROR)<<"commit id:"<0){ + data.data = addr_changes_list_[last_w][addr_id].data.data; + data.version = addr_changes_list_[last_w][addr_id].data.version; + } + } + } + } + + //AddDataToChangeList(changes_list_[commit_id][address], data); + #ifdef CDebug + //LOG(ERROR)<<"add commit id:"< q; + q.push(commit_id); + + std::vector v(window_size_+1); + for(int i = 0; i <= window_size_; i++) v[i] = 0; + v[commit_id] = 1; + + while(!q.empty()){ + int x = q.front(); + q.pop(); + auto& cs = changes_list_[x][address]; + if(!cs.empty() && x != commit_id){ + if(cs.back().state == STORE){ + return x; + } + } + for(int f : addr_pre_[x][address]) { + if(v[f]==0){ + v[f] = 1; + q.push(f); + } + } + } + return -1; +} + +int FXController::FindR(int64_t commit_id, const uint256_t& address, int addr_idx) { + + std::queue q; + q.push(commit_id); + + std::vector v(window_size_+1); + for(int i = 0; i <= window_size_; i++) v[i] = 0; + v[commit_id] = 1; + + while(!q.empty()){ + int x = q.front(); + q.pop(); + auto& cs = changes_list_[x][address]; + if(!cs.empty()){ + if(cs.front().state == LOAD){ + return x; + } + } + for(int f : pre_[x]) { + if(v[f]==0){ + v[f] = 1; + q.push(f); + } + } + } + return -1; +} + + +bool FXController::AddOldNode(const uint256_t& address, int addr_idx, + int64_t commit_id, Data& data) { + + #ifdef CDebug + //LOG(ERROR)<<"add old node address:"<Load(address, false); + data.version = ret.second+1; + */ + data.version = 0; + Connect(commit_id, 0, address, addr_idx, data.state!=STORE); + //assert(ret.second==0); + } + else { + if(Reach(commit_id, last_r)){ + //LOG(ERROR)<<"commit id:"<Load(address, false); + data.data = ret.first; + data.version = ret.second; + } + bool ret = Connect(commit_id, 0, address, addr_idx, data.state!=STORE); + assert(ret); + //assert(ret.second==0); + } + else { + if(Reach(commit_id, last_w)){ + //assert(1==0); + //std::set rs = GetReach(commit_id, last_w); + // cycle? + #ifdef CDebug + // LOG(ERROR)<<"commit id:"<0){ + data.data = addr_changes_list_[last_w][addr_idx].data.data; + data.version = addr_changes_list_[last_w][addr_idx].data.version; + } + } + } + } + else { + if(data.state == STORE){ + if(change_set.back().state == LOAD){ + data.version = change_set.back().version+1; + } + else { + data.version = change_set.back().version; + } + } + else { + data.data = change_set.back().data; + data.version = change_set.back().version; + } + if(data.state == STORE){ + ConnectSelf(commit_id, commit_id, address, addr_idx); + if(aborted_[commit_id]){ + AbortNode(commit_id); + return false; + } + has_w = has_write_[commit_id]; + } + + auto git = graph_[addr_idx%2048].find(addr_idx); + assert(git != graph_[addr_idx%2048].end()); + GraphInfo * g = &git->second; + + auto& lrp = g->lastr_; + auto& lwp = g->lastw_; + + if(lrp.find(commit_id) != lrp.end()){ + if(data.state == STORE){ + lwp.insert(commit_id); + } + } + else if( lwp.find(commit_id) != lwp.end()){ + if(data.state == LOAD){ + lrp.insert(commit_id); + } + } + } +#ifdef CDebug +LOG(ERROR)<<"has w:"<0 && data.state == STORE){ + AbortNodeFrom(commit_id, address); + } + } + +// AddDataToChangeList(change_set, data); + #ifdef CDebug + //LOG(ERROR)<<"add commit id:"<"; + PrintReach(i,j); + PrintReach(j,i); + assert(1==0); + } + } + } + #endif + /* + for(int i = 1; i < 500; ++i){ + for(auto it : addr_pre_[i]){ + auto address = it.first; + for(int c : it.second){ + if(c==0)continue; + if(addr_child_[c][address].find(i) == addr_child_[c][address].end()){ + LOG(ERROR)<<" id:"<GetVersion(it.first, false); + if(op.state == STORE){ + /* + if(op.version+1 != v){ + LOG(ERROR)<<"state:"<0){ + if(pre_[commit_id].size()==1 && *pre_[commit_id].begin() == 0){ + } + else { + #ifdef CDebug + for(int f : pre_[commit_id]){ + LOG(ERROR)<<" wait for pre:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + //LOG(ERROR)<<"load"; + break; + case STORE: + //LOG(ERROR)<<"commit:"<StoreWithVersion(it.first, op.data, op.version, false); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, false); + done = true; + break; + } + } + } + + //LOG(ERROR)<<" commit id done:"< &FXController::GetRedo(){ + return redo_; +} +const std::vector &FXController::GetDone(){ + return done_; +} +uint64_t FXController::GetDelay(int64_t commit_id) { +return commit_delay_[commit_id]; +} + +} +} +} + diff --git a/platform/consensus/ordering/fides/executor/x_manager/fx_controller.cpp.bak3 b/platform/consensus/ordering/fides/executor/x_manager/fx_controller.cpp.bak3 new file mode 100644 index 000000000..9f61e8df4 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/fx_controller.cpp.bak3 @@ -0,0 +1,1891 @@ +#include "service/contract/executor/x_manager/fx_controller.h" + +#include +#include +#include + +#include "eEVM/exception.h" + +#include "common/utils/utils.h" + +#define CDebug +//#define DDebug + +namespace resdb { +namespace contract { +namespace x_manager { + +namespace { +int GetHashKey(const uint256_t& address){ + + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%2048; + } +} + +FXController::FXController(DataStorage * storage, int window_size) : + ConcurrencyController(storage), window_size_(window_size), storage_(storage){ + for(int i = 0; i < 32; i++){ + if((1<window_size_){ + window_size_ = (1< FXController::GetChangeList(int64_t commit_id){ + // read lock + //return std::move(changes_list_[commit_id]); + return nullptr; +} + +void FXController::Clear(int64_t commit_id){ +#ifdef CDebug + LOG(ERROR)<<"CLEAR id:"<& change_set, const Data& data){ + if(change_set.empty()){ + change_set.push_back(data); + } + else if(data.state != LOAD){ + if(change_set.back().state != LOAD){ + change_set.pop_back(); + } + change_set.push_back(data); + } + assert(change_set.size()<3); +} + +int FXController::GetLastR(const uint256_t& address, int addr_idx){ + #ifdef CDebug + LOG(ERROR)<<"get last r, lp size:"<second.empty()){ + //return -1; + //LOG(ERROR)<<"no last:"<second; + //return *--lp.end(); + return *lp.begin(); +} + +int FXController::GetLastW(const uint256_t& address, int addr_idx){ +#ifdef CDebug + LOG(ERROR)<<"get last w, lp size:"<second.empty()){ + /* + if(last_commit_.find(addr_idx) != last_commit_.end()){ + return last_commit_[addr_idx]; + } + */ + //return -1; + //LOG(ERROR)<<"no last:"<second; + //return *--lp.end(); + return *lp.begin(); +} + +int FXController::GetLastWOnly(const uint256_t& address, int addr_idx){ + return GetLastW(address, addr_idx); +} + + +void FXController::Abort(int64_t commit_id){ + if(aborted_[commit_id]){ + return; + } + aborted_[commit_id] = true; + //LOG(ERROR)<<"abort :"< q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + if(x==to) { + //LOG(ERROR)<<"access from:"< FXController::GetReach(int from){ + std::queue q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + for(int ch : child_[x]){ + if(v.find(ch) == v.end()){ + v.insert(ch); + q.push(ch); + } + } + } + //assert(reach_[to][from]==false); + return v; +} + +std::set FXController::GetReach(int from, int to){ + std::queue q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + if(x==to) { + //LOG(ERROR)<<"access from:"< q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + LOG(ERROR)<<"reach from:"< new_f; + std::vector new_cf; + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + #ifdef CDebug + LOG(ERROR)<<"connect idx:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"< r = GetReach(last_idx); + for(int cf: new_cf){ + if(r.find(cf) != r.end()){ + // cycle + #ifdef CDebug + LOG(ERROR)<<"have cycle after change:"< new_c; +std::vector check_c; + if(last_idx==0){ + for(int c : root_addr_[addr_idx_e][address]){ + if(!is_only_[c]){ + assert(!committed_[c]); + new_c.push_back(c); + } + else { + LOG(ERROR)<<"add check child:"<second.find(c) != root_it->second.end()); + root_it->second.erase(root_it->second.find(c)); + assert(addr_pre_[c][address].find(last_idx) != addr_pre_[c][address].end()); + addr_pre_[c][address].erase(addr_pre_[c][address].find(last_idx)); + } + } + else { + LOG(ERROR)<<"addr child:"<second.find(c) != it->second.end()); + it->second.erase(it->second.find(c)); + assert(addr_pre_[c][address].find(last_idx) != addr_pre_[c][address].end()); + addr_pre_[c][address].erase(addr_pre_[c][address].find(last_idx)); + } + } + + for(int c : new_c){ + addr_child_[idx][address].insert(c); + addr_pre_[c][address].insert(idx); + pre_[c].insert(idx); + child_[idx].insert(c); + LOG(ERROR)<<"add child:"<0){ + LOG(ERROR)<<" add check c:"< new_f; + std::vector new_cf; + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + #ifdef CDebug + LOG(ERROR)<<"connect idx:"<second){ + if(f==0){ + int addr_idx_e = addr_idx&window_size_; + auto& mp = root_addr_[addr_idx_e][address]; + int sz = mp.size(); + //LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + #ifdef CDebug + LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(committed_[cf]){ + continue; + } + if(cf == last_idx){ + continue; + } + + //assert(cf != last_idx); + new_cf.push_back(cf); + LOG(ERROR)<<"address:"<second.erase(ait->second.find(f)); + } + pre_[idx].insert(last_idx); + child_[last_idx].insert(idx); + LOG(ERROR)<<"connect:"< r = GetReach(last_idx); + for(int cf: new_cf){ + if(r.find(cf) != r.end()){ + // cycle +#ifdef CDebug + LOG(ERROR)<<"have cycle after change:"<second.insert(cf); + addr_child_[cf][address].insert(last_idx); + addr_pre_[last_idx][address].insert(cf); + child_[cf].insert(last_idx); + pre_[last_idx].insert(cf); + LOG(ERROR)<<"add edge :<"<second; + } + } + else { + last_r = GetLastR(address, addr_id); + } + // LOG(ERROR)<<"get last r:"<Load(address, false); + data.version = ret.second+1; + */ + data.version = 0; + Connect(commit_id, 0, address, addr_id, data.state!=STORE); + //assert(ret.second<=1); + } + else { + data.version = addr_changes_list_[last_r][addr_id].data.version+1; + bool ret = Connect(commit_id, last_r, address, addr_id, false); + if(!ret){ + LOG(ERROR)<<"connect commit:"<second; + //LOG(ERROR)<<"get from last:"<Load(address, false); + //LOG(ERROR)<<"load storage:"<Load(address, false); + // data.data = ret.first; + // data.version = ret.second; + if(is_only_[commit_id]){ + if(!ConnectOnly(commit_id, 0, address, addr_id, data.state!=STORE)){ + return false; + } + } + else { + bool ret = Connect(commit_id, 0, address, addr_id, data.state!=STORE); + assert(ret); + } + // assert(ret.second<=1); + } + else { + { + if(Reach(commit_id, last_w)){ + //assert(1==0); + //std::set rs = GetReach(commit_id, last_w); + // cycle? + #ifdef CDebug + // LOG(ERROR)<<"commit id:"<0){ + data.data = addr_changes_list_[last_w][addr_id].data.data; + data.version = addr_changes_list_[last_w][addr_id].data.version; + } + } + } + } + + //AddDataToChangeList(changes_list_[commit_id][address], data); + #ifdef CDebug + //LOG(ERROR)<<"add commit id:"< q; + q.push(commit_id); + + std::vector v(window_size_+1); + for(int i = 0; i <= window_size_; i++) v[i] = 0; + v[commit_id] = 1; + + while(!q.empty()){ + int x = q.front(); + q.pop(); + auto& cs = changes_list_[x][address]; + if(!cs.empty() && x != commit_id){ + if(cs.back().state == STORE){ + return x; + } + } + for(int f : addr_pre_[x][address]) { + if(v[f]==0){ + v[f] = 1; + q.push(f); + } + } + } + return -1; +} + +int FXController::FindR(int64_t commit_id, const uint256_t& address, int addr_idx) { + + std::queue q; + q.push(commit_id); + + std::vector v(window_size_+1); + for(int i = 0; i <= window_size_; i++) v[i] = 0; + v[commit_id] = 1; + + while(!q.empty()){ + int x = q.front(); + q.pop(); + auto& cs = changes_list_[x][address]; + if(!cs.empty()){ + if(cs.front().state == LOAD){ + return x; + } + } + for(int f : pre_[x]) { + if(v[f]==0){ + v[f] = 1; + q.push(f); + } + } + } + return -1; +} + + +bool FXController::AddOldNode(const uint256_t& address, int addr_idx, + int64_t commit_id, Data& data) { + + #ifdef CDebug + LOG(ERROR)<<"add old node address:"<Load(address, false); + data.version = ret.second+1; + */ + data.version = 0; + Connect(commit_id, 0, address, addr_idx, data.state!=STORE); + //assert(ret.second==0); + } + else { + if(Reach(commit_id, last_r)){ + //LOG(ERROR)<<"commit id:"<second; + //LOG(ERROR)<<"get from last:"<Load(address, false); + data.data = ret.first; + data.version = ret.second; + } + if(is_only_[commit_id]){ + if(!ConnectOnly(commit_id, 0, address, addr_idx, data.state!=STORE)){ + return false; + } + } + else { + bool ret = Connect(commit_id, 0, address, addr_idx, data.state!=STORE); + assert(ret); + } + //assert(ret.second==0); + } + else { + if(Reach(commit_id, last_w)){ + //assert(1==0); + //std::set rs = GetReach(commit_id, last_w); + // cycle? + #ifdef CDebug + // LOG(ERROR)<<"commit id:"<0){ + data.data = addr_changes_list_[last_w][addr_idx].data.data; + data.version = addr_changes_list_[last_w][addr_idx].data.version; + } + } + } + } + else { + if(data.state == STORE){ + if(change_set.back().state == LOAD){ + data.version = change_set.back().version+1; + } + else { + data.version = change_set.back().version; + } + } + else { + data.data = change_set.back().data; + data.version = change_set.back().version; + } + if(data.state == STORE){ + ConnectSelf(commit_id, commit_id, address, addr_idx); + if(aborted_[commit_id]){ + AbortNode(commit_id); + return false; + } + has_w = has_write_[commit_id]; + } + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + + if(lrp.find(commit_id) != lrp.end()){ + if(data.state == STORE){ + lwp.insert(commit_id); + } + } + else if( lwp.find(commit_id) != lwp.end()){ + if(data.state == LOAD){ + lrp.insert(commit_id); + } + } + } +#ifdef CDebug +LOG(ERROR)<<"has w:"<0 && data.state == STORE){ + AbortNodeFrom(commit_id, address); + } + } + +// AddDataToChangeList(change_set, data); + #ifdef CDebug + //LOG(ERROR)<<"add commit id:"<"; + PrintReach(i,j); + PrintReach(j,i); + assert(1==0); + } + } + } + #endif + for(int i = 1; i < 500; ++i){ + for(auto it : addr_pre_[i]){ + auto address = it.first; + for(int c : it.second){ + if(c==0)continue; + if(addr_child_[c][address].find(i) == addr_child_[c][address].end()){ + LOG(ERROR)<<" id:"<GetVersion(it.first, false); + if(op.state == STORE){ + /* + if(op.version+1 != v){ + LOG(ERROR)<<"state:"<0){ + if(pre_[commit_id].size()==1 && *pre_[commit_id].begin() == 0){ + } + else { + #ifdef CDebug + for(int f : pre_[commit_id]){ + LOG(ERROR)<<" wait for pre:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + //LOG(ERROR)<<"load"; + break; + case STORE: + LOG(ERROR)<<"commit:"<StoreWithVersion(it.first, op.data, op.version, false); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, false); + done = true; + break; + } + } + } + + //LOG(ERROR)<<" commit id done:"< &FXController::GetRedo(){ + return redo_; +} +const std::vector &FXController::GetDone(){ + return done_; +} +uint64_t FXController::GetDelay(int64_t commit_id) { +return commit_delay_[commit_id]; +} + +} +} +} + diff --git a/platform/consensus/ordering/fides/executor/x_manager/fx_controller.h b/platform/consensus/ordering/fides/executor/x_manager/fx_controller.h new file mode 100644 index 000000000..6f01efdcb --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/fx_controller.h @@ -0,0 +1,152 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/data_storage.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class FXController : public ConcurrencyController { + public: + FXController(DataStorage * storage, int window_size); + virtual ~FXController(); + + // ============================== + virtual void Store(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + virtual uint256_t Load(const int64_t commit_id, const uint256_t& key, int version); + bool Remove(const int64_t commit_id, const uint256_t& key, int version); + + + // ============================== + typedef std::map > CommitList; + + const std::vector& GetDone(); + const std::vector &GetRedo(); + + void PushCommit(int64_t commit_id, const ModifyMap& local_changes_){} + bool Commit(int64_t commit_id); + + void StoreInternal(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + uint256_t LoadInternal(const int64_t commit_id, const uint256_t& key, int version); + + std::unique_ptr GetChangeList(int64_t commit_id); + + void Clear(); + void Clear(int64_t commit_id); + uint64_t GetDelay(int64_t commit_id); +void SetOnly(int commit_id); + + private: + + bool CommitUpdates(int64_t commit_id); + + bool CheckCommit(int64_t commit_id); + + void AppendPreRecord(const uint256_t& address, + int64_t commit_id, Data& data); + + int GetLastR(const uint256_t& address, int addr_id); + int GetLastW(const uint256_t& address, int addr_id); + int GetLastWOnly(const uint256_t& address, int addr_id); + int FindW(int64_t commit_id, const uint256_t& address, int addr_id); + int FindR(int64_t commit_id, const uint256_t& address, int addr_id); + + bool Connect(int idx, int last_idx, const uint256_t& address, int addr_idx, bool is_read); + void ConnectSelf(int idx, int last_idx, const uint256_t& address, int addr_idx); + bool AddNewNode(const uint256_t& address, int addr_idx, int64_t commit_id, Data& data); + bool AddOldNode(const uint256_t& address, int addr_idx, int64_t commit_id, Data& data); + void AddDataToChangeList(std::vector& change_set, const Data& data); + + void RecursiveAbort(int64_t idx, const uint256_t& address); + void AbortNodeFrom(int64_t idx, const uint256_t& address); + void AbortNode(int64_t idx); + bool ContainRead(int commit_id, const uint256_t &address); + + void RemoveNode(int64_t commit_id); + + void Abort(const int64_t commit_id); + bool Reach(int from, int to); + bool PrintReach(int from, int to); + std::set GetReach(int from, int to); + std::set GetReach(int from); + + int GetDep(int from, int to); + void AddRedo(int64_t commit_id); + + int AddressToId(const uint256_t& key); + uint256_t& GetAddress(int key); + + void ResetReach(int64_t commit_id); + void Update(const std::vector& commit_id) ; + void AttachReadOnly(int commit_id, const uint256_t& address); + void ReadReadOnly(int commit_id, const uint256_t& address, Data &data); + void AddDataSnap(int commit_idx, const uint256_t& address, const uint256_t& data, int64_t version); + + private: + int window_size_ = 1000; + + struct DataInfo { + int64_t commit_id; + int type; + Data data; + int version; + DataInfo():type(0){} + DataInfo(int64_t commit_id, int type, Data&data) : commit_id(commit_id), type(type), data(data){} + }; + + //typedef std::map>> KeyMap; + std::vector changes_list_; + std::vector> addr_changes_list_; + //std::vector> changes_list_; + + std::set pd_; + std::vector redo_; + std::vector done_; + DataStorage* storage_; + std::vector wait_; + std::mutex mutex_[2048], abort_mutex_; + std::mutex g_mutex_, k_mutex_[2048], s_mutex_; + std::map > lock_[2048]; + bool aborted_[2048]; + bool is_redo_[2048]; + bool finish_[2048]; + bool committed_[2048]; + bool has_write_[2048]; + std::vector abort_list_; + std::set pre_[2048]; + std::set child_[2048]; + std::bitset<2048> reach_[2048]; + + std::map> addr_pre_[2048]; + std::map> addr_child_[2048]; + std::map> root_addr_[2048]; + std::unordered_map > lastr_, lastw_; + + std::unordered_map> check_; + std::set check_abort_; + std::vector post_abort_, pending_check_; + std::map key_[2048]; + std::unordered_map akey_; + std::atomic key_id_; + bool ds_ = false; + uint64_t commit_time_[2048], commit_delay_[2048]; + bool is_only_[2048]; + + std::map >> commit_list_; + int last_commit_; + int attach_[2048]; + int commit_idx_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/fx_controller.h.bak3 b/platform/consensus/ordering/fides/executor/x_manager/fx_controller.h.bak3 new file mode 100644 index 000000000..f55e647ac --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/fx_controller.h.bak3 @@ -0,0 +1,149 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/data_storage.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class FXController : public ConcurrencyController { + public: + FXController(DataStorage * storage, int window_size); + virtual ~FXController(); + + // ============================== + virtual void Store(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + virtual uint256_t Load(const int64_t commit_id, const uint256_t& key, int version); + bool Remove(const int64_t commit_id, const uint256_t& key, int version); + + + // ============================== + typedef std::map > CommitList; + + const std::vector& GetDone(); + const std::vector &GetRedo(); + + void PushCommit(int64_t commit_id, const ModifyMap& local_changes_){} + bool Commit(int64_t commit_id); + + void StoreInternal(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + uint256_t LoadInternal(const int64_t commit_id, const uint256_t& key, int version); + + std::unique_ptr GetChangeList(int64_t commit_id); + + void Clear(); + void Clear(int64_t commit_id); + uint64_t GetDelay(int64_t commit_id); +void SetOnly(int commit_id); + + private: + + bool CommitUpdates(int64_t commit_id); + + bool CheckCommit(int64_t commit_id); + + void AppendPreRecord(const uint256_t& address, + int64_t commit_id, Data& data); + + int GetLastR(const uint256_t& address, int addr_id); + int GetLastW(const uint256_t& address, int addr_id); + int GetLastWOnly(const uint256_t& address, int addr_id); + int FindW(int64_t commit_id, const uint256_t& address, int addr_id); + int FindR(int64_t commit_id, const uint256_t& address, int addr_id); + + bool Connect(int idx, int last_idx, const uint256_t& address, int addr_idx, bool is_read); + void ConnectSelf(int idx, int last_idx, const uint256_t& address, int addr_idx); + bool AddNewNode(const uint256_t& address, int addr_idx, int64_t commit_id, Data& data); + bool AddOldNode(const uint256_t& address, int addr_idx, int64_t commit_id, Data& data); + void AddDataToChangeList(std::vector& change_set, const Data& data); + + void RecursiveAbort(int64_t idx, const uint256_t& address); + void AbortNodeFrom(int64_t idx, const uint256_t& address); + void AbortNode(int64_t idx); + bool ContainRead(int commit_id, const uint256_t &address); + + void RemoveNode(int64_t commit_id); + + void Abort(const int64_t commit_id); + bool Reach(int from, int to); + bool PrintReach(int from, int to); + std::set GetReach(int from, int to); + std::set GetReach(int from); + + int GetDep(int from, int to); + void AddRedo(int64_t commit_id); + + int AddressToId(const uint256_t& key); + uint256_t& GetAddress(int key); + + void ResetReach(int64_t commit_id); + void Update(const std::vector& commit_id) ; + bool ConnectOnly(int idx, int last_idx, const uint256_t& address, int addr_idx, bool is_read); + + private: + int window_size_ = 1000; + + struct DataInfo { + int64_t commit_id; + int type; + Data data; + int version; + DataInfo():type(0){} + DataInfo(int64_t commit_id, int type, Data&data) : commit_id(commit_id), type(type), data(data){} + }; + + //typedef std::map>> KeyMap; + std::vector changes_list_; + std::vector> addr_changes_list_; + //std::vector> changes_list_; + + std::set pd_; + std::vector redo_; + std::vector done_; + DataStorage* storage_; + std::vector wait_; + std::mutex mutex_[2048], abort_mutex_; + std::mutex g_mutex_, k_mutex_[2048]; + std::map > lock_[2048]; + bool aborted_[2048]; + bool is_redo_[2048]; + bool finish_[2048]; + bool committed_[2048]; + bool has_write_[2048]; + std::vector abort_list_; + std::set pre_[2048]; + std::set child_[2048]; + std::bitset<2048> reach_[2048]; + + std::map> addr_pre_[2048]; + std::map> addr_child_[2048]; + std::map> root_addr_[2048]; + std::unordered_map > lastr_, lastw_; + + std::unordered_map> check_; + std::set check_abort_; + std::vector post_abort_, pending_check_; + std::map key_[2048]; + std::unordered_map akey_; + std::atomic key_id_; + bool ds_ = false; + uint64_t commit_time_[2048], commit_delay_[2048]; + std::unordered_map last_commit_; + std::unordered_map last_commit_only_; + bool is_only_[2048]; + std::map has_addr_write_[2048]; + std::map> last_r_, last_w_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/global_state.cpp b/platform/consensus/ordering/fides/executor/x_manager/global_state.cpp new file mode 100644 index 000000000..3ccd6453e --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/global_state.cpp @@ -0,0 +1,52 @@ +#include "service/contract/executor/x_manager/global_state.h" + +#include + +namespace resdb { +namespace contract { +namespace x_manager { + +using eevm::Address; +using eevm::AccountState; +using eevm::Code; +using eevm::SimpleAccount; + + GlobalState::GlobalState(DataStorage * storage) : storage_(storage) { + } + + bool GlobalState::Exists(const eevm::Address& addr) { + return accounts.find(addr) != accounts.cend(); + } + + void GlobalState::remove(const Address& addr) { + accounts.erase(addr); + } + + AccountState GlobalState::get(const Address& addr) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()) + return acc->second; + + return create(addr, 0, {}); + } + + AccountState GlobalState::create( + const Address& addr, const uint256_t& balance, const Code& code) { + Insert({SimpleAccount(addr, balance, code), GlobalView(storage_)}); + + return get(addr); + } + + const eevm::SimpleAccount& GlobalState::GetAccount(const eevm::Address& addr) { + const auto acc = accounts.find(addr); + return acc->second.first; + } + + void GlobalState::Insert(const StateEntry& p) { + const auto ib = accounts.insert(std::make_pair(p.first.get_address(), p)); + + assert(ib.second); + } +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/global_state.h b/platform/consensus/ordering/fides/executor/x_manager/global_state.h new file mode 100644 index 000000000..04767ad28 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/global_state.h @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include "service/contract/executor/x_manager/global_view.h" +#include "service/contract/executor/x_manager/evm_state.h" + +#include "eEVM/simple/simpleaccount.h" + +namespace resdb { +namespace contract { +namespace x_manager { + + class GlobalState : public EVMState{ + public: + using StateEntry = std::pair; + + public: + GlobalState(DataStorage* storage); + virtual ~GlobalState() = default; + + virtual void remove(const eevm::Address& addr) override; + + // Get contract by contract address. + eevm::AccountState get(const eevm::Address& addr) override; + + bool Exists(const eevm::Address& addr); + + // Create an account for the contract, which the balance is 0. + eevm::AccountState create( + const eevm::Address& addr, const uint256_t& balance, const eevm::Code& code) override; + + const eevm::SimpleAccount& GetAccount(const eevm::Address& addr) ; + + protected: + void Insert(const StateEntry& p); + + private: + std::map accounts; + DataStorage* storage_; + }; + +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/global_view.cpp b/platform/consensus/ordering/fides/executor/x_manager/global_view.cpp new file mode 100644 index 000000000..dc88a2124 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/global_view.cpp @@ -0,0 +1,27 @@ +#include "service/contract/executor/x_manager/global_view.h" + +#include "eEVM/util.h" + +#include + +namespace resdb { +namespace contract { +namespace x_manager { + +GlobalView::GlobalView(DataStorage* storage) :storage_(storage){ } + +void GlobalView::store(const uint256_t& key, const uint256_t& value) { + storage_->Store(key, value); +} + +uint256_t GlobalView::load(const uint256_t& key) { + return storage_->Load(key).first; +} + +bool GlobalView::remove(const uint256_t& key) { + return storage_->Remove(key); +} + +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/global_view.h b/platform/consensus/ordering/fides/executor/x_manager/global_view.h new file mode 100644 index 000000000..09915d438 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/global_view.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include "service/contract/executor/x_manager/data_storage.h" +#include "eEVM/storage.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class GlobalView : public eevm::Storage { + +public: + GlobalView(DataStorage* storage); + virtual ~GlobalView() = default; + + void store(const uint256_t& key, const uint256_t& value) override; + uint256_t load(const uint256_t& key) override; + bool remove(const uint256_t& key) override; + +private: + DataStorage * storage_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/leveldb.cpp b/platform/consensus/ordering/fides/executor/x_manager/leveldb.cpp new file mode 100644 index 000000000..b540aed45 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/leveldb.cpp @@ -0,0 +1,30 @@ +#include "service/contract/executor/manager/leveldb.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +LevelDB::LevelDB(){ + db_ = std::make_unique("./"); + db_->SetBatchSize(10000); +} + +void LevelDB::Flush(){ + //LOG(ERROR)<<"flush"; + for(const auto& it : s){ + std::string addr = eevm::to_hex_string(it.first); + std::string value = eevm::to_hex_string(it.second.first); + //LOG(ERROR)<<"addr:"<SetValue(addr, std::string(buf, value.size()+sizeof(it.second.second))); + delete buf; + } +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/leveldb.h b/platform/consensus/ordering/fides/executor/x_manager/leveldb.h new file mode 100644 index 000000000..e76ca274f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/leveldb.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#include "eEVM/util.h" +#include "service/contract/executor/manager/data_storage.h" +#include "storage/res_leveldb.h" + +namespace resdb { +namespace contract { + +class LevelDB : public DataStorage { + +public: + LevelDB(); + virtual ~LevelDB() = default; + + virtual void Flush(); + +private: + std::unique_ptr db_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/leveldb_d_storage.cpp b/platform/consensus/ordering/fides/executor/x_manager/leveldb_d_storage.cpp new file mode 100644 index 000000000..9f2f94f1d --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/leveldb_d_storage.cpp @@ -0,0 +1,210 @@ +#include "service/contract/executor/x_manager/leveldb_d_storage.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +namespace { + + int GetHashKey(const uint256_t& address){ + // Get big-endian form + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%1024; + } +void Write(const uint256_t& key, const uint256_t& value, int version, ResLevelDB * db){ + std::string addr = eevm::to_hex_string(key); + + const uint8_t* bytes = intx::as_bytes(value); + size_t sz = sizeof(value); + db->SetValue(addr, std::string((const char*)bytes, sz)); + return; +} + +uint256_t Read(const uint256_t& key, ResLevelDB * db){ + std::string addr = eevm::to_hex_string(key); + + std::string v = db->GetValue(addr); + if(v.empty()){ + return 0; + } + + uint8_t tmp[32] = {}; + memcpy(tmp, v.c_str(), 32); + return intx::le::load(tmp); +} + + +void InternalReset(const uint256_t& key, const uint256_t& value, int64_t version, + std::map > * db, std::shared_mutex * mutex, ResLevelDB * storage ) { + + std::unique_lock lock(*mutex); + (*db)[key] = std::make_pair(value,version); + if(storage) { + Write(key, value, version, storage); + } +} + +int64_t InternalStore(const uint256_t& key, const uint256_t& value, + std::map > * db, std::shared_mutex * mutex, ResLevelDB * storage ) { + + std::unique_lock lock(*mutex); + int64_t v = (*db)[key].second; + (*db)[key] = std::make_pair(value,v+1); + if(storage) { + Write(key, value, v+1, storage); + } + return v+1; +} + +std::pair InternalLoad(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex, ResLevelDB * storage){ + + std::shared_lock lock(*mutex); + auto e = db->find(key); + if (e == db->end()){ + if(storage) { + return std::make_pair(Read(key, storage), 0); + } + return std::make_pair(0,0); + } + return e->second; +} + +bool InternalRemove(const uint256_t& key, + std::map > * db, + std::shared_mutex * mutex) { + + std::unique_lock lock(*mutex); + auto e = db->find(key); + if (e == db->end()) + return false; + db->erase(e); + return true; +} + +bool InternalExist(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + return db->find(key) != db->end(); +} + +int64_t InternalGetVersion(const uint256_t& key, + const std::map > * db, + std::shared_mutex * mutex) { + std::shared_lock lock(*mutex); + auto it = db->find(key); + if( it == db->end()){ + return 0; + } + return it->second.second; +} + +} + +LevelDB_D_Storage :: LevelDB_D_Storage(){ + db_ = std::make_unique("./"); +} + +int64_t LevelDB_D_Storage::StoreWithVersion(const uint256_t& key, const uint256_t& value, int version, bool is_local) { +//LOG(ERROR)<<"storage key:"< LevelDB_D_Storage::Load(const uint256_t& key, bool is_local_view) const { + //LOG(ERROR)<<"load key:"<second.second)<<" key:"< +#include + +#include "service/contract/executor/x_manager/data_storage.h" +#include "storage/res_leveldb.h" + +namespace resdb { +namespace contract { + +class LevelDB_D_Storage : public DataStorage { +public: + LevelDB_D_Storage(); + +public: + virtual int64_t Store(const uint256_t& key, const uint256_t& value, bool is_local); + virtual int64_t StoreWithVersion(const uint256_t& key, const uint256_t& value, int version, bool is_local); + virtual std::pair Load(const uint256_t& key, bool is_from_local_view) const; + virtual bool Remove(const uint256_t& key, bool is_local); + virtual bool Exist(const uint256_t& key, bool is_local) const; + + virtual int64_t GetVersion(const uint256_t& key, bool is_local) const; + + virtual void Reset(const uint256_t& key, const uint256_t& value, int64_t version, bool is_local); + +protected: + std::map > c_s_[1024]; + mutable std::shared_mutex mutex_[1024]; + + std::map > g_s_[1024]; + mutable std::shared_mutex g_mutex_[1024]; + + std::unique_ptr db_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/leveldb_storage.cpp b/platform/consensus/ordering/fides/executor/x_manager/leveldb_storage.cpp new file mode 100644 index 000000000..1e1cb5a14 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/leveldb_storage.cpp @@ -0,0 +1,122 @@ +#include "service/contract/executor/x_manager/leveldb_storage.h" + +#include "glog/logging.h" + + +namespace resdb { +namespace contract { + +namespace { + + int GetHashKey(const uint256_t& address){ + // Get big-endian form + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return 0; + return v%2048; + } +} + +LevelDBStorage :: LevelDBStorage(){ + db_ = std::make_unique("./"); +} + +void LevelDBStorage::Write(const uint256_t& key, const uint256_t& value, int version){ + std::string addr = eevm::to_hex_string(key); + + const uint8_t* bytes = intx::as_bytes(value); + size_t sz = sizeof(value); + db_->SetValue(addr, std::string((const char*)bytes, sz)); + return; + + //LOG(ERROR)<<"addr:"<SetValue(addr, std::string(buf, sz+sizeof(version))); + LOG(ERROR)<<"write db"; + delete buf; +} + +uint256_t LevelDBStorage::Read(const uint256_t& key) const { + std::string addr = eevm::to_hex_string(key); + + std::string v = db_->GetValue(addr); + if(v.empty()){ + return 0; + } + + uint8_t tmp[32] = {}; + memcpy(tmp, v.c_str(), 32); + return intx::le::load(tmp); +} + +int64_t LevelDBStorage::Store(const uint256_t& key, const uint256_t& value, bool) { + int idx = GetHashKey(key); + std::unique_lock lock(mutex_[idx]); + //LOG(ERROR)<<"store key:"< LevelDBStorage::Load(const uint256_t& key, bool) const { +int idx = GetHashKey(key); + std::shared_lock lock(mutex_[idx]); + //LOG(ERROR)<<"load key:"<second; +} + +bool LevelDBStorage::Remove(const uint256_t& key, bool) { +int idx = GetHashKey(key); + std::unique_lock lock(mutex_[idx]); + auto e = s[idx].find(key); + if (e == s[idx].end()) + return false; + s[idx].erase(e); + return true; +} + +bool LevelDBStorage::Exist(const uint256_t& key, bool) const { +int idx = GetHashKey(key); + std::shared_lock lock(mutex_[idx]); + return s[idx].find(key) != s[idx].end(); +} + +int64_t LevelDBStorage::GetVersion(const uint256_t& key, bool) const{ +int idx = GetHashKey(key); + std::shared_lock lock(mutex_[idx]); + auto it = s[idx].find(key); + if( it == s[idx].end()){ + return 0; + } + return it->second.second; +} + +int64_t LevelDBStorage::StoreWithVersion(const uint256_t& key, const uint256_t& value, int version, bool ) { + int idx = GetHashKey(key); + std::unique_lock lock(mutex_[idx]); + s[idx][key] = std::make_pair(value,version); + Write(key, value, version); + return 0; +} + + + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/leveldb_storage.h b/platform/consensus/ordering/fides/executor/x_manager/leveldb_storage.h new file mode 100644 index 000000000..c93df7a70 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/leveldb_storage.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include + +#include "service/contract/executor/x_manager/data_storage.h" +#include "storage/res_leveldb.h" + +namespace resdb { +namespace contract { + +class LevelDBStorage : public DataStorage { + +public: + LevelDBStorage(); + virtual ~LevelDBStorage() = default; + + virtual int64_t Store(const uint256_t& key, const uint256_t& value, bool is_local = false); + virtual std::pair Load(const uint256_t& key, bool is_local_view = false) const; + virtual bool Remove(const uint256_t& key, bool is_local = false); + virtual bool Exist(const uint256_t& key, bool is_local = false) const; + virtual int64_t StoreWithVersion(const uint256_t& key, const uint256_t& value, int version, bool is_local = false); + + virtual int64_t GetVersion(const uint256_t& key, bool is_local = false) const; + + virtual void Reset(const uint256_t& key, const uint256_t& value, int64_t version, bool is_local = false) {} + virtual void Flush(){}; + +private: + void Write(const uint256_t& key, const uint256_t& value, int version); + uint256_t Read(const uint256_t& key) const; + +protected: + std::map > s[4096]; + mutable std::shared_mutex mutex_[4096]; + std::unique_ptr db_; +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/local_state.cpp b/platform/consensus/ordering/fides/executor/x_manager/local_state.cpp new file mode 100644 index 000000000..f1b02cfcb --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/local_state.cpp @@ -0,0 +1,75 @@ +#include "service/contract/executor/x_manager/local_state.h" + +#include + +namespace resdb { +namespace contract { +namespace x_manager { + +using eevm::Address; +using eevm::AccountState; +using eevm::Code; +using eevm::SimpleAccount; + + LocalState::LocalState(ConcurrencyController * controller) : controller_(controller) { + } + + bool LocalState::Exists(const eevm::Address& addr) { + return accounts.find(addr) != accounts.cend(); + } + + void LocalState::remove(const Address& addr) { + accounts.erase(addr); + } + + AccountState LocalState::get(const Address& addr) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()) + return acc->second; + + return create(addr, 0, {}); + } + + AccountState LocalState::create( + const Address& addr, const uint256_t& balance, const Code& code) { + Insert({SimpleAccount(addr, balance, code), LocalView(controller_, 0)}); + return get(addr); + } + + const eevm::SimpleAccount& LocalState::GetAccount(const eevm::Address& addr) { + const auto acc = accounts.find(addr); + return acc->second.first; + } + + void LocalState::Set(const eevm::SimpleAccount& acc, int64_t commit_id) { + Insert({acc, LocalView(controller_, commit_id)}); + } + + void LocalState::Insert(const StateEntry& p) { + const auto ib = accounts.insert(std::make_pair(p.first.get_address(), p)); + + assert(ib.second); + } + + bool LocalState::Flesh(const Address& addr, int commit_id) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()){ + acc->second.second.Flesh(commit_id); + return true; + } + return false; + } + +/* + bool LocalState::Commit(const eevm::Address& addr) { + const auto acc = accounts.find(addr); + if (acc != accounts.cend()){ + return acc->second.second.Commit(); + } + return false; + } + */ + +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/local_state.h b/platform/consensus/ordering/fides/executor/x_manager/local_state.h new file mode 100644 index 000000000..82c518aaf --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/local_state.h @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include "service/contract/executor/x_manager/local_view.h" +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/evm_state.h" + +#include "eEVM/simple/simpleaccount.h" + +namespace resdb { +namespace contract { +namespace x_manager { + + class LocalState : public EVMState { + public: + using StateEntry = std::pair; + + public: + LocalState(ConcurrencyController * controller); + virtual ~LocalState() = default; + + virtual void remove(const eevm::Address& addr) override; + + // Get contract by contract address. + eevm::AccountState get(const eevm::Address& addr) override; + + bool Exists(const eevm::Address& addr); + + // Flesh the local view to the controller with a commit id. + // Once all the contracts have fleshed their changes, they should call commit. + // Return false if contract not exists. + bool Flesh(const eevm::Address& addr, int commit_id); + // Commit the changes using the commit id from the flesh. + //bool Commit(const eevm::Address& addr); + + // Create an account for the contract, which the balance is 0. + eevm::AccountState create( + const eevm::Address& addr, const uint256_t& balance, const eevm::Code& code) override; + + const eevm::SimpleAccount& GetAccount(const eevm::Address& addr) ; + void Set(const eevm::SimpleAccount& acc, int64_t commit_id); + + protected: + void Insert(const StateEntry& p); + + private: + std::map accounts; + ConcurrencyController * controller_; + }; + +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/local_view.cpp b/platform/consensus/ordering/fides/executor/x_manager/local_view.cpp new file mode 100644 index 000000000..c46eabb00 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/local_view.cpp @@ -0,0 +1,59 @@ +#include "service/contract/executor/x_manager/local_view.h" + +#include "eEVM/util.h" + +#include + +namespace resdb { +namespace contract { +namespace x_manager { + +LocalView::LocalView(ConcurrencyController * controller, int64_t commit_id) + :controller_(controller), + commit_id_(commit_id){ } + +void LocalView::store(const uint256_t& key, const uint256_t& value) { + //LOG(ERROR)<<"========= store key:"< load_value = controller_->GetStorage()->Load(key, /*is_from_local=*/true); + local_changes_[key].push_back(Data(STORE, value, load_value.second, load_value.first)); + } + else { + const Data& data = local_changes_[key].back(); + if(data.state == LOAD){ + local_changes_[key].push_back(Data(STORE, value, data.version+1)); + } + else { + local_changes_[key].pop_back(); + local_changes_[key].push_back(Data(STORE, value, data.version)); + } + } +} + +uint256_t LocalView::load(const uint256_t& key) { + //LOG(ERROR)<<"load key:"< value = controller_->GetStorage()->Load(key, /*is_from_local=*/true); + local_changes_[key].push_back(Data(LOAD, value.first, value.second)); + return value.first; + } + return it->second.back().data; +} + +bool LocalView::remove(const uint256_t& key) { + local_changes_[key].push_back(Data(REMOVE)); + return true; +} + +void LocalView::Flesh(int64_t commit_id) { + commit_id_ = commit_id; + //LOG(ERROR)<<"commit push:"<PushCommit(commit_id, local_changes_); + local_changes_.clear(); +} + +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/local_view.h b/platform/consensus/ordering/fides/executor/x_manager/local_view.h new file mode 100644 index 000000000..3dca1b7fb --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/local_view.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "eEVM/storage.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class LocalView : public eevm::Storage { + +public: + LocalView(ConcurrencyController * controller, int64_t commit_id); + virtual ~LocalView() = default; + + void store(const uint256_t& key, const uint256_t& value) override; + uint256_t load(const uint256_t& key) override; + bool remove(const uint256_t& key) override; + + // for 2PL, once it is done, all the commit will be pushed to + // the controller to judge if it can be committed. + // During the flesh, all the changes will be removed. + void Flesh(int64_t commit_id); + // Commit the changes. If there is a conflict, return false. + // Make sure all other committers have pushed their changes before calling Commit. + //bool Commit(); + // Remove all the changes. + //void Abort(); + +private: + ConcurrencyController * controller_; + int64_t commit_id_; + std::map> local_changes_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/local_view_test.cpp b/platform/consensus/ordering/fides/executor/x_manager/local_view_test.cpp new file mode 100644 index 000000000..f05672a9f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/local_view_test.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/local_view.h" +#include "service/contract/executor/manager/two_phase_controller.h" + +#include +#include + +namespace resdb { +namespace contract { +namespace { + +using ::testing::Test; + +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +TEST(LocalViewTest, ViewChange) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + LocalView view(&controller, 0); + + EXPECT_EQ(view.load(address1), 2000) ; + view.store(address1, 3000); + EXPECT_EQ(view.load(address1), 3000) ; + + // storage still contains 2000 + EXPECT_EQ(storage.Load(address1).first, 2000); +} + +TEST(LocalViewTest, CommitChange) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + LocalView view(&controller, 0); + + EXPECT_EQ(view.load(address1), 2000) ; + view.store(address1, 3000); + EXPECT_EQ(view.load(address1), 3000) ; + + // storage still contains 2000 + EXPECT_EQ(storage.Load(address1).first, 2000); + + view.Flesh(0); + EXPECT_TRUE(controller.Commit(0)); + // Save to real storage. + EXPECT_EQ(storage.Load(address1).first, 3000); +} + +TEST(LocalViewTest, CommitConflict) { + DataStorage storage; + uint256_t address1 = HexToInt("0x123"); + + storage.Store(address1, 2000); + EXPECT_EQ(storage.Load(address1).first, 2000); + + TwoPhaseController controller(&storage); + + LocalView view1(&controller, 0); + LocalView view2(&controller, 1); + + EXPECT_EQ(view1.load(address1), 2000) ; + view1.store(address1, 3000); + EXPECT_EQ(view1.load(address1), 3000) ; + + // storage still contains 2000 + EXPECT_EQ(storage.Load(address1).first, 2000); + + + EXPECT_EQ(view2.load(address1), 2000) ; + view2.store(address1, 4000); + EXPECT_EQ(view2.load(address1), 4000) ; + + // storage still contains 2000 + EXPECT_EQ(storage.Load(address1).first, 2000); + + + view1.Flesh(0); + view2.Flesh(1); + + EXPECT_FALSE(controller.Commit(1)); + EXPECT_TRUE(controller.Commit(0)); + + // Save to real storage. + EXPECT_EQ(storage.Load(address1).first, 3000); +} + + + +} // namespace +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/mock_d_storage.h b/platform/consensus/ordering/fides/executor/x_manager/mock_d_storage.h new file mode 100644 index 000000000..976bf9e7f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/mock_d_storage.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "gmock/gmock.h" +#include "service/contract/executor/x_manager/d_storage.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class MockDStorage : public D_Storage { + public: + typedef std::pair LoadType; + + MOCK_METHOD(int64_t, Store, (const uint256_t& key, const uint256_t& value, bool), (override)); + MOCK_METHOD(int64_t, StoreWithVersion, (const uint256_t& key, const uint256_t& value, int version, bool), (override)); + MOCK_METHOD(bool, Remove, (const uint256_t&, bool), (override)); + MOCK_METHOD(bool, Exist, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(int64_t, GetVersion, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(LoadType, Load, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(void, Reset, (const uint256_t&, const uint256_t&, int64_t, bool), (override)); +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/mock_data_storage.h b/platform/consensus/ordering/fides/executor/x_manager/mock_data_storage.h new file mode 100644 index 000000000..fa6743374 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/mock_data_storage.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "gmock/gmock.h" +#include "service/contract/executor/x_manager/data_storage.h" + +namespace resdb { +namespace contract { + +class MockStorage : public DataStorage { + public: + typedef std::pair LoadType; + + MOCK_METHOD(int64_t, Store, (const uint256_t& key, const uint256_t& value, bool), (override)); + MOCK_METHOD(bool, Remove, (const uint256_t&, bool), (override)); + MOCK_METHOD(bool, Exist, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(int64_t, GetVersion, (const uint256_t&, bool), (const, override)); + MOCK_METHOD(LoadType, Load, (const uint256_t&, bool), (const, override)); +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/mock_e_controller.h b/platform/consensus/ordering/fides/executor/x_manager/mock_e_controller.h new file mode 100644 index 000000000..afdfc58bd --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/mock_e_controller.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "gmock/gmock.h" +#include "service/contract/executor/x_manager/streaming_e_controller.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class MockEController : public StreamingEController { + public: + MockEController(DataStorage* storage, int window):StreamingEController(storage, window){} + + MOCK_METHOD(void, Store, (const int64_t, const uint256_t& key, const uint256_t& value, int), (override)); + MOCK_METHOD(uint256_t, Load, (const int64_t, const uint256_t&, int), (override)); +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/seq_committer.cpp b/platform/consensus/ordering/fides/executor/x_manager/seq_committer.cpp new file mode 100644 index 000000000..a3f5f8193 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/seq_committer.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/seq_committer.h" +#include "service/contract/executor/x_manager/executor_state.h" + +#include +#include + +#include "common/utils/utils.h" +#include "eEVM/exception.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +//#define Debug + +namespace resdb { +namespace contract { +namespace x_manager { + +SeqCommitter:: SeqCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + int worker_num):gs_(global_state), + worker_num_(worker_num), + window_size_(window_size) { + + executor_ = std::make_unique(); +} + + +SeqCommitter::~SeqCommitter(){ + //LOG(ERROR)<<"desp"; + is_stop_ = true; +} + +void SeqCommitter::AsyncExecContract(std::vector& requests) { + return ; +} + +std::vector> SeqCommitter::ExecContract( + std::vector& requests) { + std::vector> resp_list; + for(auto& request: requests) { + auto ret = ExecContract(request.caller_address, + request.contract_address, + request.func_addr, + request.func_params, gs_); + std::unique_ptr resp = std::make_unique(); + resp->contract_address = request.contract_address; + resp->commit_id = request.commit_id; + resp->user_id = request.user_id; + resp->ret = 0; + resp->result = *ret; + resp_list.push_back(std::move(resp)); + } + return resp_list; +} + +absl::StatusOr SeqCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/seq_committer.h b/platform/consensus/ordering/fides/executor/x_manager/seq_committer.h new file mode 100644 index 000000000..5db60b3cf --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/seq_committer.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/contract_executor.h" +#include "service/contract/executor/x_manager/committer_context.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class SeqCommitter : public ContractCommitter { + public: + SeqCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + int worker_num = 2); + + ~SeqCommitter(); + + //void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info); + +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + + void CallBack(uint64_t commit_id); + + private: + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::unique_ptr executor_; + + std::vector> resp_list_; + + const int worker_num_; + int window_size_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/seq_controller.cpp b/platform/consensus/ordering/fides/executor/x_manager/seq_controller.cpp new file mode 100644 index 000000000..38d6b06e9 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/seq_controller.cpp @@ -0,0 +1,1758 @@ +#include "service/contract/executor/x_manager/x_controller.h" + +#include +#include +#include + +#include "eEVM/exception.h" + +#include "common/utils/utils.h" + +//#define CDebug +//#define DDebug + +namespace resdb { +namespace contract { +namespace x_manager { + +int GetHashKey(const uint256_t& address){ + + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%2048; + } + + +XController::XController(DataStorage * storage, int window_size) : + ConcurrencyController(storage), window_size_(window_size), storage_(storage){ + for(int i = 0; i < 32; i++){ + if((1<window_size_){ + window_size_ = (1< XController::GetChangeList(int64_t commit_id){ + // read lock + //return std::move(changes_list_[commit_id]); + return nullptr; +} + +void XController::Clear(int64_t commit_id){ +#ifdef CDebug + LOG(ERROR)<<"CLEAR id:"<& change_set, const Data& data){ + if(change_set.empty()){ + change_set.push_back(data); + } + else if(data.state != LOAD){ + if(change_set.back().state != LOAD){ + change_set.pop_back(); + } + change_set.push_back(data); + } + assert(change_set.size()<3); +} + +int XController::GetLastR(const uint256_t& address, int addr_idx){ + #ifdef CDebug + LOG(ERROR)<<"get last r, lp size:"<second; + if(lp.empty()){ + //LOG(ERROR)<<"no last:"<second; + if(lp.empty()){ + //LOG(ERROR)<<"no last:"< q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + if(x==to) { + //LOG(ERROR)<<"access from:"< XController::GetReach(int from){ + std::queue q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + for(int ch : child_[x]){ + if(v.find(ch) == v.end()){ + v.insert(ch); + q.push(ch); + } + } + } + //assert(reach_[to][from]==false); + return v; +} + +std::set XController::GetReach(int from, int to){ + std::queue q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + if(x==to) { + //LOG(ERROR)<<"access from:"< q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + LOG(ERROR)<<"reach from:"< new_f; + std::vector new_cf; + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + #ifdef CDebug + LOG(ERROR)<<"connect idx:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"< r = GetReach(last_idx); + for(int cf: new_cf){ + if(r.find(cf) != r.end()){ + // cycle + #ifdef CDebug + LOG(ERROR)<<"have cycle after change:"< new_f; + std::vector new_cf; + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + #ifdef CDebug + LOG(ERROR)<<"connect idx:"<second){ + if(f==0){ + int addr_idx_e = addr_idx&window_size_; + auto& mp = root_addr_[addr_idx_e][address]; + int sz = mp.size(); + //LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + #ifdef CDebug + LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(committed_[cf]){ + continue; + } + if(cf == last_idx){ + continue; + } + + //assert(cf != last_idx); + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"<second.erase(ait->second.find(f)); + } + pre_[idx].insert(last_idx); + child_[last_idx].insert(idx); + if(!new_cf.empty()){ + std::set r = GetReach(last_idx); + for(int cf: new_cf){ + if(r.find(cf) != r.end()){ + // cycle +#ifdef CDebug + LOG(ERROR)<<"have cycle after change:"<second.insert(cf); + addr_child_[cf][address].insert(last_idx); + addr_pre_[last_idx][address].insert(cf); + child_[cf].insert(last_idx); + pre_[last_idx].insert(cf); + } + } + + pre_[idx].insert(last_idx); + child_[last_idx].insert(idx); + #ifdef CDebug + LOG(ERROR)<<"connect :"<Load(address, false); + data.version = ret.second+1; + */ + data.version = 0; + Connect(commit_id, 0, address, addr_id, data.state!=STORE); + //assert(ret.second<=1); + } + else { + data.version = addr_changes_list_[last_r][addr_id].data.version+1; + bool ret = Connect(commit_id, last_r, address, addr_id, false); + if(!ret){ + LOG(ERROR)<<"connect commit:"<Load(address, false); + //LOG(ERROR)<<"load storage:"<Load(address, false); + // data.data = ret.first; + // data.version = ret.second; + bool ret = Connect(commit_id, 0, address, addr_id, data.state!=STORE); + assert(ret); + // assert(ret.second<=1); + } + else { + { + if(Reach(commit_id, last_w)){ + //assert(1==0); + //std::set rs = GetReach(commit_id, last_w); + // cycle? + #ifdef CDebug + // LOG(ERROR)<<"commit id:"<0){ + data.data = addr_changes_list_[last_w][addr_id].data.data; + data.version = addr_changes_list_[last_w][addr_id].data.version; + } + } + } + } + + //AddDataToChangeList(changes_list_[commit_id][address], data); + #ifdef CDebug + //LOG(ERROR)<<"add commit id:"< q; + q.push(commit_id); + + std::vector v(window_size_+1); + for(int i = 0; i <= window_size_; i++) v[i] = 0; + v[commit_id] = 1; + + while(!q.empty()){ + int x = q.front(); + q.pop(); + auto& cs = changes_list_[x][address]; + if(!cs.empty() && x != commit_id){ + if(cs.back().state == STORE){ + return x; + } + } + for(int f : addr_pre_[x][address]) { + if(v[f]==0){ + v[f] = 1; + q.push(f); + } + } + } + return -1; +} + +int XController::FindR(int64_t commit_id, const uint256_t& address, int addr_idx) { + + std::queue q; + q.push(commit_id); + + std::vector v(window_size_+1); + for(int i = 0; i <= window_size_; i++) v[i] = 0; + v[commit_id] = 1; + + while(!q.empty()){ + int x = q.front(); + q.pop(); + auto& cs = changes_list_[x][address]; + if(!cs.empty()){ + if(cs.front().state == LOAD){ + return x; + } + } + for(int f : pre_[x]) { + if(v[f]==0){ + v[f] = 1; + q.push(f); + } + } + } + return -1; +} + + +bool XController::AddOldNode(const uint256_t& address, int addr_idx, + int64_t commit_id, Data& data) { + + #ifdef CDebug + //LOG(ERROR)<<"add old node address:"<Load(address, false); + data.version = ret.second+1; + */ + data.version = 0; + Connect(commit_id, 0, address, addr_idx, data.state!=STORE); + //assert(ret.second==0); + } + else { + if(Reach(commit_id, last_r)){ + //LOG(ERROR)<<"commit id:"<Load(address, false); + data.data = ret.first; + data.version = ret.second; + } + bool ret = Connect(commit_id, 0, address, addr_idx, data.state!=STORE); + assert(ret); + //assert(ret.second==0); + } + else { + if(Reach(commit_id, last_w)){ + //assert(1==0); + //std::set rs = GetReach(commit_id, last_w); + // cycle? + #ifdef CDebug + // LOG(ERROR)<<"commit id:"<0){ + data.data = addr_changes_list_[last_w][addr_idx].data.data; + data.version = addr_changes_list_[last_w][addr_idx].data.version; + } + } + } + } + else { + if(data.state == STORE){ + if(change_set.back().state == LOAD){ + data.version = change_set.back().version+1; + } + else { + data.version = change_set.back().version; + } + } + else { + data.data = change_set.back().data; + data.version = change_set.back().version; + } + if(data.state == STORE){ + ConnectSelf(commit_id, commit_id, address, addr_idx); + if(aborted_[commit_id]){ + AbortNode(commit_id); + return false; + } + has_w = has_write_[commit_id]; + } + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + + if(lrp.find(commit_id) != lrp.end()){ + if(data.state == STORE){ + lwp.insert(commit_id); + } + } + else if( lwp.find(commit_id) != lwp.end()){ + if(data.state == LOAD){ + lrp.insert(commit_id); + } + } + } +#ifdef CDebug +LOG(ERROR)<<"has w:"<0 && data.state == STORE){ + AbortNodeFrom(commit_id, address); + } + } + +// AddDataToChangeList(change_set, data); + #ifdef CDebug + //LOG(ERROR)<<"add commit id:"<"; + PrintReach(i,j); + PrintReach(j,i); + assert(1==0); + } + } + } + #endif + /* + for(int i = 1; i < 500; ++i){ + for(auto it : addr_pre_[i]){ + auto address = it.first; + for(int c : it.second){ + if(c==0)continue; + if(addr_child_[c][address].find(i) == addr_child_[c][address].end()){ + LOG(ERROR)<<" id:"<GetVersion(it.first, false); + if(op.state == STORE){ + /* + if(op.version+1 != v){ + LOG(ERROR)<<"state:"<0){ + if(pre_[commit_id].size()==1 && *pre_[commit_id].begin() == 0){ + } + else { + #ifdef CDebug + for(int f : pre_[commit_id]){ + LOG(ERROR)<<" wait for pre:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + //LOG(ERROR)<<"load"; + break; + case STORE: + //LOG(ERROR)<<"commit:"<StoreWithVersion(it.first, op.data, op.version, false); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, false); + done = true; + break; + } + } + } + + //LOG(ERROR)<<" commit id done:"< &XController::GetRedo(){ + return redo_; +} +const std::vector &XController::GetDone(){ + return done_; +} + +uint64_t XController::GetDelay(int64_t commit_id) { + return commit_delay_[commit_id]; +} + +} +} +} + diff --git a/platform/consensus/ordering/fides/executor/x_manager/seq_controller.h b/platform/consensus/ordering/fides/executor/x_manager/seq_controller.h new file mode 100644 index 000000000..495e92f66 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/seq_controller.h @@ -0,0 +1,141 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/data_storage.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class XController : public ConcurrencyController { + public: + XController(DataStorage * storage, int window_size); + virtual ~XController(); + + // ============================== + virtual void Store(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + virtual uint256_t Load(const int64_t commit_id, const uint256_t& key, int version); + bool Remove(const int64_t commit_id, const uint256_t& key, int version); + + + // ============================== + typedef std::map > CommitList; + + const std::vector& GetDone(); + const std::vector &GetRedo(); + + void PushCommit(int64_t commit_id, const ModifyMap& local_changes_){} + bool Commit(int64_t commit_id); + + void StoreInternal(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + uint256_t LoadInternal(const int64_t commit_id, const uint256_t& key, int version); + + std::unique_ptr GetChangeList(int64_t commit_id); + + void Clear(); +void Clear(int64_t commit_id); + uint64_t GetDelay(int64_t commit_id); + + private: + + bool CommitUpdates(int64_t commit_id); + + bool CheckCommit(int64_t commit_id); + + void AppendPreRecord(const uint256_t& address, + int64_t commit_id, Data& data); + + int GetLastR(const uint256_t& address, int addr_id); + int GetLastW(const uint256_t& address, int addr_id); + int GetLastWOnly(const uint256_t& address, int addr_id); + int FindW(int64_t commit_id, const uint256_t& address, int addr_id); + int FindR(int64_t commit_id, const uint256_t& address, int addr_id); + + bool Connect(int idx, int last_idx, const uint256_t& address, int addr_idx, bool is_read); + void ConnectSelf(int idx, int last_idx, const uint256_t& address, int addr_idx); + bool AddNewNode(const uint256_t& address, int addr_idx, int64_t commit_id, Data& data); + bool AddOldNode(const uint256_t& address, int addr_idx, int64_t commit_id, Data& data); + void AddDataToChangeList(std::vector& change_set, const Data& data); + + void RecursiveAbort(int64_t idx, const uint256_t& address); + void AbortNodeFrom(int64_t idx, const uint256_t& address); + void AbortNode(int64_t idx); + bool ContainRead(int commit_id, const uint256_t &address); + + void RemoveNode(int64_t commit_id); + + void Abort(const int64_t commit_id); + bool Reach(int from, int to); + bool PrintReach(int from, int to); + std::set GetReach(int from, int to); + std::set GetReach(int from); + + int GetDep(int from, int to); + void AddRedo(int64_t commit_id); + + int AddressToId(const uint256_t& key); + uint256_t& GetAddress(int key); + + void ResetReach(int64_t commit_id); +void Update(const std::vector& commit_id) ; + private: + int window_size_ = 1000; + + struct DataInfo { + int64_t commit_id; + int type; + Data data; + int version; + DataInfo():type(0){} + DataInfo(int64_t commit_id, int type, Data&data) : commit_id(commit_id), type(type), data(data){} + }; + + //typedef std::map>> KeyMap; + std::vector changes_list_; + std::vector> addr_changes_list_; + //std::vector> changes_list_; + + std::set pd_; + std::vector redo_; + std::vector done_; + DataStorage* storage_; + std::vector wait_; + std::mutex mutex_[2048], abort_mutex_; + std::mutex g_mutex_, k_mutex_[2048]; + std::map > lock_[2048]; + bool aborted_[2048]; + bool is_redo_[2048]; + bool finish_[2048]; + bool committed_[2048]; + bool has_write_[2048]; + std::vector abort_list_; + std::set pre_[2048]; + std::set child_[2048]; + std::bitset<2048> reach_[2048]; + + std::map> addr_pre_[2048]; + std::map> addr_child_[2048]; + std::map> root_addr_[2048]; + std::unordered_map > lastr_, lastw_; + + std::unordered_map> check_; + std::set check_abort_; + std::vector post_abort_, pending_check_; + std::map key_[2048]; + std::unordered_map akey_; + std::atomic key_id_; + bool ds_ = false; + uint64_t commit_time_[2048], commit_delay_[2048]; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/streaming_e_committer.cpp b/platform/consensus/ordering/fides/executor/x_manager/streaming_e_committer.cpp new file mode 100644 index 000000000..f4a5d8d6f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/streaming_e_committer.cpp @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/streaming_e_committer.h" +#include "service/contract/executor/x_manager/executor_state.h" + +#include +#include + +#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +//#define DEBUG + +namespace resdb { +namespace contract { +namespace x_manager { + +namespace { +class TimeTrack { +public: + TimeTrack(std::string name = ""){ + name_ = name; + start_time_ = GetCurrentTime(); + } + + ~TimeTrack(){ + uint64_t end_time = GetCurrentTime(); + //LOG(ERROR) << name_ <<" run:" << (end_time - start_time_)<<"ms"; + } + + double GetRunTime(){ + uint64_t end_time = GetCurrentTime(); + return (end_time - start_time_) / 1000000.0; + } +private: + std::string name_; + uint64_t start_time_; +}; +} + +StreamingECommitter:: StreamingECommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back, + int worker_num):storage_(storage), gs_(global_state), + worker_num_(worker_num), + window_size_(window_size), + call_back_(call_back) { + + //LOG(ERROR)<<"init window:"<(storage, window_size*2); + executor_ = std::make_unique(); + +// LOG(ERROR)<<"init"; + resp_list_.resize(window_size_); + is_done_.resize(window_size_); + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + num_ = 0; + first_id_ = 0; + last_id_ = 1; + is_stop_ = false; + id_ = 1; + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request_ptr = request_queue_.Pop(); + if (request_ptr == nullptr) { + continue; + } + ExecutionContext * request = *request_ptr; + + TimeTrack track; + ExecutorState executor_state(controller_.get(), request->GetContractExecuteInfo()->commit_id); + executor_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id, + request->RedoTime()); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &executor_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + //LOG(ERROR)<<"========= get resp commit id:"<GetContractExecuteInfo()->commit_id<<" param:"<< request->GetContractExecuteInfo()->func_params.DebugString(); + //LOG(ERROR)<<"========= get resp commit id:"<GetContractExecuteInfo()->commit_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=request->RedoTime(); + } + //assert(resp->retry_time<=5); + resp->runtime = track.GetRunTime()*1000; + //LOG(ERROR)<<"run:"<runtime; + //local_state.Flesh(request->GetContractExecuteInfo()->contract_address, + // request->GetContractExecuteInfo()->commit_id); + } + else { + //LOG(ERROR)<<"commit :"<commit_id<<" fail"; + resp->ret = -1; + //assert(resp->ret>=0); + } + resp_queue_.Push(std::move(resp)); + } + })); + } + + response_ = std::thread([&]() { + while (!is_stop_) { + ResponseProcess(); + } + }); +} + +void StreamingECommitter::SetExecuteCallBack(std::function)> func) { + call_back_ = std::move(func); +} + +void StreamingECommitter::Clear(){ + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + num_ = 0; + first_id_ = 0; + last_id_ = 1; + id_ = 1; +} + +StreamingECommitter::~StreamingECommitter(){ + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } + if(response_.joinable()){ + response_.join(); + } +} + +void StreamingECommitter::SetController(std::unique_ptr controller) { + controller_ = std::move(controller); +} + +void StreamingECommitter::AddTask(int64_t commit_id, std::unique_ptr context){ + context_list_[commit_id%window_size_] = std::move(context); +} + +void StreamingECommitter::RemoveTask(int64_t commit_id){ + context_list_.erase(context_list_.find(commit_id)); +} + +ExecutionContext* StreamingECommitter::GetTaskContext(int64_t commit_id){ + return context_list_[commit_id%window_size_].get(); +} + +void StreamingECommitter::CallBack(uint64_t commit_id){ + int idx = commit_id%window_size_; + //LOG(ERROR)<<"call back:"< lk(mutex_); + cv_.notify_all(); + num_--; + } +} + +bool StreamingECommitter::WaitNext(){ + int c = 64; + while(!is_stop_) { + int timeout_ms = 10000; + std::unique_lock lk(mutex_); + cv_.wait_for(lk, std::chrono::microseconds(timeout_ms), [&] { + return num_ lk(mutex_); + cv_.wait_for(lk, std::chrono::microseconds(timeout_ms), [&] { + return first_id_>0&&first_id_%500==0; + //return id_ - first_id_commit_id; + int idx = resp->commit_id % window_size_; + +#ifdef DEBUG + LOG(ERROR)<<"recv :"<ret<<" last id:"<Commit(resp_commit_id); + std::vector next_commit = controller_->GetRedo(); + for(int64_t new_next : next_commit) { + auto context_ptr = GetTaskContext(new_next); + context_ptr->SetRedo(); +#ifdef DEBUG + LOG(ERROR)<<"redo :"<RedoTime(); +#endif + controller_->Clear(new_next); + request_queue_.Push(std::make_unique(context_ptr)); + } + + std::vector done_list = controller_->GetDone(); + for(int64_t done_id : done_list) { + //LOG(ERROR)<<"get doen id:"<& requests) { + Clear(); + controller_->Clear(); + + for(auto& request: requests) { + if(!WaitNext()){ + return; + } + num_++; + int cur_idx = id_%window_size_; + assert(id_>=last_id_); + + request.commit_id = id_++; + auto context = std::make_unique(request); + auto context_ptr = context.get(); + + //LOG(ERROR)<<"execute:"<Clear(request.commit_id); + request_queue_.Push(std::make_unique(context_ptr)); + } + + return ; +} + +absl::StatusOr StreamingECommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + //LOG(ERROR)<<"start:"<ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/streaming_e_committer.h b/platform/consensus/ordering/fides/executor/x_manager/streaming_e_committer.h new file mode 100644 index 000000000..ba6fd3158 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/streaming_e_committer.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/contract_executor.h" +#include "service/contract/executor/x_manager/committer_context.h" +#include "service/contract/executor/x_manager/streaming_e_controller.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class StreamingECommitter : public ContractCommitter { + public: + StreamingECommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + std::function)> call_back = nullptr, + int worker_num = 2); + + ~StreamingECommitter(); + + void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info) { return {}; } + + void SetController(std::unique_ptr controller); + +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + void Clear(); + + void CallBack(uint64_t commit_id); + + private: + std::unique_ptr controller_; + std::unique_ptr executor_; + DataStorage * storage_; + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::atomic first_id_, last_id_, id_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + std::vector> resp_list_; + std::vector is_done_; + + std::map> context_list_; + + const int worker_num_; + int window_size_; + std::function)> call_back_; + std::condition_variable cv_; + std::mutex mutex_; + std::atomic num_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/streaming_e_committer_test.cpp b/platform/consensus/ordering/fides/executor/x_manager/streaming_e_committer_test.cpp new file mode 100644 index 000000000..3bb7f26df --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/streaming_e_committer_test.cpp @@ -0,0 +1,843 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/streaming_e_committer.h" + +#include + +#include "service/contract/executor/x_manager/mock_d_storage.h" +#include "service/contract/executor/x_manager/mock_e_controller.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/contract_deployer.h" +#include "service/contract/executor/x_manager/address_manager.h" +#include "service/contract/proto/func_params.pb.h" + +#include +#include + + +namespace resdb { +namespace contract { +namespace x_manager { +namespace { + +using ::testing::Test; +using ::testing::Invoke; + +const std::string test_dir = "/home/ubuntu/nexres//service/contract/executor/manager/"; +//const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + + // std::string(getenv("TEST_WORKSPACE")) + + // "/service/contract/executor/manager/"; + +Address get_random_address() { return AddressManager().CreateRandomAddress(); } + +std::string U256ToString(uint256_t v) { return eevm::to_hex_string(v); } +uint256_t HexToInt(const std::string& v) { return eevm::to_uint256(v); } + +class StreamingECommitterTest : public Test { + public: + StreamingECommitterTest() : owner_address_(get_random_address()) { + std::string contract_path = test_dir + "test_data/kv.json"; + + std::ifstream contract_fstream(contract_path); + if (!contract_fstream) { + throw std::runtime_error(fmt::format( + "Unable to open contract definition file {}", contract_path)); + } + + const auto contracts_definition = nlohmann::json::parse(contract_fstream); + const auto all_contracts = contracts_definition["contracts"]; + const auto contract_code = all_contracts["kv.sol:KV"]; + storage_ = std::make_unique(); + contract_json_ = contract_code; + + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + auto ret = data_[address]; + //LOG(ERROR)<<"load:"<(storage_.get()); + + auto controller = std::make_unique(storage_.get(), 10); + controller_ = controller.get(); + + EXPECT_CALL(*controller_, Load).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& address, int version) { + return controller_->LoadInternal(commit_id, address, version); + })); + + EXPECT_CALL(*controller_, Store).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version) { + return controller_->StoreInternal(commit_id, key, value, version); + })); + + + committer_ = std::make_unique(storage_.get(), gs_.get(), 10); + committer_->SetController(std::move(controller)); + + contract_address_ = AddressManager::CreateContractAddress(owner_address_); + deployer_ = std::make_unique(committer_.get(), gs_.get()); + contract_address_ = deployer_->DeployContract(owner_address_, contract_json_, {1000}); + } + + void ExecContract(std::vector& execute_info) { + for(int i = 0; i < execute_info.size();++i){ + std::string func_addr = + deployer_->GetFuncAddress(execute_info[i].contract_address, execute_info[i].func_params.func_name()); + if (func_addr.empty()) { + LOG(ERROR) << "no fouction:" << execute_info[i].func_params.func_name(); + execute_info[i].contract_address = 0; + continue; + } + execute_info[i].func_addr = func_addr; + execute_info[i].commit_id = i+1; + } + committer_->AsyncExecContract(execute_info); + } + + protected: + Address owner_address_; + Address contract_address_; + nlohmann::json contract_json_; + std::unique_ptr storage_; + std::unique_ptr gs_; + std::unique_ptrcommitter_; + MockEController* controller_; + std::map> data_;//, g_data_; + std::unique_ptr deployer_; +}; + +TEST_F(StreamingECommitterTest, ExecContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + { + Params func_params; + func_params.set_func_name("get(address)"); + func_params.add_param(U256ToString(owner_address_)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done.set_value(true); + }); + + { + ExecContract(info); + } + done_future.get(); + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + //LOG(ERROR)<<"owner key:"< done; + std::future done_future = done.get_future(); + std::vector info; + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + assert(resp != nullptr); + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==2){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + EXPECT_EQ(data_[owner_key].first, 800); + EXPECT_EQ(data_[recer].first, 100); + EXPECT_EQ(data_[recer2].first, 100); + LOG(ERROR)<<"===== done"; +} + +TEST_F(StreamingECommitterTest, ExecConflictContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + std::set ids; + EXPECT_CALL(*controller_, Load).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& address, int version) { + if(commit_id==1){ + while(ids.find(2) == ids.end()){ + sleep(1); + } + } + ids.insert(commit_id); + return controller_->LoadInternal(commit_id, address, version); + })); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==2){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + EXPECT_EQ(data_[owner_key].first, 800); + EXPECT_EQ(data_[recer].first, 100); + EXPECT_EQ(data_[recer2].first, 100); + +} + +TEST_F(StreamingECommitterTest, ExecConflictContractAhead2) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + std::map ids; + EXPECT_CALL(*controller_, Load).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& address, int version) { + if(commit_id==1){ + while(ids.find(2) == ids.end()){ + sleep(1); + } + } + LOG(ERROR)<<"======== load :"<LoadInternal(commit_id, address, version); + })); + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(100)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("get(address)"); + func_params.add_param(U256ToString(transfer_receiver3)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); + EXPECT_EQ(ids[2], 1); + EXPECT_EQ(ids[1], 0); + EXPECT_EQ(ids[3], 0); + + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + EXPECT_EQ(data_[owner_key].first, 800); + EXPECT_EQ(data_[recer].first, 100); + EXPECT_EQ(data_[recer2].first, 100); + +} + +TEST_F(StreamingECommitterTest, ExecConflictContractAhead) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + std::map ids; + EXPECT_CALL(*controller_, Load).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& address, int version) { + if(commit_id==1){ + while(ids.find(2) == ids.end()){ + sleep(1); + } + } + LOG(ERROR)<<"======== load :"<LoadInternal(commit_id, address, version); + })); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver3)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + uint256_t recer3 = AddressManager::AddressToSHAKey(transfer_receiver3); + EXPECT_EQ(data_[owner_key].first, 400); + EXPECT_EQ(data_[recer].first, 300); + EXPECT_EQ(data_[recer2].first, 300); + EXPECT_EQ(data_[recer3].first, 500); +} + +TEST_F(StreamingECommitterTest, ExecConflictPreCommitContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + std::map ids; + EXPECT_CALL(*controller_, Load).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& address, int version) { + if(commit_id==1){ + while(ids.find(2) == ids.end()){ + sleep(1); + } + } + LOG(ERROR)<<"======== load :"<LoadInternal(commit_id, address, version); + })); + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + uint256_t recer3 = AddressManager::AddressToSHAKey(transfer_receiver3); + EXPECT_EQ(data_[owner_key].first, 400); + EXPECT_EQ(data_[recer].first, 300); + EXPECT_EQ(data_[recer2].first, 800); +} + + +TEST_F(StreamingECommitterTest, ExecConflictPreCommitContract2) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + if(is_local){ + load_time[address]++; + } + auto ret = data_[address]; + LOG(ERROR)<<"load add:"<1){ + done = true; + break; + } + } + } + } + + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + return 1; + })); + + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + start = true; + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + uint256_t recer3 = AddressManager::AddressToSHAKey(transfer_receiver3); + EXPECT_EQ(data_[owner_key].first, 900); + EXPECT_EQ(data_[recer].first, 300); + EXPECT_EQ(data_[recer2].first, 300); +} + +TEST_F(StreamingECommitterTest, ExecConflictCommitContract) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + + bool start = false; + std::map load_time; + EXPECT_CALL(*storage_, Load).WillRepeatedly(Invoke([&](const uint256_t& address, bool is_local) { + if(is_local){ + load_time[address]++; + } + auto ret = data_[address]; + LOG(ERROR)<<"load add:"<1){ + done = true; + break; + } + } + } + } + + int v = data_[key].second; + data_[key] = std::make_pair(value, v+1); + return 1; + })); + + EXPECT_CALL(*storage_, Reset).WillRepeatedly(Invoke([&](const uint256_t& key, const uint256_t& value, int64_t version, bool is_local) { + LOG(ERROR)<<"reset key:"< done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==3){ + done.set_value(true); + } + }); + + start = true; + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + uint256_t recer3 = AddressManager::AddressToSHAKey(transfer_receiver3); + EXPECT_EQ(data_[owner_key].first, 400); + EXPECT_EQ(data_[recer].first, 500); + EXPECT_EQ(data_[recer2].first, 300); + +} + +// rollback two columns +TEST_F(StreamingECommitterTest, ExecConflictCommitContract2) { + // owner 1000 + std::promise done; + std::future done_future = done.get_future(); + std::vector info; + + std::set pre_ids; + controller_->SetPrecommitCallback([&](int64_t id){ + LOG(ERROR)<<"precommit done:"< ids; + EXPECT_CALL(*controller_, Load).WillRepeatedly(Invoke([&]( + const int64_t commit_id, const uint256_t& address, int version) { + if(commit_id==2 && version>0){ + while(pre_ids.size()<3){ + LOG(ERROR)<<"======== load :"<LoadInternal(commit_id, address, version); + })); + + Address transfer_receiver = get_random_address(); + Address transfer_receiver2 = get_random_address(); + Address transfer_receiver3 = get_random_address(); + Address transfer_receiver4 = get_random_address(); + + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transferif(address,address,address,uint256)"); + func_params.add_param(U256ToString(owner_address_)); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver2)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("transfer(address,address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(transfer_receiver3)); + func_params.add_param(U256ToString(300)); + + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver3)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + { + Params func_params; + func_params.set_func_name("set(address,uint256)"); + func_params.add_param(U256ToString(transfer_receiver)); + func_params.add_param(U256ToString(500)); + info.push_back(ContractExecuteInfo(owner_address_, contract_address_, "", func_params, 0)); + } + + std::set done_list; + committer_->SetExecuteCallBack([&](std::unique_ptr resp){ + LOG(ERROR)<<"!!!!! get resp:"<commit_id; + done_list.insert(resp->commit_id); + if(done_list.size()==6){ + done.set_value(true); + } + }); + + { + ExecContract(info); + } + done_future.get(); + + uint256_t owner_key = AddressManager::AddressToSHAKey(owner_address_); + uint256_t recer = AddressManager::AddressToSHAKey(transfer_receiver); + uint256_t recer2 = AddressManager::AddressToSHAKey(transfer_receiver2); + uint256_t recer3 = AddressManager::AddressToSHAKey(transfer_receiver3); + LOG(ERROR)<<"recr:"< +#include +#include + +#include "eEVM/exception.h" +#include "common/utils/utils.h" + +//#define CDebug + +namespace resdb { +namespace contract { +namespace x_manager { + +namespace { + + int GetHashKey(const uint256_t& address){ + // Get big-endian form + uint8_t arr[32] = {}; + memset(arr,0,sizeof(arr)); + intx::be::store(arr, address); + uint32_t v = 0; + for(int i = 0; i < 32; ++i){ + v += arr[i]; + } + + /* + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + */ + return v%1; + } +} + +StreamingEController::StreamingEController(DataStorage * storage, int window_size) : + ConcurrencyController(storage), window_size_(window_size), storage_(static_cast(storage)){ + for(int i = 0; i < 32; i++){ + if((1<window_size_){ + window_size_ = (1< precommit_callback) { + precommit_callback_ = std::move(precommit_callback); +} + +void StreamingEController::Clear(){ + last_commit_id_=1; + current_commit_id_=1; + last_pre_commit_id_=0; + + assert(window_size_+1<=4096); + //is_redo_.resize(window_size_+1); + //is_done_.resize(window_size_+1); + changes_list_.resize(window_size_+1); + rechanges_list_.resize(window_size_+1); + + for(int i = 0; i < window_size_; ++i){ + changes_list_[i].clear(); + rechanges_list_[i].clear(); + is_redo_[i] = 0; + is_invalid_[i] = 0; + commit_[i] = 0; + version_[i] = 0; + is_start_[i] = true; + //is_done_[i] = false; + } + + for(int i = 0; i < 4096; ++i){ + commit_list_[i].clear(); + } + pre_commit_list_.clear(); +} + +void StreamingEController::GenRedo(){ + //std::unique_lock lock(mutex_[commit_id&window_size_]); + + return; +} + +std::vector& StreamingEController::GetRedo(){ + //std::unique_lock lock(mutex_[commit_id&window_size_]); + return redo_; +} + +std::vector& StreamingEController::GetDone(){ + return done_; +} + +class TimeTrack { +public: + TimeTrack(std::string name = ""){ + name_ = name; + start_time_ = GetCurrentTime(); + } + + ~TimeTrack(){ + uint64_t end_time = GetCurrentTime(); + LOG(ERROR) << name_ <<" run:" << (end_time - start_time_)<<"ms"; + } + + double GetRunTime(){ + uint64_t end_time = GetCurrentTime(); + return (end_time - start_time_) / 1000000.0; + } +private: + std::string name_; + uint64_t start_time_; +}; + + +// ======================================================== +void StreamingEController::StoreInternal(const int64_t commit_id, const uint256_t& address, const uint256_t& value, int version) { + { + std::unique_lock lock(valid_mutex_[commit_id&window_size_]); + if(is_invalid_[commit_id&window_size_]){ + //LOG(ERROR)<<"aborted:"< lk(abort_mutex_); + abort_list_.push_back(commit_id); +} + +std::vector StreamingEController::FetchAbort(){ + std::vector p; + { + std::lock_guard lk(abort_mutex_); + p = abort_list_; + abort_list_.clear(); + } + return p; +} + + +void StreamingEController::AppendPreRecord(const uint256_t& address, + int64_t commit_id, Data& data, int version) { + + data.commit_version = version; +#ifdef CDebug + LOG(ERROR)<<"append record addr:"< lk(mutex_[hash_idx]); + std::unique_lock lock(g_mutex_); + //std::unique_lock lock(mutex_[hash_idx]); + if(is_invalid_[commit_id]){ + #ifdef CDebug + LOG(ERROR)<<"append commit id:"<> tmp; + while(!commit_set.empty()){ + if(commit_set.back()->commit_id > commit_id){ + //LOG(ERROR)<<"push :"<commit_id; + tmp.push(std::move(commit_set.back())); + commit_set.pop_back(); + } + else { + break; + } + } + + if(data.state == LOAD){ + if(commit_set.empty()){ + auto ret = storage_->Load(address, false); + data.data = ret.first; + data.version = ret.second; + //LOG(ERROR)<<"LOAD from db:"<<" version:"<data.data; + data.version = commit_set.back()->data.version; + //LOG(ERROR)<<"LOAD from :"<second->commit_id<<" version:"<< it->second->data.version; + } + } + else { + if(commit_set.empty()){ + auto ret = storage_->Load(address, false); + data.version = ret.second+1; + //LOG(ERROR)<<"LOAD from db:"; + } + else { + data.version = commit_set.back()->data.version+1; + //LOG(ERROR)<<"LOAD from :"<second->commit_id<<" version:"<second->data.version; + } + } + + int type = 1; + if(data.state == LOAD){ + type = 1; + } + else { + type = 2; + } + + if(!commit_set.empty()){ + if( commit_set.back()->commit_id == commit_id){ + commit_set.back()->type |= type; + commit_set.back()->data = data; + } + else { + commit_set.push_back(std::make_unique(commit_id, type, data)); + } + //LOG(ERROR)<<"back type:"<type; + } + else { + commit_set.push_back(std::make_unique(commit_id, type, data)); + } + + while(!tmp.empty()){ + int ok = 1; + if(data.state == STORE){ + if(tmp.top()->type & 1){ +#ifdef CDebug + LOG(ERROR)<<"abbort:"<commit_id<<" from:"<commit_id); + } + } + if(ok){ + commit_set.push_back(std::move(tmp.top())); + } + tmp.pop(); + } + } + + int idx = commit_id&window_size_; + //std::unique_lock lock(change_list_mutex_[idx]); + auto& change_set = changes_list_[idx][address]; + if(change_set.empty()){ + change_set.push_back(data); + } + else if(data.state != LOAD && !change_set.empty()){ + if(change_set.back().state != LOAD){ + change_set.pop_back(); + } + change_set.push_back(data); + } + assert(change_set.size()<3); + rechanges_list_[idx].insert(address); + //LOG(ERROR)<<"append record addr:"<> tmp; + while(!commit_set.empty()){ + auto& it = commit_set.back(); + if(it->commit_id != commit_id){ + //LOG(ERROR)<<"push queue:"<commit_id<<" address:"<commit_id == commit_id){ + type = it->type; + //LOG(ERROR)<<"remove old data:"<type&1){ + tmp.top()->version=-1; + #ifdef CDebug + LOG(ERROR)<<"abort :"<commit_id<<" from release:"<commit_id); + } + else if((tmp.top()->type&2)){ + flag = false; + } + } + if(ok){ + commit_set.push_back(std::move(tmp.top())); + } + tmp.pop(); + } + //LOG(ERROR)<<"add size:"<commit_id != commit_id){ + LOG(ERROR)<<"not the head:"<commit_id<<" address:"<commit_id == commit_id); + commit_set.pop_front(); + /* + if(!commit_set.empty()){ + LOG(ERROR)<<"after commit:"<commit_id<<" commit id:"<commit_id != commit_id); + } + else { + LOG(ERROR)<<"after commit empty. commit id:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<StoreWithVersion(it.first, op.data, op.version, false); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, false); + done = true; + break; + } + } + } + commit_[commit_id&window_size_]=true; + } + + CommitDone(commit_id); + last_commit_id_++; + + return true; +} + + +// ================= post commit ======================= + +void StreamingEController::CommitDone(int64_t commit_id) { +#ifdef CDebug + LOG(ERROR)<<"commit done:"<GetVersion(it.first, false); + if(op.state == STORE){ + if(op.version != v+1){ + LOG(ERROR)<<"state:"< +#include +#include +#include + +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/d_storage.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class StreamingEController : public ConcurrencyController { + public: + StreamingEController(DataStorage * storage, int window_size); + virtual ~StreamingEController(); + + // ============================== + virtual void Store(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + virtual uint256_t Load(const int64_t commit_id, const uint256_t& key, int version); + bool Remove(const int64_t commit_id, const uint256_t& key, int version); + + + // ============================== + typedef std::map > CommitList; + + struct DataInfo { + int64_t commit_id; + int type; + Data data; + int version; + DataInfo(){} + DataInfo(int64_t commit_id, int type, Data&data) : commit_id(commit_id), type(type), data(data){} + }; + typedef std::map> > PreCommitList; + //typedef std::map> > PreCommitList; + + void GenRedo(); + std::vector& GetRedo(); + std::vector& GetDone(); + + void PushCommit(int64_t commit_id, const ModifyMap& local_changes_){} + bool Commit(int64_t commit_id); + + void StoreInternal(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + uint256_t LoadInternal(const int64_t commit_id, const uint256_t& key, int version); + void SetPrecommitCallback( std::function precommit_callback); + + void Release(int64_t commit_id); + void Clear(int64_t commit_id); + bool ExecuteDone(int64_t commit_id); + bool CheckCommit(int64_t commit_id); + + bool CheckRedo(int64_t commit_id); + void Clear(); + + private: + + void Abort(int64_t commit_id); + int64_t Release(int64_t commit_id, const uint256_t& address, bool need_abort); + + //void ReleaseCommit(int64_t commit_id); + void ReleaseCommit(int64_t commit_id, const uint256_t& address); + + + bool PreCommit(int64_t commit_id); + bool PostCommit(int64_t commit_id); + + void RedoConflict(int64_t commit_id); + bool CheckPreCommit(int64_t commit_id); + bool CheckFirstFromPreCommit(const uint256_t& address, int64_t commit_id); + bool CheckFirstFromCommit(const uint256_t& address, int64_t commit_id); + + void Remove(int64_t commit_id); + void CleanOldData(int64_t commit_id); + + void Rollback(int64_t id, const uint256_t& address); + void Rollback(); + + int64_t RemovePrecommitRecord(const uint256_t& address, int64_t commit_id); + void RemovePreRecord(const uint256_t& address, + int64_t commit_id); + + bool CheckCommit(int64_t commit_id, bool is_pre); + void CommitDone(int64_t commit_id); + void RedoCommit(int64_t commit_id, int flag); + std::set RollCommit(int64_t commit_id); + std::set AbortCommit(int64_t commit_id, const uint256_t& address); + + void RollBackData(const uint256_t& address, const Data& data); + + void AppendRecord(const uint256_t& address, int64_t commit_id); + + void AppendPreRecord(const uint256_t& address, + int64_t commit_id, Data& data, int version); + void AppendPreRecord(const uint256_t& address, int hash_idx, + const std::vector& commit_id); + + void ClearOldData(const int64_t commit_id); + void AddRedo(int64_t commit_id); +std::vector FetchAbort(); + + private: + int window_size_ = 1000; + + std::vector changes_list_; + std::vector>rechanges_list_; + + CommitList commit_list_[4096]; + int64_t last_commit_id_, current_commit_id_; + bool commit_[4096]; + + PreCommitList pre_commit_list_ GUARDED_BY(mutex_); + int64_t last_pre_commit_id_; + + std::atomic is_redo_[4096]; + + std::vector redo_; + + //std::atomic is_done_[1024]; + std::vector done_; + + D_Storage * storage_; + std::mutex mutex_[4096], change_list_mutex_[4096], valid_mutex_[4096], rb_mutex_, g_mutex_, abort_mutex_; + //mutable std::shared_mutex mutex_[4096], change_list_mutex_[4096], valid_mutex_[4096], rb_mutex_; + + bool is_invalid_[4096], is_start_[4096], wait_[4096]; + int version_[4096]; + std::function precommit_callback_; + std::set forward_[4096], back_[4096]; + + typedef std::set RedoList; + RedoList redo_list_ GUARDED_BY(mutex_); + void CheckRedo(); + + std::vector abort_list_; + std::set pd_; + std::setredo_p_; + std::map> num_; + std::map ref_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/test_committer.cpp b/platform/consensus/ordering/fides/executor/x_manager/test_committer.cpp new file mode 100644 index 000000000..e69912d0b --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/test_committer.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/manager/test_committer.h" + +#include "glog/logging.h" +//#include "eEVM/processor.h" + +namespace resdb { +namespace contract { + +TestCommitter:: TestCommitter( + DataStorage* storage, + GlobalState * global_state):gs_(global_state) { + + controller_ = std::make_unique(storage); + executor_ = std::make_unique(); +} + +TestCommitter::~TestCommitter(){ +} + +std::vector> TestCommitter::ExecContract( + const std::vector& requests) { + + std::vector > resp_list; + for(const auto& request: requests){ + std::unique_ptr resp = std::make_unique(); + //auto start_time = GetCurrentTime(); + auto ret = ExecContract(request.caller_address, request.contract_address, + request.func_addr, + request.func_params, gs_); + resp->state = ret.status(); + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + } + else { + LOG(ERROR)<<"exec fail"; + resp->ret = -1; + } + resp->contract_address = request.contract_address; + resp->commit_id = request.commit_id; + + resp_list.push_back(std::move(resp)); + } + return resp_list; +} + +absl::StatusOr TestCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + return executor_->ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/test_committer.h b/platform/consensus/ordering/fides/executor/x_manager/test_committer.h new file mode 100644 index 000000000..0d98bafba --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/test_committer.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include + +#include "service/contract/executor/manager/global_state.h" +#include "service/contract/executor/manager/contract_executor.h" +#include "service/contract/executor/manager/contract_committer.h" +#include "service/contract/executor/manager/test_controller.h" +#include "service/contract/proto/func_params.pb.h" + +#include "absl/status/statusor.h" + +namespace resdb { +namespace contract { + +class TestCommitter : public ContractCommitter { + public: + TestCommitter( + DataStorage* storage, + GlobalState * global_state); + + virtual ~TestCommitter(); + + std::vector> ExecContract(const std::vector& request); + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + private: + std::unique_ptr controller_; + GlobalState* gs_; + std::unique_ptr executor_; +}; + +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/test_controller.cpp b/platform/consensus/ordering/fides/executor/x_manager/test_controller.cpp new file mode 100644 index 000000000..97edd57ed --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/test_controller.cpp @@ -0,0 +1,35 @@ +#include "service/contract/executor/manager/test_controller.h" + +#include + +namespace resdb { +namespace contract { + +TestController::TestController(DataStorage * storage) : ConcurrencyController(storage){} + +void TestController::PushCommit(int64_t commit_id, const ModifyMap& local_changes) { + for(auto it : local_changes){ + bool done = false; + for(int i = it.second.size()-1; i >=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<Store(it.first, op.data); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first); + done = true; + break; + } + } + } + return ; +} + +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/test_controller.h b/platform/consensus/ordering/fides/executor/x_manager/test_controller.h new file mode 100644 index 000000000..a4371033a --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/test_controller.h @@ -0,0 +1,19 @@ +#pragma once + +#include "service/contract/executor/manager/concurrency_controller.h" + +#include +#include + +namespace resdb { +namespace contract { + +class TestController : public ConcurrencyController { + public: + TestController(DataStorage * storage); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_); +}; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/test_data/BUILD b/platform/consensus/ordering/fides/executor/x_manager/test_data/BUILD new file mode 100644 index 000000000..6f9052157 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/test_data/BUILD @@ -0,0 +1 @@ +exports_files(["contract.json", "kv.json"]) diff --git a/platform/consensus/ordering/fides/executor/x_manager/test_data/compile.sh b/platform/consensus/ordering/fides/executor/x_manager/test_data/compile.sh new file mode 100644 index 000000000..dfd25e66f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/test_data/compile.sh @@ -0,0 +1,5 @@ +# sudo add-apt-repository ppa:ethereum/ethereum +# sudo apt-get update +# sudo apt-get install solc +solc --evm-version homestead --combined-json bin,hashes --pretty-json --optimize kv.sol > kv.json + diff --git a/platform/consensus/ordering/fides/executor/x_manager/test_data/contract.json b/platform/consensus/ordering/fides/executor/x_manager/test_data/contract.json new file mode 100644 index 000000000..e9c0d972f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/test_data/contract.json @@ -0,0 +1,19 @@ +{ + "contracts": + { + "ERC20.sol:ERC20Token": + { + "bin": "608060405234801561001057600080fd5b506040516104423803806104428339818101604052602081101561003357600080fd5b50516000818155338152600160205260409020556103ec806100566000396000f3fe608060405234801561001057600080fd5b506004361061007e577c01000000000000000000000000000000000000000000000000000000006000350463095ea7b3811461008357806318160ddd146100c357806323b872dd146100dd57806370a0823114610113578063a9059cbb14610139578063dd62ed3e14610165575b600080fd5b6100af6004803603604081101561009957600080fd5b50600160a060020a038135169060200135610193565b604080519115158252519081900360200190f35b6100cb6101fa565b60408051918252519081900360200190f35b6100af600480360360608110156100f357600080fd5b50600160a060020a03813581169160208101359091169060400135610200565b6100cb6004803603602081101561012957600080fd5b5035600160a060020a03166102e6565b6100af6004803603604081101561014f57600080fd5b50600160a060020a038135169060200135610301565b6100cb6004803603604081101561017b57600080fd5b50600160a060020a038135811691602001351661038c565b336000818152600260209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b60005490565b600160a060020a038316600090815260016020526040812054821180159061024b5750600160a060020a03841660009081526002602090815260408083203384529091529020548211155b156102db57600160a060020a038085166000818152600160209081526040808320805488900390559387168083528483208054880190559282526002815283822033808452908252918490208054879003905583518681529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35060016102df565b5060005b9392505050565b600160a060020a031660009081526001602052604090205490565b3360009081526001602052604081205482116103845733600081815260016020908152604080832080548790039055600160a060020a03871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35060016101f4565b5060006101f4565b600160a060020a0391821660009081526002602090815260408083209390941682529190915220549056fea265627a7a72315820e4ae92c4517e475d9f77ac0bfcd10463a09239f34734fc0ab4d7966450fb428464736f6c63430005100032", + "hashes": + { + "allowance(address,address)": "dd62ed3e", + "approve(address,uint256)": "095ea7b3", + "balanceOf(address)": "70a08231", + "totalSupply()": "18160ddd", + "transfer(address,uint256)": "a9059cbb", + "transferFrom(address,address,uint256)": "23b872dd" + } + } + }, + "version": "0.5.16+commit.9c3226ce.Linux.g++" +} diff --git a/platform/consensus/ordering/fides/executor/x_manager/test_data/kv.json b/platform/consensus/ordering/fides/executor/x_manager/test_data/kv.json new file mode 100644 index 000000000..87891db72 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/test_data/kv.json @@ -0,0 +1,18 @@ +{ + "contracts": + { + "kv.sol:KV": + { + "bin": "608060405234801561001057600080fd5b5060405161052338038061052383398101604081905261002f91610044565b3360009081526020819052604090205561005d565b60006020828403121561005657600080fd5b5051919050565b6104b78061006c6000396000f3fe608060405234801561001057600080fd5b5060043610610073577c01000000000000000000000000000000000000000000000000000000006000350463239b83eb81146100785780633825d828146100a0578063beabacc8146100b3578063c2bc2efc146100c6578063cfc9c3f9146100fd575b600080fd5b61008b610086366004610359565b610110565b60405190151581526020015b60405180910390f35b61008b6100ae3660046103a4565b6101d6565b61008b6100c13660046103ce565b61021e565b6100ef6100d436600461040a565b600160a060020a031660009081526020819052604090205490565b604051908152602001610097565b61008b61010b3660046103ce565b6102a3565b600160a060020a0384166000908152602081905260408120548281111561015f57600160a060020a0386166000908152602081905260408120805485929061015990849061045b565b90915550505b61032081101561019c57600160a060020a0385166000908152602081905260408120805485929061019190849061046e565b909155506101ca9050565b600160a060020a038416600090815260208190526040812080548592906101c490849061046e565b90915550505b50600195945050505050565b600160a060020a0382166000908152602081905260408120546101f9818461046e565b600160a060020a03851660009081526020819052604090205550600190505b92915050565b600160a060020a03831660009081526020819052604081205482101561026c57600160a060020a0384166000908152602081905260408120805484929061026690849061045b565b90915550505b600160a060020a0383166000908152602081905260408120805484929061029490849061046e565b90915550600195945050505050565b3360009081526020819052604081208054908390836102c2838561045b565b909155505061032081101561030457600160a060020a038516600090815260208190526040812080548592906102f990849061046e565b909155506103329050565b600160a060020a0384166000908152602081905260408120805485929061032c90849061046e565b90915550505b506001949350505050565b8035600160a060020a038116811461035457600080fd5b919050565b6000806000806080858703121561036f57600080fd5b6103788561033d565b93506103866020860161033d565b92506103946040860161033d565b9396929550929360600135925050565b600080604083850312156103b757600080fd5b6103c08361033d565b946020939093013593505050565b6000806000606084860312156103e357600080fd5b6103ec8461033d565b92506103fa6020850161033d565b9150604084013590509250925092565b60006020828403121561041c57600080fd5b6104258261033d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156102185761021861042c565b808201808211156102185761021861042c56fea2646970667358221220cfe0598bf227525b3a229778738f57a355eb5f0f171527891e3413c58bbffbd964736f6c63430008130033", + "hashes": + { + "get(address)": "c2bc2efc", + "set(address,uint256)": "3825d828", + "transfer(address,address,uint256)": "beabacc8", + "transferif(address,address,address,uint256)": "239b83eb", + "transferto(address,address,uint256)": "cfc9c3f9" + } + } + }, + "version": "0.8.19+commit.7dd6d404.Linux.g++" +} diff --git a/platform/consensus/ordering/fides/executor/x_manager/test_data/kv.sol b/platform/consensus/ordering/fides/executor/x_manager/test_data/kv.sol new file mode 100644 index 000000000..f5bfed426 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/test_data/kv.sol @@ -0,0 +1,59 @@ +pragma solidity >= 0.5.0; + +// Transfer tokens from the contract owner +contract KV { + mapping (address => uint256) balances; + mapping (address => uint256) allow; + + constructor(uint256 s) public { + balances[msg.sender] = s; + } + + // Get the account balance of another account with address _owner + function get(address _owner) public view returns (uint256) { + return balances[_owner]; + } + + // Send _value amount of tokens to address _to + function set(address _to, uint256 _value) public returns (bool) { + uint256 values = balances[_to]; + balances[_to] = _value + values; + return true; + } + + // Send _value amount of tokens to address _to + function transfer(address _from, address _to, uint256 _value) public returns (bool) { + if (balances[_from] > _value) { + balances[_from] -= _value; + } + balances[_to] += _value; + return true; + } + + function transferif(address _from, address _to1, address _to2, uint256 _value) public returns (bool) { + uint256 value = balances[_from]; + + if (balances[_from] > _value) { + balances[_from] -= _value; + } + if (value < 800 ) { + balances[_to1] += _value; + } else { + balances[_to2] += _value; + } + return true; + } + + function transferto(address _to1, address _to2, uint256 _value) public returns (bool) { + uint256 value = balances[msg.sender]; + balances[msg.sender] -= _value; + if (value < 800 ) { + balances[_to1] += _value; + } else { + balances[_to2] += _value; + } + return true; + } + +} + diff --git a/platform/consensus/ordering/fides/executor/x_manager/utils.h b/platform/consensus/ordering/fides/executor/x_manager/utils.h new file mode 100644 index 000000000..2d243d66f --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/utils.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "eEVM/address.h" + +namespace resdb { +namespace contract { + +typedef eevm::Address Address; + +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/v_controller.cpp b/platform/consensus/ordering/fides/executor/x_manager/v_controller.cpp new file mode 100644 index 000000000..d5a363c32 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/v_controller.cpp @@ -0,0 +1,87 @@ +#include "service/contract/executor/x_manager/v_controller.h" + +#include + +namespace resdb { +namespace contract { +namespace x_manager { + +VController::VController(DataStorage * storage) : ConcurrencyController(storage){ + + changes_list_.resize(window_size_); + for(int i = 0; i < window_size_; ++i){ + changes_list_[i].clear(); + } +} + +VController::~VController(){} + +const ConcurrencyController::ModifyMap * VController::GetChangeList(int64_t commit_id) const { + return &changes_list_[commit_id]; +} + +void VController::PushCommit(int64_t commit_id, const ModifyMap& local_changes) { + changes_list_[commit_id] = local_changes; +} + +bool VController::CheckCommit(int64_t commit_id) { + const auto& change_set = changes_list_[commit_id]; + if(change_set.empty()){ + LOG(ERROR)<<" no commit id record found:"<GetVersion(address); + //LOG(ERROR)<<"get version:"< new_commit_ids; + for(const auto& it : change_set){ + bool done = false; + for(int i = it.second.size()-1; i >=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + break; + case STORE: + //LOG(ERROR)<<"commit:"<Store(it.first, op.data); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first); + done = true; + break; + } + } + } + return true; + +} + +} +} +} // namespace eevm diff --git a/platform/consensus/ordering/fides/executor/x_manager/v_controller.h b/platform/consensus/ordering/fides/executor/x_manager/v_controller.h new file mode 100644 index 000000000..db8b71c8d --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/v_controller.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include +#include + +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class VController : public ConcurrencyController { + public: + VController(DataStorage * storage); + ~VController(); + + virtual void PushCommit(int64_t commit_id, const ModifyMap& local_changes_); + bool Commit(int64_t commit_id); + const ModifyMap * GetChangeList(int64_t commit_id) const; + +private: +bool CheckCommit(int64_t commit_id); + private: + const int window_size_ = 2000; + std::vector changes_list_; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/x_committer.cpp b/platform/consensus/ordering/fides/executor/x_manager/x_committer.cpp new file mode 100644 index 000000000..e9b388112 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/x_committer.cpp @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/x_committer.h" +#include "service/contract/executor/x_manager/executor_state.h" + +#include +#include + +#include "common/utils/utils.h" +#include "eEVM/exception.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +//#define Debug + +namespace resdb { +namespace contract { +namespace x_manager { + +namespace { + +class TimeTrack { +public: + TimeTrack(std::string name = ""){ + name_ = name; + start_time_ = GetCurrentTime(); + } + + ~TimeTrack(){ + uint64_t end_time = GetCurrentTime(); + //LOG(ERROR) << name_ <<" run:" << (end_time - start_time_)<<"ms"; + } + + double GetRunTime(){ + uint64_t end_time = GetCurrentTime(); + return (end_time - start_time_) / 1000000.0; + } +private: + std::string name_; + uint64_t start_time_; +}; + +} + +XCommitter:: XCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + int worker_num):gs_(global_state), + worker_num_(worker_num), + window_size_(window_size) { + + //LOG(ERROR)<<"init window:"<(storage, window_size); + //controller_ = std::make_unique(storage, window_size*2); + executor_ = std::make_unique(); + + resp_list_.resize(window_size_); + is_done_.resize(window_size_); + for(int i = 0; i < window_size_;++i){ + is_done_[i] =false; + resp_list_[i] = nullptr; + } + + //context_list_.resize(window_size_); + //tmp_resp_list_.resize(window_size_); + first_id_ = 0; + last_id_ = 1; + is_stop_ = false; + id_ = 1; + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request_ptr = request_queue_.Pop(); + if (request_ptr == nullptr) { + continue; + } + ExecutionContext * request = *request_ptr; + + TimeTrack track; + ExecutorState executor_state(controller_.get(), request->GetContractExecuteInfo()->commit_id); + executor_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id, + request->RedoTime()); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &executor_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time=request->RedoTime(); + } + resp->runtime = track.GetRunTime()*1000; + } + else { + //LOG(ERROR)<<"commit :"<commit_id<<" fail"; + resp->ret = -1; + } + resp_queue_.Push(std::move(resp)); + } + })); + } +} + + +XCommitter::~XCommitter(){ + //LOG(ERROR)<<"desp"; + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + +void XCommitter::AddTask(int64_t commit_id, std::unique_ptr context){ + context_list_[commit_id] = std::move(context); +} + +ExecutionContext* XCommitter::GetTaskContext(int64_t commit_id){ + return context_list_[commit_id].get(); +} + +void XCommitter::AsyncExecContract(std::vector& requests) { + + return ; +} + +std::vector> XCommitter::ExecContract( + std::vector& requests) { + + controller_->Clear(); + int id = 1; + std::vector> tmp_resp_list; + for(auto& request: requests) { + request.commit_id = id++; + auto context = std::make_unique(request); + auto context_ptr = context.get(); + context_ptr->start_time = GetCurrentTime(); + + AddTask(request.commit_id, std::move(context)); + request_queue_.Push(std::make_unique(context_ptr)); + tmp_resp_list.push_back(nullptr); + } + + tmp_resp_list.push_back(nullptr); + std::vector> resp_list; + + int process_num = id-1; + //LOG(ERROR)<<"wait num:"<0) { + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + + int64_t resp_id= resp->commit_id; + int ret = resp->ret; + #ifdef Debug + LOG(ERROR)<<"resp:"<Commit(resp_id); + if(!commit_ret){ + controller_->Clear(resp_id); + auto context_ptr = GetTaskContext(resp_id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo:"<(context_ptr)); + } + const auto& redo_list = controller_->GetRedo(); + for(int64_t id : redo_list) { + controller_->Clear(id); + auto context_ptr = GetTaskContext(id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo:"<(context_ptr)); + } + + const auto& done_list = controller_->GetDone(); + for(int id : done_list){ + //tmp_resp_list[id]->rws = *controller_->GetChangeList(id); + tmp_resp_list[id]->delay = controller_->GetDelay(id)/1000.0; + //LOG(ERROR)<<"done :"<rws.size(); + resp_list.push_back(std::move(tmp_resp_list[id])); + process_num--; + continue; + } + //resp_list.push_back(std::move(tmp_resp_list[resp_id])); + //process_num--; + //continue; + } + else { + controller_->Clear(resp_id); + auto context_ptr = GetTaskContext(resp_id); + context_ptr->SetRedo(); + #ifdef Debug + LOG(ERROR)<<"redo :"<(context_ptr)); + } + } + return resp_list; +// LOG(ERROR)<<"last id:"< XCommitter::ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state) { + //LOG(ERROR)<<"start:"<ExecContract(caller_address, contract_address, func_addr, func_param, state); +} + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/x_committer.h b/platform/consensus/ordering/fides/executor/x_manager/x_committer.h new file mode 100644 index 000000000..041e0b5d6 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/x_committer.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/contract_executor.h" +#include "service/contract/executor/x_manager/committer_context.h" +#include "service/contract/executor/x_manager/streaming_e_controller.h" +#include "service/contract/executor/x_manager/x_controller.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class XCommitter : public ContractCommitter { + public: + XCommitter( + DataStorage * storage, + GlobalState * global_state, + int window_size, + int worker_num = 2); + + ~XCommitter(); + + //void SetExecuteCallBack(std::function)> ) override; + + void AsyncExecContract(std::vector& request) override; + + absl::StatusOr ExecContract( + const Address& caller_address, const Address& contract_address, + const std::string& func_addr, + const Params& func_param, EVMState * state); + + std::vector> ExecContract(std::vector& execute_info); + + void SetController(std::unique_ptr controller); + +private: + void AddTask(int64_t commit_id, std::unique_ptr comtext); + void RemoveTask(int64_t commit_id); + void ResponseProcess(); + ExecutionContext* GetTaskContext(int64_t commit_id); + + bool WaitNext(); + bool WaitAll(); + + void CallBack(uint64_t commit_id); + + private: + std::unique_ptr controller_; + //std::unique_ptr controller_; + std::unique_ptr executor_; + GlobalState* gs_; + std::vector workers_; + std::thread response_; + std::atomic is_stop_; + std::atomic first_id_, last_id_, id_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + std::vector> resp_list_; + std::vector is_done_; + + std::map> context_list_; + + const int worker_num_; + int window_size_; + std::function)> call_back_; + std::condition_variable cv_; + std::mutex mutex_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/x_controller.cpp b/platform/consensus/ordering/fides/executor/x_manager/x_controller.cpp new file mode 100644 index 000000000..38d6b06e9 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/x_controller.cpp @@ -0,0 +1,1758 @@ +#include "service/contract/executor/x_manager/x_controller.h" + +#include +#include +#include + +#include "eEVM/exception.h" + +#include "common/utils/utils.h" + +//#define CDebug +//#define DDebug + +namespace resdb { +namespace contract { +namespace x_manager { + +int GetHashKey(const uint256_t& address){ + + const uint8_t* bytes = intx::as_bytes(address); + //uint8_t arr[32] = {}; + //memset(arr,0,sizeof(arr)); + //intx::be::store(arr, address); + //const uint8_t* bytes = arr; + size_t sz = sizeof(address); + int v = 0; + for(int i = 0; i < sz; ++i){ + v += bytes[i]; + } + return v%2048; + } + + +XController::XController(DataStorage * storage, int window_size) : + ConcurrencyController(storage), window_size_(window_size), storage_(storage){ + for(int i = 0; i < 32; i++){ + if((1<window_size_){ + window_size_ = (1< XController::GetChangeList(int64_t commit_id){ + // read lock + //return std::move(changes_list_[commit_id]); + return nullptr; +} + +void XController::Clear(int64_t commit_id){ +#ifdef CDebug + LOG(ERROR)<<"CLEAR id:"<& change_set, const Data& data){ + if(change_set.empty()){ + change_set.push_back(data); + } + else if(data.state != LOAD){ + if(change_set.back().state != LOAD){ + change_set.pop_back(); + } + change_set.push_back(data); + } + assert(change_set.size()<3); +} + +int XController::GetLastR(const uint256_t& address, int addr_idx){ + #ifdef CDebug + LOG(ERROR)<<"get last r, lp size:"<second; + if(lp.empty()){ + //LOG(ERROR)<<"no last:"<second; + if(lp.empty()){ + //LOG(ERROR)<<"no last:"< q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + if(x==to) { + //LOG(ERROR)<<"access from:"< XController::GetReach(int from){ + std::queue q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + for(int ch : child_[x]){ + if(v.find(ch) == v.end()){ + v.insert(ch); + q.push(ch); + } + } + } + //assert(reach_[to][from]==false); + return v; +} + +std::set XController::GetReach(int from, int to){ + std::queue q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + if(x==to) { + //LOG(ERROR)<<"access from:"< q; + q.push(from); + + std::set v; + v.insert(from); + + while(!q.empty()){ + int x = q.front(); + q.pop(); + LOG(ERROR)<<"reach from:"< new_f; + std::vector new_cf; + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + #ifdef CDebug + LOG(ERROR)<<"connect idx:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"< r = GetReach(last_idx); + for(int cf: new_cf){ + if(r.find(cf) != r.end()){ + // cycle + #ifdef CDebug + LOG(ERROR)<<"have cycle after change:"< new_f; + std::vector new_cf; + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + #ifdef CDebug + LOG(ERROR)<<"connect idx:"<second){ + if(f==0){ + int addr_idx_e = addr_idx&window_size_; + auto& mp = root_addr_[addr_idx_e][address]; + int sz = mp.size(); + //LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(cf == last_idx){ + continue; + } + if(committed_[cf]){ + continue; + } + new_cf.push_back(cf); + #ifdef CDebug + LOG(ERROR)<<"address:"<1){ + for(int cf : mp){ + if(committed_[cf]){ + continue; + } + if(cf == last_idx){ + continue; + } + + //assert(cf != last_idx); + new_cf.push_back(cf); + // LOG(ERROR)<<"address:"<second.erase(ait->second.find(f)); + } + pre_[idx].insert(last_idx); + child_[last_idx].insert(idx); + if(!new_cf.empty()){ + std::set r = GetReach(last_idx); + for(int cf: new_cf){ + if(r.find(cf) != r.end()){ + // cycle +#ifdef CDebug + LOG(ERROR)<<"have cycle after change:"<second.insert(cf); + addr_child_[cf][address].insert(last_idx); + addr_pre_[last_idx][address].insert(cf); + child_[cf].insert(last_idx); + pre_[last_idx].insert(cf); + } + } + + pre_[idx].insert(last_idx); + child_[last_idx].insert(idx); + #ifdef CDebug + LOG(ERROR)<<"connect :"<Load(address, false); + data.version = ret.second+1; + */ + data.version = 0; + Connect(commit_id, 0, address, addr_id, data.state!=STORE); + //assert(ret.second<=1); + } + else { + data.version = addr_changes_list_[last_r][addr_id].data.version+1; + bool ret = Connect(commit_id, last_r, address, addr_id, false); + if(!ret){ + LOG(ERROR)<<"connect commit:"<Load(address, false); + //LOG(ERROR)<<"load storage:"<Load(address, false); + // data.data = ret.first; + // data.version = ret.second; + bool ret = Connect(commit_id, 0, address, addr_id, data.state!=STORE); + assert(ret); + // assert(ret.second<=1); + } + else { + { + if(Reach(commit_id, last_w)){ + //assert(1==0); + //std::set rs = GetReach(commit_id, last_w); + // cycle? + #ifdef CDebug + // LOG(ERROR)<<"commit id:"<0){ + data.data = addr_changes_list_[last_w][addr_id].data.data; + data.version = addr_changes_list_[last_w][addr_id].data.version; + } + } + } + } + + //AddDataToChangeList(changes_list_[commit_id][address], data); + #ifdef CDebug + //LOG(ERROR)<<"add commit id:"< q; + q.push(commit_id); + + std::vector v(window_size_+1); + for(int i = 0; i <= window_size_; i++) v[i] = 0; + v[commit_id] = 1; + + while(!q.empty()){ + int x = q.front(); + q.pop(); + auto& cs = changes_list_[x][address]; + if(!cs.empty() && x != commit_id){ + if(cs.back().state == STORE){ + return x; + } + } + for(int f : addr_pre_[x][address]) { + if(v[f]==0){ + v[f] = 1; + q.push(f); + } + } + } + return -1; +} + +int XController::FindR(int64_t commit_id, const uint256_t& address, int addr_idx) { + + std::queue q; + q.push(commit_id); + + std::vector v(window_size_+1); + for(int i = 0; i <= window_size_; i++) v[i] = 0; + v[commit_id] = 1; + + while(!q.empty()){ + int x = q.front(); + q.pop(); + auto& cs = changes_list_[x][address]; + if(!cs.empty()){ + if(cs.front().state == LOAD){ + return x; + } + } + for(int f : pre_[x]) { + if(v[f]==0){ + v[f] = 1; + q.push(f); + } + } + } + return -1; +} + + +bool XController::AddOldNode(const uint256_t& address, int addr_idx, + int64_t commit_id, Data& data) { + + #ifdef CDebug + //LOG(ERROR)<<"add old node address:"<Load(address, false); + data.version = ret.second+1; + */ + data.version = 0; + Connect(commit_id, 0, address, addr_idx, data.state!=STORE); + //assert(ret.second==0); + } + else { + if(Reach(commit_id, last_r)){ + //LOG(ERROR)<<"commit id:"<Load(address, false); + data.data = ret.first; + data.version = ret.second; + } + bool ret = Connect(commit_id, 0, address, addr_idx, data.state!=STORE); + assert(ret); + //assert(ret.second==0); + } + else { + if(Reach(commit_id, last_w)){ + //assert(1==0); + //std::set rs = GetReach(commit_id, last_w); + // cycle? + #ifdef CDebug + // LOG(ERROR)<<"commit id:"<0){ + data.data = addr_changes_list_[last_w][addr_idx].data.data; + data.version = addr_changes_list_[last_w][addr_idx].data.version; + } + } + } + } + else { + if(data.state == STORE){ + if(change_set.back().state == LOAD){ + data.version = change_set.back().version+1; + } + else { + data.version = change_set.back().version; + } + } + else { + data.data = change_set.back().data; + data.version = change_set.back().version; + } + if(data.state == STORE){ + ConnectSelf(commit_id, commit_id, address, addr_idx); + if(aborted_[commit_id]){ + AbortNode(commit_id); + return false; + } + has_w = has_write_[commit_id]; + } + auto& lrp = lastr_[addr_idx]; + auto& lwp = lastw_[addr_idx]; + + if(lrp.find(commit_id) != lrp.end()){ + if(data.state == STORE){ + lwp.insert(commit_id); + } + } + else if( lwp.find(commit_id) != lwp.end()){ + if(data.state == LOAD){ + lrp.insert(commit_id); + } + } + } +#ifdef CDebug +LOG(ERROR)<<"has w:"<0 && data.state == STORE){ + AbortNodeFrom(commit_id, address); + } + } + +// AddDataToChangeList(change_set, data); + #ifdef CDebug + //LOG(ERROR)<<"add commit id:"<"; + PrintReach(i,j); + PrintReach(j,i); + assert(1==0); + } + } + } + #endif + /* + for(int i = 1; i < 500; ++i){ + for(auto it : addr_pre_[i]){ + auto address = it.first; + for(int c : it.second){ + if(c==0)continue; + if(addr_child_[c][address].find(i) == addr_child_[c][address].end()){ + LOG(ERROR)<<" id:"<GetVersion(it.first, false); + if(op.state == STORE){ + /* + if(op.version+1 != v){ + LOG(ERROR)<<"state:"<0){ + if(pre_[commit_id].size()==1 && *pre_[commit_id].begin() == 0){ + } + else { + #ifdef CDebug + for(int f : pre_[commit_id]){ + LOG(ERROR)<<" wait for pre:"<=0 && !done;--i){ + const auto& op = it.second[i]; + switch(op.state){ + case LOAD: + //LOG(ERROR)<<"load"; + break; + case STORE: + //LOG(ERROR)<<"commit:"<StoreWithVersion(it.first, op.data, op.version, false); + done = true; + break; + case REMOVE: + //LOG(ERROR)<<"remove:"<Remove(it.first, false); + done = true; + break; + } + } + } + + //LOG(ERROR)<<" commit id done:"< &XController::GetRedo(){ + return redo_; +} +const std::vector &XController::GetDone(){ + return done_; +} + +uint64_t XController::GetDelay(int64_t commit_id) { + return commit_delay_[commit_id]; +} + +} +} +} + diff --git a/platform/consensus/ordering/fides/executor/x_manager/x_controller.h b/platform/consensus/ordering/fides/executor/x_manager/x_controller.h new file mode 100644 index 000000000..495e92f66 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/x_controller.h @@ -0,0 +1,141 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "service/contract/executor/x_manager/concurrency_controller.h" +#include "service/contract/executor/x_manager/data_storage.h" +#include "platform/common/queue/lock_free_queue.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class XController : public ConcurrencyController { + public: + XController(DataStorage * storage, int window_size); + virtual ~XController(); + + // ============================== + virtual void Store(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + virtual uint256_t Load(const int64_t commit_id, const uint256_t& key, int version); + bool Remove(const int64_t commit_id, const uint256_t& key, int version); + + + // ============================== + typedef std::map > CommitList; + + const std::vector& GetDone(); + const std::vector &GetRedo(); + + void PushCommit(int64_t commit_id, const ModifyMap& local_changes_){} + bool Commit(int64_t commit_id); + + void StoreInternal(const int64_t commit_id, const uint256_t& key, const uint256_t& value, int version); + uint256_t LoadInternal(const int64_t commit_id, const uint256_t& key, int version); + + std::unique_ptr GetChangeList(int64_t commit_id); + + void Clear(); +void Clear(int64_t commit_id); + uint64_t GetDelay(int64_t commit_id); + + private: + + bool CommitUpdates(int64_t commit_id); + + bool CheckCommit(int64_t commit_id); + + void AppendPreRecord(const uint256_t& address, + int64_t commit_id, Data& data); + + int GetLastR(const uint256_t& address, int addr_id); + int GetLastW(const uint256_t& address, int addr_id); + int GetLastWOnly(const uint256_t& address, int addr_id); + int FindW(int64_t commit_id, const uint256_t& address, int addr_id); + int FindR(int64_t commit_id, const uint256_t& address, int addr_id); + + bool Connect(int idx, int last_idx, const uint256_t& address, int addr_idx, bool is_read); + void ConnectSelf(int idx, int last_idx, const uint256_t& address, int addr_idx); + bool AddNewNode(const uint256_t& address, int addr_idx, int64_t commit_id, Data& data); + bool AddOldNode(const uint256_t& address, int addr_idx, int64_t commit_id, Data& data); + void AddDataToChangeList(std::vector& change_set, const Data& data); + + void RecursiveAbort(int64_t idx, const uint256_t& address); + void AbortNodeFrom(int64_t idx, const uint256_t& address); + void AbortNode(int64_t idx); + bool ContainRead(int commit_id, const uint256_t &address); + + void RemoveNode(int64_t commit_id); + + void Abort(const int64_t commit_id); + bool Reach(int from, int to); + bool PrintReach(int from, int to); + std::set GetReach(int from, int to); + std::set GetReach(int from); + + int GetDep(int from, int to); + void AddRedo(int64_t commit_id); + + int AddressToId(const uint256_t& key); + uint256_t& GetAddress(int key); + + void ResetReach(int64_t commit_id); +void Update(const std::vector& commit_id) ; + private: + int window_size_ = 1000; + + struct DataInfo { + int64_t commit_id; + int type; + Data data; + int version; + DataInfo():type(0){} + DataInfo(int64_t commit_id, int type, Data&data) : commit_id(commit_id), type(type), data(data){} + }; + + //typedef std::map>> KeyMap; + std::vector changes_list_; + std::vector> addr_changes_list_; + //std::vector> changes_list_; + + std::set pd_; + std::vector redo_; + std::vector done_; + DataStorage* storage_; + std::vector wait_; + std::mutex mutex_[2048], abort_mutex_; + std::mutex g_mutex_, k_mutex_[2048]; + std::map > lock_[2048]; + bool aborted_[2048]; + bool is_redo_[2048]; + bool finish_[2048]; + bool committed_[2048]; + bool has_write_[2048]; + std::vector abort_list_; + std::set pre_[2048]; + std::set child_[2048]; + std::bitset<2048> reach_[2048]; + + std::map> addr_pre_[2048]; + std::map> addr_child_[2048]; + std::map> root_addr_[2048]; + std::unordered_map > lastr_, lastw_; + + std::unordered_map> check_; + std::set check_abort_; + std::vector post_abort_, pending_check_; + std::map key_[2048]; + std::unordered_map akey_; + std::atomic key_id_; + bool ds_ = false; + uint64_t commit_time_[2048], commit_delay_[2048]; +}; + +} +} +} // namespace resdb diff --git a/platform/consensus/ordering/fides/executor/x_manager/x_verifier.cpp b/platform/consensus/ordering/fides/executor/x_manager/x_verifier.cpp new file mode 100644 index 000000000..7dc04c22e --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/x_verifier.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "service/contract/executor/x_manager/x_verifier.h" + +#include + +#include "service/contract/executor/x_manager/local_state.h" +#include "common/utils/utils.h" + +#include "glog/logging.h" +#include "eEVM/processor.h" + +namespace resdb { +namespace contract { +namespace x_manager { + + +XVerifier:: XVerifier( + DataStorage * storage, + GlobalState * global_state, int worker_num):storage_(storage), gs_(global_state),worker_num_(worker_num) { + + controller_ = std::make_unique(storage); + is_stop_ = false; + + for (int i = 0; i < worker_num_; ++i) { + workers_.push_back(std::thread([&]() { + while (!is_stop_) { + auto request = request_queue_.Pop(); + if (request == nullptr) { + continue; + } + + LocalState local_state(controller_.get()); + local_state.Set(gs_->GetAccount( + request->GetContractExecuteInfo()->contract_address), + request->GetContractExecuteInfo()->commit_id); + + std::unique_ptr resp = std::make_unique(); + auto ret = ExecContract(request->GetContractExecuteInfo()->caller_address, + request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->func_addr, + request->GetContractExecuteInfo()->func_params, &local_state); + resp->state = ret.status(); + resp->contract_address = request->GetContractExecuteInfo()->contract_address; + resp->commit_id = request->GetContractExecuteInfo()->commit_id; + resp->user_id = request->GetContractExecuteInfo()->user_id; + if(ret.ok()){ + resp->ret = 0; + resp->result = *ret; + if(request->IsRedo()){ + resp->retry_time++; + } + local_state.Flesh(request->GetContractExecuteInfo()->contract_address, + request->GetContractExecuteInfo()->commit_id); + } + else { + resp->ret = -1; + } + resp_queue_.Push(std::move(resp)); + } + })); + } +} + +XVerifier::~XVerifier(){ + is_stop_ = true; + for (int i = 0; i < worker_num_; ++i) { + workers_[i].join(); + } +} + + +bool XVerifier::VerifyContract( + const std::vector& request_list, + const std::vector& rws_list) { + std::vector d; + std::map > g; + std::map id; + + for(int i = 0; i < rws_list.size();++i){ + d.push_back(0); + for(auto it : rws_list[i]){ + const Address& address = it.first; + //LOG(ERROR)<<"i ="< q; + for(int i = 0; i < request_list.size();++i){ + if(d[i]==0){ + auto context = std::make_unique(request_list[i]); + context->GetContractExecuteInfo()->commit_id = i; + request_queue_.Push(std::move(context)); + //LOG(ERROR)<<"add:"<0){ + auto resp = resp_queue_.Pop(); + if(resp == nullptr){ + continue; + } + process_num--; + int resp_commit_id = resp->commit_id; + bool ret = controller_->Commit(resp_commit_id); + if(!ret){ + return false; + } + //LOG(ERROR)<<"verify:"<GetChangeList(resp_commit_id); + if(!RWSEqual(*rws, rws_list[resp_commit_id])){ + LOG(ERROR)<<"rws not equal"; + return false; + } + for(int n_id : g[resp_commit_id]){ + //LOG(ERROR)<<"next id:"<(request_list[n_id]); + context->GetContractExecuteInfo()->commit_id = n_id; + request_queue_.Push(std::move(context)); + //LOG(ERROR)<<"add next:"<first != it2->first){ + LOG(ERROR)<<"address not equal:"<first<<" "<first; + return false; + } + +/* + if(it1->second.size() != it2->second.size()){ + LOG(ERROR)<<"item size not equal:"<second.size()<<" "<second.size()<<" address:"<first; + return false; + } + */ + + int last2 = -1, last1 = -1; + for(int i = it2->second.size()-1; i >=0; i--){ + if(it2->second[i].state == STORE){ + last2 = i; + break; + } + } + + for(int i = it1->second.size()-1; i >=0; i--){ + if(it1->second[i].state == STORE){ + last1 = i; + break; + } + } + + if(last2 ==-1 && last1 == -1){ + continue; + } + if(last2 >=0 && last1 >=0){ + if(it1->second[last1].data != it2->second[last2].data){ + LOG(ERROR)<<"data not equal:"<first<<" data:"<second[last1].data<<" "<second[last2].data; + return false; + } + continue; + } + LOG(ERROR)<<"write set not equal:"<first; + } + return true; +} + +} +} // namespace contract +} // namespace resdb + diff --git a/platform/consensus/ordering/fides/executor/x_manager/x_verifier.h b/platform/consensus/ordering/fides/executor/x_manager/x_verifier.h new file mode 100644 index 000000000..3f0261351 --- /dev/null +++ b/platform/consensus/ordering/fides/executor/x_manager/x_verifier.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include +#include + +#include "absl/status/statusor.h" +#include "eEVM/opcode.h" +#include "platform/common/queue/lock_free_queue.h" +#include "service/contract/executor/x_manager/global_state.h" +#include "service/contract/executor/x_manager/v_controller.h" +#include "service/contract/executor/x_manager/contract_committer.h" +#include "service/contract/executor/x_manager/committer_context.h" +#include "service/contract/executor/x_manager/contract_verifier.h" +#include "service/contract/executor/x_manager/utils.h" +#include "service/contract/proto/func_params.pb.h" + +namespace resdb { +namespace contract { +namespace x_manager { + +class XVerifier : public ContractVerifier { + public: + XVerifier( + DataStorage * storage, + GlobalState * global_state, int worker_num = 2); + + ~XVerifier(); + + bool VerifyContract( + const std::vector& request_list, + const std::vector& rws_list); + + bool RWSEqual(const ConcurrencyController :: ModifyMap&a, const ConcurrencyController :: ModifyMap&b); + + private: + DataStorage * storage_; + GlobalState* gs_; + std::vector workers_; + std::unique_ptr controller_; + std::atomic is_stop_; + + LockFreeQueue request_queue_; + LockFreeQueue resp_queue_; + const int worker_num_; +}; + +} +} // namespace contract +} // namespace resdb diff --git a/platform/consensus/ordering/fides/framework/BUILD b/platform/consensus/ordering/fides/framework/BUILD new file mode 100644 index 000000000..c8311d90b --- /dev/null +++ b/platform/consensus/ordering/fides/framework/BUILD @@ -0,0 +1,18 @@ +package(default_visibility = ["//visibility:private"]) + +cc_library( + name = "consensus", + srcs = ["consensus.cpp"], + hdrs = ["consensus.h"], + visibility = [ + "//visibility:public", + ], + copts = ["-Iexternal/openenclave"], + deps = [ + "//common/utils", + "//platform/consensus/ordering/common/framework:consensus", + "//platform/consensus/ordering/fides/algorithm:fides", + "//enclave:headers", + ], +) + diff --git a/platform/consensus/ordering/fides/framework/consensus.cpp b/platform/consensus/ordering/fides/framework/consensus.cpp new file mode 100644 index 000000000..17ad1c125 --- /dev/null +++ b/platform/consensus/ordering/fides/framework/consensus.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "platform/consensus/ordering/fides/framework/consensus.h" + +#include +#include + +#include "common/utils/utils.h" + +namespace resdb { +namespace fides { + +FidesConsensus::FidesConsensus(const ResDBConfig& config, + std::unique_ptr executor, + oe_enclave_t* enclave) + : Consensus(config, std::move(executor)) { + int total_replicas = config_.GetReplicaNum(); + int f = (total_replicas - 1) / 3; + + Init(); + + if (config_.GetPublicKeyCertificateInfo() + .public_key() + .public_key_info() + .type() != CertificateKeyInfo::CLIENT) { + fides_ = std::make_unique(config_.GetSelfInfo().id(), f, + total_replicas, GetSignatureVerifier(), + config, enclave); + + fides_->SetSingleCallFunc( + [&](int type, const google::protobuf::Message& msg, int node_id) { + return SendMsg(type, msg, node_id); + }); + + fides_->SetBroadcastCallFunc( + [&](int type, const google::protobuf::Message& msg) { + return Broadcast(type, msg); + }); + + fides_->SetCommitFunc([&](const google::protobuf::Message& msg) { + return CommitMsg(dynamic_cast(msg)); + }); + } + LOG(ERROR)<<"init consensus done"; +} + +int FidesConsensus::ProcessCustomConsensus(std::unique_ptr request) { + //LOG(ERROR)<<"recv request:"<user_type()); + // int64_t current_time = GetCurrentTime(); + if (request->user_type() == MessageType::NewBlock) { + std::unique_ptr p = std::make_unique(); + if (!p->ParseFromString(request->data())) { + LOG(ERROR) << "parse proposal fail"; + assert(1 == 0); + return -1; + } + fides_->ReceiveBlock(std::move(p)); + } + // Only 1 type of message: NewBlock. + /* + else if (request->user_type() == MessageType::BlockACK) { + std::unique_ptr metadata = std::make_unique(); + if (!metadata->ParseFromString(request->data())) { + LOG(ERROR) << "parse proposal fail"; + assert(1 == 0); + return -1; + } + fides_->ReceiveBlockACK(std::move(metadata)); + } else if (request->user_type() == MessageType::Cert) { + std::unique_ptr cert = std::make_unique(); + if (!cert->ParseFromString(request->data())) { + LOG(ERROR) << "parse proposal fail"; + assert(1 == 0); + return -1; + } + fides_->ReceiveBlockCert(std::move(cert)); + } + */ + return 0; +} + +int FidesConsensus::ProcessNewTransaction(std::unique_ptr request) { + std::unique_ptr txn = std::make_unique(); + txn->set_data(request->data()); + txn->set_hash(request->hash()); + txn->set_proxy_id(request->proxy_id()); + return fides_->ReceiveTransaction(std::move(txn)); +} + +int FidesConsensus::CommitMsg(const google::protobuf::Message& msg) { + return CommitMsgInternal(dynamic_cast(msg)); +} + +int FidesConsensus::CommitMsgInternal(const Transaction& txn) { + //LOG(ERROR)<<"commit txn:"< request = std::make_unique(); + request->set_queuing_time(txn.queuing_time()); + request->set_data(txn.data()); + request->set_seq(txn.id()); + request->set_proxy_id(txn.proxy_id()); + transaction_executor_->AddExecuteMessage(std::move(request)); + return 0; +} + + + +} // namespace fides +} // namespace resdb diff --git a/platform/consensus/ordering/fides/framework/consensus.h b/platform/consensus/ordering/fides/framework/consensus.h new file mode 100644 index 000000000..46b56b9c6 --- /dev/null +++ b/platform/consensus/ordering/fides/framework/consensus.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "executor/common/transaction_manager.h" +#include "platform/consensus/execution/transaction_executor.h" +#include "platform/consensus/ordering/common/framework/consensus.h" +#include "platform/consensus/ordering/fides/algorithm/fides.h" +#include "platform/networkstrate/consensus_manager.h" +#include "enclave/sgx_cpp_u.h" + +namespace resdb { +namespace fides { + +class FidesConsensus : public common::Consensus { + public: + FidesConsensus(const ResDBConfig& config, + std::unique_ptr transaction_manager, + oe_enclave_t* enclave); + + protected: + int ProcessCustomConsensus(std::unique_ptr request) override; + int ProcessNewTransaction(std::unique_ptr request) override; + int CommitMsg(const google::protobuf::Message& msg) override; + int CommitMsgInternal(const Transaction& txn); + + private: + std::unique_ptr fides_; +}; + +} // namespace fides +} // namespace resdb diff --git a/platform/consensus/ordering/fides/proto/BUILD b/platform/consensus/ordering/fides/proto/BUILD new file mode 100644 index 000000000..9b640b702 --- /dev/null +++ b/platform/consensus/ordering/fides/proto/BUILD @@ -0,0 +1,18 @@ +package(default_visibility = ["//platform/consensus/ordering/fides:__subpackages__"]) + +load("@rules_cc//cc:defs.bzl", "cc_proto_library") +load("@rules_proto//proto:defs.bzl", "proto_library") +load("@rules_proto_grpc//python:defs.bzl", "python_proto_library") + +proto_library( + name = "proposal_proto", + srcs = ["proposal.proto"], + deps = [ + "//common/proto:signature_info_proto", + ], +) + +cc_proto_library( + name = "proposal_cc_proto", + deps = [":proposal_proto"], +) diff --git a/platform/consensus/ordering/fides/proto/proposal.proto b/platform/consensus/ordering/fides/proto/proposal.proto new file mode 100644 index 000000000..57cdd8937 --- /dev/null +++ b/platform/consensus/ordering/fides/proto/proposal.proto @@ -0,0 +1,85 @@ + +syntax = "proto3"; +import "common/proto/signature_info.proto"; + +package resdb.fides; + +message Metadata { + int32 round = 1; + bytes hash = 2; + int32 sender = 3; + SignatureInfo sign = 4; // signature for each resp. + int32 proposer = 5; +} + +message Reference { + int32 round = 1; + bytes hash = 2; + int32 proposer = 3; +} + +message CertLink { + repeated Certificate cert = 1; +} + +message ReferenceLink { + repeated ReferenceLink ref = 1; +} + +message Certificate { + repeated Metadata metadata = 1; + int32 round = 2; + int32 proposer = 3; + bytes hash = 4; + CertLink strong_cert = 5; + CounterInfo counter = 6; +} + +message Transaction{ + int32 id = 1; + bytes data = 2; + bytes hash = 3; + int32 proxy_id = 4; + int64 create_time = 5; + int32 group_id = 6; + int64 queuing_time = 7; +} + +enum ProposalType{ + NewMsg = 0; + Prepared = 1; + Commit = 2; + Ready_execute = 3; +}; + +message Header { + int32 proposer_id = 3; + int32 proposal_id = 4; + int64 create_time = 6; + ProposalType status = 7; + int32 round = 8; + CertLink strong_cert = 9; + CertLink weak_cert = 10; + CounterInfo counter = 11; +} + +message Proposal { + Header header = 1; + repeated Transaction transactions = 3; + int32 sender = 5; + bytes hash = 6; + int64 queuing_time = 7; +}; + +message CounterInfo { + uint32 value = 1; + bytes attestation = 2; +} + +enum MessageType { + NewProposal = 0; + NewBlock = 1; + BlockACK = 2; + Cert = 3; +}; + diff --git a/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.cpp b/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.cpp index 4317a3960..fc3d7fc5e 100644 --- a/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.cpp +++ b/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.h" diff --git a/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.h b/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.h index 9cb3edafd..42fbf3ae7 100644 --- a/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.h +++ b/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.cpp b/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.cpp index acc10b5f2..61c5cf37e 100644 --- a/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.cpp +++ b/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/geo_pbft/geo_pbft_commitment.h" diff --git a/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.h b/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.h index c059da5e2..43fc7c76d 100644 --- a/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.h +++ b/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/geo_pbft/geo_pbft_commitment_test.cpp b/platform/consensus/ordering/geo_pbft/geo_pbft_commitment_test.cpp index 6cc66585b..0c9c31c45 100644 --- a/platform/consensus/ordering/geo_pbft/geo_pbft_commitment_test.cpp +++ b/platform/consensus/ordering/geo_pbft/geo_pbft_commitment_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/geo_pbft/geo_pbft_commitment.h" diff --git a/platform/consensus/ordering/geo_pbft/hash_set.h b/platform/consensus/ordering/geo_pbft/hash_set.h index 2ee556bbb..e608e7955 100644 --- a/platform/consensus/ordering/geo_pbft/hash_set.h +++ b/platform/consensus/ordering/geo_pbft/hash_set.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/pbft/BUILD b/platform/consensus/ordering/pbft/BUILD index 300c96a90..ce59cb9f7 100644 --- a/platform/consensus/ordering/pbft/BUILD +++ b/platform/consensus/ordering/pbft/BUILD @@ -61,7 +61,7 @@ cc_library( ":lock_free_collector_pool", ":transaction_collector", ":transaction_utils", - "//chain/storage:txn_memory_db", + "//chain/state:chain_state", "//executor/common:transaction_manager", "//platform/config:resdb_config", "//platform/networkstrate:server_comm", @@ -114,7 +114,7 @@ cc_library( hdrs = ["checkpoint_manager.h"], deps = [ ":transaction_utils", - "//chain/storage:txn_memory_db", + "//chain/state:chain_state", "//common/crypto:signature_verifier", "//interface/common:resdb_txn_accessor", "//platform/config:resdb_config", diff --git a/platform/consensus/ordering/pbft/checkpoint_manager.cpp b/platform/consensus/ordering/pbft/checkpoint_manager.cpp index cc8815633..ef7483083 100644 --- a/platform/consensus/ordering/pbft/checkpoint_manager.cpp +++ b/platform/consensus/ordering/pbft/checkpoint_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/checkpoint_manager.h" @@ -37,7 +31,7 @@ CheckPointManager::CheckPointManager(const ResDBConfig& config, SignatureVerifier* verifier) : config_(config), replica_communicator_(replica_communicator), - txn_db_(std::make_unique()), + txn_db_(std::make_unique()), verifier_(verifier), stop_(false), txn_accessor_(config), @@ -71,7 +65,7 @@ std::string GetHash(const std::string& h1, const std::string& h2) { return SignatureVerifier::CalculateHash(h1 + h2); } -TxnMemoryDB* CheckPointManager::GetTxnDB() { return txn_db_.get(); } +ChainState* CheckPointManager::GetTxnDB() { return txn_db_.get(); } uint64_t CheckPointManager::GetMaxTxnSeq() { return txn_db_->GetMaxSeq(); } @@ -105,7 +99,7 @@ bool CheckPointManager::IsValidCheckpointProof( senders.insert(signature.node_id()); } - return (senders.size() >= config_.GetMinDataReceiveNum()) || + return (static_cast(senders.size()) >= config_.GetMinDataReceiveNum()) || (stable_ckpt.seq() == 0 && senders.size() == 0); } @@ -171,7 +165,6 @@ bool CheckPointManager::Wait() { void CheckPointManager::UpdateStableCheckPointStatus() { uint64_t last_committable_seq = 0; - int water_mark = config_.GetCheckPointWaterMark(); while (!stop_) { if (!Wait()) { continue; diff --git a/platform/consensus/ordering/pbft/checkpoint_manager.h b/platform/consensus/ordering/pbft/checkpoint_manager.h index cbde9ada5..e043978ea 100644 --- a/platform/consensus/ordering/pbft/checkpoint_manager.h +++ b/platform/consensus/ordering/pbft/checkpoint_manager.h @@ -1,33 +1,27 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once #include -#include "chain/storage/txn_memory_db.h" +#include "chain/state/chain_state.h" #include "common/crypto/signature_verifier.h" #include "interface/common/resdb_txn_accessor.h" #include "platform/config/resdb_config.h" @@ -47,7 +41,7 @@ class CheckPointManager : public CheckPoint { SignatureVerifier* verifier); virtual ~CheckPointManager(); - TxnMemoryDB* GetTxnDB(); + ChainState* GetTxnDB(); uint64_t GetMaxTxnSeq(); void AddCommitData(std::unique_ptr request); @@ -92,7 +86,7 @@ class CheckPointManager : public CheckPoint { protected: ResDBConfig config_; ReplicaCommunicator* replica_communicator_; - std::unique_ptr txn_db_; + std::unique_ptr txn_db_; std::thread checkpoint_thread_, stable_checkpoint_thread_; SignatureVerifier* verifier_; std::atomic stop_; diff --git a/platform/consensus/ordering/pbft/checkpoint_manager_test.cpp b/platform/consensus/ordering/pbft/checkpoint_manager_test.cpp index d5ef6528f..f302e8195 100644 --- a/platform/consensus/ordering/pbft/checkpoint_manager_test.cpp +++ b/platform/consensus/ordering/pbft/checkpoint_manager_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/checkpoint_manager.h" diff --git a/platform/consensus/ordering/pbft/commitment.cpp b/platform/consensus/ordering/pbft/commitment.cpp index d30add520..c2e84b149 100644 --- a/platform/consensus/ordering/pbft/commitment.cpp +++ b/platform/consensus/ordering/pbft/commitment.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/commitment.h" @@ -160,7 +154,8 @@ int Commitment::ProcessProposeMsg(std::unique_ptr context, return -2; } if (request->is_recovery()) { - if (request->seq() >= message_manager_->GetNextSeq()) { + if (static_cast(request->seq()) >= + message_manager_->GetNextSeq()) { message_manager_->SetNextSeq(request->seq() + 1); } return message_manager_->AddConsensusMsg(context->signature, diff --git a/platform/consensus/ordering/pbft/commitment.h b/platform/consensus/ordering/pbft/commitment.h index d694caaa8..03d77cf3d 100644 --- a/platform/consensus/ordering/pbft/commitment.h +++ b/platform/consensus/ordering/pbft/commitment.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/pbft/commitment_test.cpp b/platform/consensus/ordering/pbft/commitment_test.cpp index 86e16927a..1b8b24a79 100644 --- a/platform/consensus/ordering/pbft/commitment_test.cpp +++ b/platform/consensus/ordering/pbft/commitment_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/commitment.h" diff --git a/platform/consensus/ordering/pbft/consensus_manager_pbft.cpp b/platform/consensus/ordering/pbft/consensus_manager_pbft.cpp index f1946bbe2..5131445a2 100644 --- a/platform/consensus/ordering/pbft/consensus_manager_pbft.cpp +++ b/platform/consensus/ordering/pbft/consensus_manager_pbft.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/consensus_manager_pbft.h" diff --git a/platform/consensus/ordering/pbft/consensus_manager_pbft.h b/platform/consensus/ordering/pbft/consensus_manager_pbft.h index 5cefee33b..bea50990c 100644 --- a/platform/consensus/ordering/pbft/consensus_manager_pbft.h +++ b/platform/consensus/ordering/pbft/consensus_manager_pbft.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/pbft/lock_free_collector_pool.cpp b/platform/consensus/ordering/pbft/lock_free_collector_pool.cpp index 6ccc86723..4336b66d2 100644 --- a/platform/consensus/ordering/pbft/lock_free_collector_pool.cpp +++ b/platform/consensus/ordering/pbft/lock_free_collector_pool.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/lock_free_collector_pool.h" diff --git a/platform/consensus/ordering/pbft/lock_free_collector_pool.h b/platform/consensus/ordering/pbft/lock_free_collector_pool.h index 0c075e2a1..5335c4fd6 100644 --- a/platform/consensus/ordering/pbft/lock_free_collector_pool.h +++ b/platform/consensus/ordering/pbft/lock_free_collector_pool.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/pbft/lock_free_collector_pool_test.cpp b/platform/consensus/ordering/pbft/lock_free_collector_pool_test.cpp index 89e51867c..1c4d5761c 100644 --- a/platform/consensus/ordering/pbft/lock_free_collector_pool_test.cpp +++ b/platform/consensus/ordering/pbft/lock_free_collector_pool_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/lock_free_collector_pool.h" diff --git a/platform/consensus/ordering/pbft/message_manager.cpp b/platform/consensus/ordering/pbft/message_manager.cpp index b7b7bfe2a..37d3b5de8 100644 --- a/platform/consensus/ordering/pbft/message_manager.cpp +++ b/platform/consensus/ordering/pbft/message_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/message_manager.h" diff --git a/platform/consensus/ordering/pbft/message_manager.h b/platform/consensus/ordering/pbft/message_manager.h index 667dfe831..c51fd22a5 100644 --- a/platform/consensus/ordering/pbft/message_manager.h +++ b/platform/consensus/ordering/pbft/message_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once @@ -32,7 +26,7 @@ #include #include -#include "chain/storage/txn_memory_db.h" +#include "chain/state/chain_state.h" #include "executor/common/transaction_manager.h" #include "platform/common/queue/lock_free_queue.h" #include "platform/config/resdb_config.h" @@ -130,7 +124,7 @@ class MessageManager { uint64_t next_seq_ = 1; LockFreeQueue queue_; - TxnMemoryDB* txn_db_; + ChainState* txn_db_; SystemInfo* system_info_; CheckPointManager* checkpoint_manager_; std::map>> diff --git a/platform/consensus/ordering/pbft/mock_checkpoint_manager.h b/platform/consensus/ordering/pbft/mock_checkpoint_manager.h index d52c22ee4..0cdd6028d 100644 --- a/platform/consensus/ordering/pbft/mock_checkpoint_manager.h +++ b/platform/consensus/ordering/pbft/mock_checkpoint_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/pbft/performance_manager.cpp b/platform/consensus/ordering/pbft/performance_manager.cpp index dfecb5940..a5ba979ff 100644 --- a/platform/consensus/ordering/pbft/performance_manager.cpp +++ b/platform/consensus/ordering/pbft/performance_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/performance_manager.h" diff --git a/platform/consensus/ordering/pbft/performance_manager.h b/platform/consensus/ordering/pbft/performance_manager.h index cfc6fd97b..7fc6e5967 100644 --- a/platform/consensus/ordering/pbft/performance_manager.h +++ b/platform/consensus/ordering/pbft/performance_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/pbft/pre_very_consensus_service_pbft.h b/platform/consensus/ordering/pbft/pre_very_consensus_service_pbft.h index e03852606..1b26313de 100644 --- a/platform/consensus/ordering/pbft/pre_very_consensus_service_pbft.h +++ b/platform/consensus/ordering/pbft/pre_very_consensus_service_pbft.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/pbft/query.cpp b/platform/consensus/ordering/pbft/query.cpp index f01cc2344..72bb4ed5b 100644 --- a/platform/consensus/ordering/pbft/query.cpp +++ b/platform/consensus/ordering/pbft/query.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/query.h" diff --git a/platform/consensus/ordering/pbft/query.h b/platform/consensus/ordering/pbft/query.h index afc6734f6..e451cdfeb 100644 --- a/platform/consensus/ordering/pbft/query.h +++ b/platform/consensus/ordering/pbft/query.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/pbft/query_test.cpp b/platform/consensus/ordering/pbft/query_test.cpp index 54d9c6088..4cc1a1175 100644 --- a/platform/consensus/ordering/pbft/query_test.cpp +++ b/platform/consensus/ordering/pbft/query_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/query.h" diff --git a/platform/consensus/ordering/pbft/response_manager.cpp b/platform/consensus/ordering/pbft/response_manager.cpp index 5764d96b3..9d212f619 100644 --- a/platform/consensus/ordering/pbft/response_manager.cpp +++ b/platform/consensus/ordering/pbft/response_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/response_manager.h" diff --git a/platform/consensus/ordering/pbft/response_manager.h b/platform/consensus/ordering/pbft/response_manager.h index 8b08c7fad..fdf89b752 100644 --- a/platform/consensus/ordering/pbft/response_manager.h +++ b/platform/consensus/ordering/pbft/response_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/pbft/response_manager_test.cpp b/platform/consensus/ordering/pbft/response_manager_test.cpp index 655b4aafe..62b16ee6f 100644 --- a/platform/consensus/ordering/pbft/response_manager_test.cpp +++ b/platform/consensus/ordering/pbft/response_manager_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/response_manager.h" diff --git a/platform/consensus/ordering/pbft/transaction_collector.cpp b/platform/consensus/ordering/pbft/transaction_collector.cpp index 4447dfc53..0c69c401d 100644 --- a/platform/consensus/ordering/pbft/transaction_collector.cpp +++ b/platform/consensus/ordering/pbft/transaction_collector.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/transaction_collector.h" diff --git a/platform/consensus/ordering/pbft/transaction_collector.h b/platform/consensus/ordering/pbft/transaction_collector.h index 601ecbf1f..a3edaa44e 100644 --- a/platform/consensus/ordering/pbft/transaction_collector.h +++ b/platform/consensus/ordering/pbft/transaction_collector.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/pbft/transaction_collector_test.cpp b/platform/consensus/ordering/pbft/transaction_collector_test.cpp index d105082de..d1c9c7eed 100644 --- a/platform/consensus/ordering/pbft/transaction_collector_test.cpp +++ b/platform/consensus/ordering/pbft/transaction_collector_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/transaction_collector.h" diff --git a/platform/consensus/ordering/pbft/transaction_utils.cpp b/platform/consensus/ordering/pbft/transaction_utils.cpp index d5a69a3f6..5369abd02 100644 --- a/platform/consensus/ordering/pbft/transaction_utils.cpp +++ b/platform/consensus/ordering/pbft/transaction_utils.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/transaction_utils.h" diff --git a/platform/consensus/ordering/pbft/transaction_utils.h b/platform/consensus/ordering/pbft/transaction_utils.h index fbed78396..e5e3eac22 100644 --- a/platform/consensus/ordering/pbft/transaction_utils.h +++ b/platform/consensus/ordering/pbft/transaction_utils.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/pbft/viewchange_manager.cpp b/platform/consensus/ordering/pbft/viewchange_manager.cpp index 79569baf2..7033801b3 100644 --- a/platform/consensus/ordering/pbft/viewchange_manager.cpp +++ b/platform/consensus/ordering/pbft/viewchange_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/viewchange_manager.h" diff --git a/platform/consensus/ordering/pbft/viewchange_manager.h b/platform/consensus/ordering/pbft/viewchange_manager.h index e65eeaa18..a6e085edd 100644 --- a/platform/consensus/ordering/pbft/viewchange_manager.h +++ b/platform/consensus/ordering/pbft/viewchange_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/ordering/pbft/viewchange_manager_test.cpp b/platform/consensus/ordering/pbft/viewchange_manager_test.cpp index 83eec0013..94701535b 100644 --- a/platform/consensus/ordering/pbft/viewchange_manager_test.cpp +++ b/platform/consensus/ordering/pbft/viewchange_manager_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/ordering/pbft/viewchange_manager.h" diff --git a/platform/consensus/ordering/poe/algorithm/BUILD b/platform/consensus/ordering/poe/algorithm/BUILD new file mode 100644 index 000000000..357f56d8b --- /dev/null +++ b/platform/consensus/ordering/poe/algorithm/BUILD @@ -0,0 +1,15 @@ +package(default_visibility = ["//platform/consensus/ordering/poe:__subpackages__"]) + +cc_library( + name = "poe", + srcs = ["poe.cpp"], + hdrs = ["poe.h"], + deps = [ + "//platform/statistic:stats", + "//common:comm", + "//platform/consensus/ordering/poe/proto:proposal_cc_proto", + "//common/crypto:signature_verifier", + "//platform/consensus/ordering/common/algorithm:protocol_base", + "//platform/common/queue:lock_free_queue", + ], +) diff --git a/platform/consensus/ordering/poe/algorithm/poe.cpp b/platform/consensus/ordering/poe/algorithm/poe.cpp new file mode 100644 index 000000000..14580b7d5 --- /dev/null +++ b/platform/consensus/ordering/poe/algorithm/poe.cpp @@ -0,0 +1,80 @@ +#include "platform/consensus/ordering/poe/algorithm/poe.h" + +#include + +#include "common/crypto/signature_verifier.h" +#include "common/utils/utils.h" + +namespace resdb { +namespace poe { + +PoE::PoE(int id, int f, int total_num, SignatureVerifier* verifier) + : ProtocolBase(id, f, total_num), verifier_(verifier) { + + LOG(ERROR) << "get proposal graph"; + id_ = id; + total_num_ = total_num; + f_ = f; + is_stop_ = false; + seq_ = 0; +} + +PoE::~PoE() { + is_stop_ = true; +} + +bool PoE::IsStop() { return is_stop_; } + +bool PoE::ReceiveTransaction(std::unique_ptr txn) { + // LOG(ERROR)<<"recv txn:"; + txn->set_create_time(GetCurrentTime()); + txn->set_seq(seq_++); + txn->set_proposer(id_); + + Broadcast(MessageType::Propose, *txn); + return true; +} + +bool PoE::ReceivePropose(std::unique_ptr txn) { + std::string hash = txn->hash(); + int64_t seq = txn->seq(); + int proposer = txn->proposer(); + { + // LOG(ERROR)<<"recv proposal"; + //LOG(ERROR)<<"recv txn from:"<proposer()<<" id:"<seq(); + std::unique_lock lk(mutex_); + data_[txn->hash()]=std::move(txn); + } + + Proposal proposal; + proposal.set_hash(hash); + proposal.set_seq(seq); + proposal.set_proposer(id_); + Broadcast(MessageType::Prepare, proposal); + //LOG(ERROR)<<"receive proposal done"; + return true; +} + +bool PoE::ReceivePrepare(std::unique_ptr proposal) { + std::unique_ptr txn = nullptr; + { + //LOG(ERROR)<<"recv proposal from:"<proposer()<<" id:"<seq(); + std::unique_lock lk(mutex_); + received_[proposal->hash()].insert(proposal->proposer()); + auto it = data_.find(proposal->hash()); + if(it != data_.end()){ + if(received_[proposal->hash()].size()>=2*f_+1){ + txn = std::move(it->second); + data_.erase(it); + } + } + } + if(txn != nullptr){ + commit_(*txn); + } + // LOG(ERROR)<<"receive proposal done"; + return true; +} + +} // namespace poe +} // namespace resdb diff --git a/platform/consensus/ordering/poe/algorithm/poe.h b/platform/consensus/ordering/poe/algorithm/poe.h new file mode 100644 index 000000000..20cc71a93 --- /dev/null +++ b/platform/consensus/ordering/poe/algorithm/poe.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include +#include + +#include "platform/common/queue/lock_free_queue.h" +#include "platform/consensus/ordering/common/algorithm/protocol_base.h" +#include "platform/consensus/ordering/poe/proto/proposal.pb.h" +#include "platform/statistic/stats.h" + +namespace resdb { +namespace poe { + +class PoE: public common::ProtocolBase { + public: + PoE(int id, int f, int total_num, SignatureVerifier* verifier); + ~PoE(); + + bool ReceiveTransaction(std::unique_ptr txn); + bool ReceivePropose(std::unique_ptr txn); + bool ReceivePrepare(std::unique_ptr proposal); + + private: + bool IsStop(); + + private: + std::mutex mutex_; + std::map > received_; + std::map > data_; + + int64_t seq_; + bool is_stop_; + SignatureVerifier* verifier_; + Stats* global_stats_; +}; + +} // namespace cassandra +} // namespace resdb diff --git a/platform/consensus/ordering/poe/framework/BUILD b/platform/consensus/ordering/poe/framework/BUILD new file mode 100644 index 000000000..7030d2a0d --- /dev/null +++ b/platform/consensus/ordering/poe/framework/BUILD @@ -0,0 +1,16 @@ +package(default_visibility = ["//visibility:private"]) + +cc_library( + name = "consensus", + srcs = ["consensus.cpp"], + hdrs = ["consensus.h"], + visibility = [ + "//visibility:public", + ], + deps = [ + "//common/utils", + "//platform/consensus/ordering/common/framework:consensus", + "//platform/consensus/ordering/poe/algorithm:poe", + ], +) + diff --git a/platform/consensus/ordering/poe/framework/consensus.cpp b/platform/consensus/ordering/poe/framework/consensus.cpp new file mode 100644 index 000000000..c162b7fce --- /dev/null +++ b/platform/consensus/ordering/poe/framework/consensus.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "platform/consensus/ordering/poe/framework/consensus.h" + +#include +#include + +#include "common/utils/utils.h" + +namespace resdb { +namespace poe { + +Consensus::Consensus(const ResDBConfig& config, + std::unique_ptr executor) + : common::Consensus(config, std::move(executor)){ + int total_replicas = config_.GetReplicaNum(); + int f = (total_replicas - 1) / 3; + + Init(); + + start_ = 0; + + if (config_.GetPublicKeyCertificateInfo() + .public_key() + .public_key_info() + .type() != CertificateKeyInfo::CLIENT) { + poe_ = std::make_unique( + config_.GetSelfInfo().id(), f, + total_replicas, GetSignatureVerifier()); + InitProtocol(poe_.get()); + } +} + +int Consensus::ProcessCustomConsensus(std::unique_ptr request) { + //LOG(ERROR)<<"receive commit:"<type()<<" "<user_type()); + if (request->user_type() == MessageType::Propose) { + std::unique_ptr txn = std::make_unique(); + if (!txn->ParseFromString(request->data())) { + assert(1 == 0); + LOG(ERROR) << "parse proposal fail"; + return -1; + } + poe_->ReceivePropose(std::move(txn)); + return 0; + } else if (request->user_type() == MessageType::Prepare) { + std::unique_ptr proposal = std::make_unique(); + if (!proposal->ParseFromString(request->data())) { + LOG(ERROR) << "parse proposal fail"; + assert(1 == 0); + return -1; + } + poe_->ReceivePrepare(std::move(proposal)); + return 0; + } + return 0; +} + +int Consensus::ProcessNewTransaction(std::unique_ptr request) { + std::unique_ptr txn = std::make_unique(); + txn->set_data(request->data()); + txn->set_hash(request->hash()); + txn->set_proxy_id(request->proxy_id()); + txn->set_uid(request->uid()); + //LOG(ERROR)<<"receive txn"; + return poe_->ReceiveTransaction(std::move(txn)); +} + +int Consensus::CommitMsg(const google::protobuf::Message& msg) { + return CommitMsgInternal(dynamic_cast(msg)); +} + +int Consensus::CommitMsgInternal(const Transaction& txn) { + //LOG(ERROR)<<"commit txn:"< request = std::make_unique(); + request->set_data(txn.data()); + request->set_seq(txn.seq()); + request->set_uid(txn.uid()); + request->set_proxy_id(txn.proxy_id()); + + transaction_executor_->Commit(std::move(request)); + return 0; +} + +} // namespace poe +} // namespace resdb diff --git a/platform/consensus/ordering/poe/framework/consensus.h b/platform/consensus/ordering/poe/framework/consensus.h new file mode 100644 index 000000000..72e56e181 --- /dev/null +++ b/platform/consensus/ordering/poe/framework/consensus.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#pragma once + +#include "executor/common/transaction_manager.h" +#include "platform/consensus/ordering/common/framework/consensus.h" +#include "platform/consensus/ordering/poe/algorithm/poe.h" +#include "platform/networkstrate/consensus_manager.h" + +namespace resdb { +namespace poe { + +class Consensus : public common::Consensus { + public: + Consensus(const ResDBConfig& config, + std::unique_ptr transaction_manager); + virtual ~Consensus() = default; + + private: + int ProcessCustomConsensus(std::unique_ptr request) override; + int ProcessNewTransaction(std::unique_ptr request) override; + int CommitMsg(const google::protobuf::Message& msg) override; + int CommitMsgInternal(const Transaction& txn); + + int Prepare(const Transaction& txn); + + protected: + std::unique_ptr poe_; + Stats* global_stats_; + int64_t start_; + std::mutex mutex_; + int send_num_[200]; +}; + +} // namespace cassandra +} // namespace resdb diff --git a/platform/consensus/ordering/poe/framework/consensus_test.cpp b/platform/consensus/ordering/poe/framework/consensus_test.cpp new file mode 100644 index 000000000..2c8834a8b --- /dev/null +++ b/platform/consensus/ordering/poe/framework/consensus_test.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2019-2022 ExpoLab, UC Davis + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "platform/consensus/ordering/cassandra/framework/consensus.h" + +#include +#include +#include + +#include + +#include "common/test/test_macros.h" +#include "executor/common/mock_transaction_manager.h" +#include "platform/config/resdb_config_utils.h" +#include "platform/networkstrate/mock_replica_communicator.h" + +namespace resdb { +namespace cassandra { +namespace { + +using ::resdb::testing::EqualsProto; +using ::testing::_; +using ::testing::Invoke; +using ::testing::Test; + +ResDBConfig GetConfig() { + ResDBConfig config({GenerateReplicaInfo(1, "127.0.0.1", 1234), + GenerateReplicaInfo(2, "127.0.0.1", 1235), + GenerateReplicaInfo(3, "127.0.0.1", 1236), + GenerateReplicaInfo(4, "127.0.0.1", 1237)}, + GenerateReplicaInfo(1, "127.0.0.1", 1234)); + return config; +} + +class ConsensusTest : public Test { + public: + ConsensusTest() : config_(GetConfig()) { + auto transaction_manager = + std::make_unique(); + mock_transaction_manager_ = transaction_manager.get(); + consensus_ = + std::make_unique(config_, std::move(transaction_manager)); + consensus_->SetCommunicator(&replica_communicator_); + } + + void AddTransaction(const std::string& data) { + auto request = std::make_unique(); + request->set_type(Request::TYPE_NEW_TXNS); + + Transaction txn; + + BatchUserRequest batch_request; + auto req = batch_request.add_user_requests(); + req->mutable_request()->set_data(data); + + batch_request.set_local_id(1); + batch_request.SerializeToString(txn.mutable_data()); + + txn.SerializeToString(request->mutable_data()); + + EXPECT_EQ(consensus_->ConsensusCommit(nullptr, std::move(request)), 0); + } + + protected: + ResDBConfig config_; + MockTransactionExecutorDataImpl* mock_transaction_manager_; + MockReplicaCommunicator replica_communicator_; + std::unique_ptr transaction_manager_; + std::unique_ptr consensus_; +}; + +TEST_F(ConsensusTest, NormalCase) { + std::promise commit_done; + std::future commit_done_future = commit_done.get_future(); + + EXPECT_CALL(replica_communicator_, BroadCast) + .WillRepeatedly(Invoke([&](const google::protobuf::Message& msg) { + Request request = *dynamic_cast(&msg); + + if (request.user_type() == MessageType::NewProposal) { + LOG(ERROR) << "bc new proposal"; + consensus_->ConsensusCommit(nullptr, + std::make_unique(request)); + LOG(ERROR) << "recv proposal done"; + } + if (request.user_type() == MessageType::Vote) { + LOG(ERROR) << "bc vote"; + + VoteMessage ack_msg; + assert(ack_msg.ParseFromString(request.data())); + for (int i = 1; i <= 3; ++i) { + ack_msg.set_proposer_id(i); + auto new_req = std::make_unique(request); + ack_msg.SerializeToString(new_req->mutable_data()); + + consensus_->ConsensusCommit(nullptr, std::move(new_req)); + } + } + // LOG(ERROR)<<"bc type:"<type()<<" user + // type:"<user_type(); + if (request.user_type() == MessageType::Prepare) { + LOG(ERROR) << "bc prepare"; + + VoteMessage ack_msg; + assert(ack_msg.ParseFromString(request.data())); + for (int i = 1; i <= 3; ++i) { + ack_msg.set_proposer_id(i); + auto new_req = std::make_unique(request); + ack_msg.SerializeToString(new_req->mutable_data()); + + consensus_->ConsensusCommit(nullptr, std::move(new_req)); + } + } + if (request.user_type() == MessageType::Voteprep) { + LOG(ERROR) << "bc voterep:"; + + VoteMessage ack_msg; + assert(ack_msg.ParseFromString(request.data())); + for (int i = 1; i <= 3; ++i) { + ack_msg.set_proposer_id(i); + auto new_req = std::make_unique(request); + ack_msg.SerializeToString(new_req->mutable_data()); + LOG(ERROR) << "new request type:" << new_req->user_type(); + + consensus_->ConsensusCommit(nullptr, std::move(new_req)); + } + } + LOG(ERROR) << "done"; + return 0; + })); + + EXPECT_CALL(*mock_transaction_manager_, ExecuteData) + .WillOnce(Invoke([&](const std::string& msg) { + LOG(ERROR) << "execute txn:" << msg; + EXPECT_EQ(msg, "transaction1"); + return nullptr; + })); + + EXPECT_CALL(replica_communicator_, SendMessage(_, 0)) + .WillRepeatedly( + Invoke([&](const google::protobuf::Message& msg, int64_t) { + Request request = *dynamic_cast(&msg); + if (request.type() == Request::TYPE_RESPONSE) { + LOG(ERROR) << "get response"; + commit_done.set_value(true); + } + return; + })); + + AddTransaction("transaction1"); + + commit_done_future.get(); +} + +} // namespace +} // namespace cassandra +} // namespace resdb diff --git a/platform/consensus/ordering/poe/proto/BUILD b/platform/consensus/ordering/poe/proto/BUILD new file mode 100644 index 000000000..8088db092 --- /dev/null +++ b/platform/consensus/ordering/poe/proto/BUILD @@ -0,0 +1,16 @@ +package(default_visibility = ["//platform/consensus/ordering/poe:__subpackages__"]) + +load("@rules_cc//cc:defs.bzl", "cc_proto_library") +load("@rules_proto//proto:defs.bzl", "proto_library") +load("@rules_proto_grpc//python:defs.bzl", "python_proto_library") + +proto_library( + name = "proposal_proto", + srcs = ["proposal.proto"], + #visibility = ["//visibility:public"], +) + +cc_proto_library( + name = "proposal_cc_proto", + deps = [":proposal_proto"], +) diff --git a/platform/consensus/ordering/poe/proto/proposal.proto b/platform/consensus/ordering/poe/proto/proposal.proto new file mode 100644 index 000000000..8302752ad --- /dev/null +++ b/platform/consensus/ordering/poe/proto/proposal.proto @@ -0,0 +1,28 @@ + +syntax = "proto3"; + +package resdb.poe; + +message Transaction{ + int32 id = 1; + bytes data = 2; + bytes hash = 3; + int32 proxy_id = 4; + int32 proposer = 5; + int64 uid = 6; + int64 create_time = 7; + int64 seq = 9; +} + +message Proposal { + bytes hash = 1; + int32 proposer = 2; + int64 seq =3 ; +} + +enum MessageType { + None = 0; + Propose = 1; + Prepare = 2; +} + diff --git a/platform/consensus/recovery/recovery.cpp b/platform/consensus/recovery/recovery.cpp index b61aa4766..fb1f6d50a 100644 --- a/platform/consensus/recovery/recovery.cpp +++ b/platform/consensus/recovery/recovery.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/recovery/recovery.h" diff --git a/platform/consensus/recovery/recovery.h b/platform/consensus/recovery/recovery.h index 743846bae..90f8fc99d 100644 --- a/platform/consensus/recovery/recovery.h +++ b/platform/consensus/recovery/recovery.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/consensus/recovery/recovery_test.cpp b/platform/consensus/recovery/recovery_test.cpp index f02cb9dff..a7cb1ef86 100644 --- a/platform/consensus/recovery/recovery_test.cpp +++ b/platform/consensus/recovery/recovery_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/consensus/recovery/recovery.h" @@ -112,7 +106,7 @@ TEST_F(RecoveryTest, ReadLog) { EXPECT_EQ(list.size(), expected_types.size()); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } } @@ -153,7 +147,7 @@ TEST_F(RecoveryTest, ReadLog_FlushOnce) { EXPECT_EQ(list.size(), expected_types.size()); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } } @@ -219,7 +213,7 @@ TEST_F(RecoveryTest, CheckPoint) { EXPECT_EQ(list.size(), types.size() * 14); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } } @@ -296,7 +290,7 @@ TEST_F(RecoveryTest, CheckPoint2) { EXPECT_EQ(list.size(), types.size() * 14); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } @@ -333,7 +327,7 @@ TEST_F(RecoveryTest, CheckPoint2) { EXPECT_EQ(list.size(), types.size() * 9); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } EXPECT_EQ(recovery.GetMinSeq(), 30); @@ -415,7 +409,7 @@ TEST_F(RecoveryTest, SystemInfo) { EXPECT_EQ(list.size(), types.size() * 14); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } @@ -455,7 +449,7 @@ TEST_F(RecoveryTest, SystemInfo) { EXPECT_EQ(data.primary_id(), 2); EXPECT_EQ(list.size(), types.size() * 9); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } EXPECT_EQ(recovery.GetMinSeq(), 30); diff --git a/platform/networkstrate/async_acceptor.cpp b/platform/networkstrate/async_acceptor.cpp index 0010a4a4d..387e98e53 100644 --- a/platform/networkstrate/async_acceptor.cpp +++ b/platform/networkstrate/async_acceptor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/networkstrate/async_acceptor.h" @@ -83,12 +77,14 @@ void AsyncAcceptor::Session::ReadDone() { delete recv_buffer_; } else { data_size_ = *reinterpret_cast(recv_buffer_); + /* if (data_size_ > 1e6) { LOG(ERROR) << "read data size:" << data_size_ << " data size:" << sizeof(data_size_) << " close socket"; Close(); return; } + */ } status_ ^= 1; recv_buffer_ = nullptr; diff --git a/platform/networkstrate/async_acceptor.h b/platform/networkstrate/async_acceptor.h index cde4893fa..26bc7ce44 100644 --- a/platform/networkstrate/async_acceptor.h +++ b/platform/networkstrate/async_acceptor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/networkstrate/async_acceptor_test.cpp b/platform/networkstrate/async_acceptor_test.cpp index 80ee4ba18..31d5ef3b0 100644 --- a/platform/networkstrate/async_acceptor_test.cpp +++ b/platform/networkstrate/async_acceptor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/networkstrate/async_acceptor.h" diff --git a/platform/networkstrate/async_replica_client.cpp b/platform/networkstrate/async_replica_client.cpp index f71f86d96..af13b7996 100644 --- a/platform/networkstrate/async_replica_client.cpp +++ b/platform/networkstrate/async_replica_client.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/networkstrate/async_replica_client.h" diff --git a/platform/networkstrate/async_replica_client.h b/platform/networkstrate/async_replica_client.h index 2555de8fa..64189c984 100644 --- a/platform/networkstrate/async_replica_client.h +++ b/platform/networkstrate/async_replica_client.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/networkstrate/async_replica_client_test.cpp b/platform/networkstrate/async_replica_client_test.cpp index f018c0a3b..b04c1c6d0 100644 --- a/platform/networkstrate/async_replica_client_test.cpp +++ b/platform/networkstrate/async_replica_client_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/networkstrate/async_replica_client.h" diff --git a/platform/networkstrate/consensus_manager.cpp b/platform/networkstrate/consensus_manager.cpp index 3e1d47251..fa9acbab5 100644 --- a/platform/networkstrate/consensus_manager.cpp +++ b/platform/networkstrate/consensus_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/networkstrate/consensus_manager.h" @@ -215,7 +209,7 @@ int ConsensusManager::ProcessHeartBeat(std::unique_ptr context, return -1; } - LOG(INFO) << "receive public size:" << hb_info.public_keys().size() + LOG(ERROR) << "receive public size:" << hb_info.public_keys().size() << " primary:" << hb_info.primary() << " version:" << hb_info.version() << " from region:" << request->region_info().region_id(); @@ -259,7 +253,7 @@ int ConsensusManager::ProcessHeartBeat(std::unique_ptr context, if (public_key.public_key_info().type() == CertificateKeyInfo::REPLICA) { replica_num++; if (!ReplicaExisted(info, replicas)) { - // AddNewReplica(info); + //AddNewReplica(info); } } else { if (!ReplicaExisted(info, clients_)) { @@ -337,6 +331,7 @@ std::unique_ptr ConsensusManager::GetReplicaClient( void ConsensusManager::AddNewReplica(const ReplicaInfo& info) {} void ConsensusManager::AddNewClient(const ReplicaInfo& info) { + std::unique_lock lk(mutex_); clients_.push_back(info); bc_client_->UpdateClientReplicas(clients_); } diff --git a/platform/networkstrate/consensus_manager.h b/platform/networkstrate/consensus_manager.h index c87d3ac6b..eb1e3ec33 100644 --- a/platform/networkstrate/consensus_manager.h +++ b/platform/networkstrate/consensus_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once @@ -106,6 +100,7 @@ class ConsensusManager : public ServiceInterface { }; private: + std::mutex mutex_; std::thread heartbeat_thread_; std::atomic is_ready_ = false; std::unique_ptr bc_client_; diff --git a/platform/networkstrate/consensus_manager_test.cpp b/platform/networkstrate/consensus_manager_test.cpp index 4b2f0b523..427b3d92e 100644 --- a/platform/networkstrate/consensus_manager_test.cpp +++ b/platform/networkstrate/consensus_manager_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/networkstrate/consensus_manager.h" diff --git a/platform/networkstrate/mock_async_replica_client.h b/platform/networkstrate/mock_async_replica_client.h index e31f9ccea..22f39afb3 100644 --- a/platform/networkstrate/mock_async_replica_client.h +++ b/platform/networkstrate/mock_async_replica_client.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/networkstrate/mock_replica_communicator.h b/platform/networkstrate/mock_replica_communicator.h index 79edb009e..dbcc64618 100644 --- a/platform/networkstrate/mock_replica_communicator.h +++ b/platform/networkstrate/mock_replica_communicator.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/networkstrate/mock_service_interface.h b/platform/networkstrate/mock_service_interface.h index 5d8c0f2e1..c3de6b8d0 100644 --- a/platform/networkstrate/mock_service_interface.h +++ b/platform/networkstrate/mock_service_interface.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/networkstrate/replica_communicator.cpp b/platform/networkstrate/replica_communicator.cpp index 9a07d614c..6b7f06e63 100644 --- a/platform/networkstrate/replica_communicator.cpp +++ b/platform/networkstrate/replica_communicator.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/networkstrate/replica_communicator.h" @@ -48,16 +42,7 @@ ReplicaCommunicator::ReplicaCommunicator( worker_threads_.push_back(std::thread([&]() { io_service_.run(); })); } } - - /* - for (const ReplicaInfo& info : replicas) { - std::string ip = info.ip(); - int port = info.port(); - auto client = std::make_unique( - &io_service_, ip, port + (is_use_long_conn_ ? 10000 : 0), true); - client_pools_[std::make_pair(ip, port)] = std::move(client); - } - */ + LOG(ERROR)<<" tcp batch:"<SendMessage(data) == 0) { ret++; } else { LOG(ERROR) << "send to:" << replica.ip() << " fail"; } + //LOG(ERROR) << "send to:" << replica.ip()<<" done"; } return ret; } diff --git a/platform/networkstrate/replica_communicator.h b/platform/networkstrate/replica_communicator.h index eb66c4fe7..87994770d 100644 --- a/platform/networkstrate/replica_communicator.h +++ b/platform/networkstrate/replica_communicator.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once @@ -43,7 +37,7 @@ class ReplicaCommunicator { ReplicaCommunicator(const std::vector& replicas, SignatureVerifier* verifier = nullptr, bool is_use_long_conn = false, int epoll_num = 1, - int tcp_batch = 100); + int tcp_batch = 1); virtual ~ReplicaCommunicator(); // HeartBeat message is used to broadcast public keys. diff --git a/platform/networkstrate/replica_communicator_test.cpp b/platform/networkstrate/replica_communicator_test.cpp index d21815c11..51013ff87 100644 --- a/platform/networkstrate/replica_communicator_test.cpp +++ b/platform/networkstrate/replica_communicator_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/networkstrate/replica_communicator.h" diff --git a/platform/networkstrate/server_comm.h b/platform/networkstrate/server_comm.h index 9fd3cd579..8eb43bfef 100644 --- a/platform/networkstrate/server_comm.h +++ b/platform/networkstrate/server_comm.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/networkstrate/service_interface.cpp b/platform/networkstrate/service_interface.cpp index 1a00676de..9379f3c47 100644 --- a/platform/networkstrate/service_interface.cpp +++ b/platform/networkstrate/service_interface.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/networkstrate/service_interface.h" diff --git a/platform/networkstrate/service_interface.h b/platform/networkstrate/service_interface.h index 0e3413641..4ebc84013 100644 --- a/platform/networkstrate/service_interface.h +++ b/platform/networkstrate/service_interface.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/networkstrate/service_network.cpp b/platform/networkstrate/service_network.cpp index 40cc29cea..fa5d3d4d7 100644 --- a/platform/networkstrate/service_network.cpp +++ b/platform/networkstrate/service_network.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/networkstrate/service_network.h" @@ -52,7 +46,7 @@ ServiceNetwork::ServiceNetwork(const ResDBConfig& config, acceptor_ = std::make_unique(config, &input_queue_); async_acceptor_ = std::make_unique( - config.GetSelfInfo().ip(), config_.GetSelfInfo().port() + 10000, + "0.0.0.0", config_.GetSelfInfo().port() + 10000, config.GetInputWorkerNum(), std::bind(&ServiceNetwork::AcceptorHandler, this, std::placeholders::_1, std::placeholders::_2)); @@ -77,8 +71,7 @@ void ServiceNetwork::AcceptorHandler(const char* buffer, size_t data_len) { std::unique_ptr item = std::make_unique(); item->socket = nullptr; item->data = std::move(sub_request_info); - // LOG(ERROR) << "receve data from acceptor:" << data.is_resp()<<" data - // len:"<data->data_len; + // LOG(ERROR) << "receve data from acceptor:" << data.is_resp()<<" data len:"<data->data_len; global_stats_->ServerCall(); input_queue_.Push(std::move(item)); } diff --git a/platform/networkstrate/service_network.h b/platform/networkstrate/service_network.h index d545e2694..c3844c09c 100644 --- a/platform/networkstrate/service_network.h +++ b/platform/networkstrate/service_network.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/networkstrate/service_network_test.cpp b/platform/networkstrate/service_network_test.cpp index 4b9deac1f..c92eddb57 100644 --- a/platform/networkstrate/service_network_test.cpp +++ b/platform/networkstrate/service_network_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/networkstrate/service_network.h" diff --git a/platform/proto/BUILD b/platform/proto/BUILD index 7b26b2abf..c19b351cd 100644 --- a/platform/proto/BUILD +++ b/platform/proto/BUILD @@ -19,7 +19,8 @@ proto_library( name = "replica_info_proto", srcs = ["replica_info.proto"], deps = [ - ":durable_proto", + "//chain/storage/proto:leveldb_config_proto", + "//chain/storage/proto:rocksdb_config_proto", "//common/proto:signature_info_proto", ], ) @@ -34,26 +35,15 @@ cc_proto_library( python_proto_library( name = "replica_info_py_proto", protos = [ - ":durable_proto", ":replica_info_proto", + "//chain/storage/proto:leveldb_config_proto", + "//chain/storage/proto:rocksdb_config_proto", ], deps = [ "//common/proto:signature_info_py_proto", ], ) -proto_library( - name = "durable_proto", - srcs = ["durable.proto"], -) - -cc_proto_library( - name = "durable_cc_proto", - deps = [ - ":durable_proto", - ], -) - proto_library( name = "resdb_proto", srcs = ["resdb.proto"], diff --git a/platform/proto/durable.proto b/platform/proto/durable.proto deleted file mode 100644 index 24823a021..000000000 --- a/platform/proto/durable.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; - -package resdb; - -message RocksDBInfo { - uint32 num_threads = 2; - uint32 write_buffer_size_mb = 3; - uint32 write_batch_size = 4; - string path = 5; - bool generate_unique_pathnames = 6; -} - -message LevelDBInfo { - uint32 write_buffer_size_mb = 2; - uint32 write_batch_size = 3; - string path = 4; - bool generate_unique_pathnames = 5; -} diff --git a/platform/proto/replica_info.proto b/platform/proto/replica_info.proto index ebfd53731..f9f2721cc 100644 --- a/platform/proto/replica_info.proto +++ b/platform/proto/replica_info.proto @@ -3,7 +3,8 @@ syntax = "proto3"; package resdb; import "common/proto/signature_info.proto"; -import "platform/proto/durable.proto"; +import "chain/storage/proto/leveldb_config.proto"; +import "chain/storage/proto/rocksdb_config.proto"; message ReplicaInfo { int64 id = 1; @@ -20,8 +21,8 @@ message RegionInfo { message ResConfigData{ repeated RegionInfo region = 1; int32 self_region_id = 2; - optional RocksDBInfo rocksdb_info = 3; - optional LevelDBInfo leveldb_info = 4; + optional storage.RocksDBInfo rocksdb_info = 3; + optional storage.LevelDBInfo leveldb_info = 4; optional bool enable_viewchange = 5; optional int32 view_change_timeout_ms = 10; optional bool not_need_signature = 6; // when delivering messages, it should be signed or not. @@ -44,6 +45,9 @@ message ResConfigData{ optional int32 max_client_complaint_num = 21; optional int32 duplicate_check_frequency_useconds = 22; + +// for fides failure. + optional int32 failure_num = 23; } message ReplicaStates { diff --git a/platform/proto/resdb.proto b/platform/proto/resdb.proto index b17b12404..ddc3be558 100644 --- a/platform/proto/resdb.proto +++ b/platform/proto/resdb.proto @@ -37,8 +37,9 @@ message Request { TYPE_VIEWCHANGE = 16; TYPE_NEWVIEW= 17; TYPE_CUSTOM_QUERY = 18; + TYPE_CUSTOM_CONSENSUS = 19; - NUM_OF_TYPE = 19; // the total number of types. + NUM_OF_TYPE = 20; // the total number of types. // Used to create the collector. }; int32 type = 1; @@ -62,6 +63,14 @@ message Request { int32 primary_id = 17; repeated bytes hashs = 18; repeated uint64 seqs = 19; + int32 user_type = 20; + int64 user_seq = 21; + int64 queuing_time = 22; + int64 uid = 23; + int64 create_time = 24; + int64 commit_time = 25; + + bytes encrypted_data = 26; } // The response message containing response diff --git a/platform/rdbc/acceptor.cpp b/platform/rdbc/acceptor.cpp index 0e07a1c1e..3410674b8 100644 --- a/platform/rdbc/acceptor.cpp +++ b/platform/rdbc/acceptor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/rdbc/acceptor.h" @@ -41,9 +35,9 @@ Acceptor::Acceptor(const ResDBConfig& config, input_queue_(input_queue) { socket_->SetRecvTimeout(1000000); // set 1s timeout. - LOG(ERROR) << "listen ip:" << config.GetSelfInfo().ip() + LOG(ERROR) << "listen ip:" << "0.0.0.0" << " port:" << config.GetSelfInfo().port(); - assert(socket_->Listen(config.GetSelfInfo().ip(), + assert(socket_->Listen("0.0.0.0", config.GetSelfInfo().port()) == 0); is_stop_ = false; global_stats_ = Stats::GetGlobalStats(); diff --git a/platform/rdbc/acceptor.h b/platform/rdbc/acceptor.h index 2ccc385e6..19ddb5700 100644 --- a/platform/rdbc/acceptor.h +++ b/platform/rdbc/acceptor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/statistic/prometheus_handler.cpp b/platform/statistic/prometheus_handler.cpp index eacadf54a..644f6a184 100644 --- a/platform/statistic/prometheus_handler.cpp +++ b/platform/statistic/prometheus_handler.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/statistic/prometheus_handler.h" diff --git a/platform/statistic/prometheus_handler.h b/platform/statistic/prometheus_handler.h index e7ceca5d7..b3a8b4d9f 100644 --- a/platform/statistic/prometheus_handler.h +++ b/platform/statistic/prometheus_handler.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/platform/statistic/set_random_data.cpp b/platform/statistic/set_random_data.cpp index a30d2cba4..0b936f585 100644 --- a/platform/statistic/set_random_data.cpp +++ b/platform/statistic/set_random_data.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include diff --git a/platform/statistic/stats.cpp b/platform/statistic/stats.cpp index f14ba9b3f..f84bd37ad 100644 --- a/platform/statistic/stats.cpp +++ b/platform/statistic/stats.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "platform/statistic/stats.h" @@ -109,6 +103,65 @@ void Stats::MonitorGlobal() { uint64_t last_total_request = 0, last_total_geo_request = 0, last_geo_request = 0; uint64_t time = 0; + + + uint64_t num_transactions = 0, num_consumed_transactions = 0; + uint64_t num_transactions_time = 0, num_consumed_transactions_time = 0; + uint64_t last_num_transactions = 0, last_num_consumed_transactions = 0; + uint64_t last_num_transactions_time = 0, last_num_consumed_transactions_time = 0; + + uint64_t queuing_num = 0, queuing_time = 0; + uint64_t last_queuing_num = 0, last_queuing_time = 0; + uint64_t round_num = 0, round_time = 0; + uint64_t last_round_num = 0, last_round_time = 0; + + uint64_t commit_num = 0, commit_time = 0; + uint64_t last_commit_num = 0, last_commit_time = 0; + + uint64_t verify_num = 0, verify_time = 0; + uint64_t last_verify_num = 0, last_verify_time = 0; + + uint64_t execute_queuing_num = 0, execute_queuing_time = 0; + uint64_t last_execute_queuing_num = 0, last_execute_queuing_time = 0; + + uint64_t execute_num = 0, execute_time = 0; + uint64_t last_execute_num = 0, last_execute_time = 0; + + uint64_t commit_running_num = 0, commit_running_time = 0; + uint64_t last_commit_running_num = 0, last_commit_running_time = 0; + + uint64_t commit_delay_num = 0, commit_delay_time = 0; + uint64_t last_commit_delay_num = 0, last_commit_delay_time = 0; + + uint64_t commit_waiting_num = 0, commit_waiting_time = 0; + uint64_t last_commit_waiting_num = 0, last_commit_waiting_time = 0; + + uint64_t execute_delay_num = 0, execute_delay_time = 0; + uint64_t last_execute_delay_num = 0, last_execute_delay_time = 0; + + uint64_t execute_prepare_num = 0, execute_prepare_time = 0; + uint64_t last_execute_prepare_num = 0, last_execute_prepare_time = 0; + + uint64_t commit_interval_num = 0, commit_interval_time = 0; + uint64_t last_commit_interval_num = 0, last_commit_interval_time = 0; + + uint64_t commit_ratio_num = 0, commit_ratio_time = 0; + uint64_t last_commit_ratio_num = 0, last_commit_ratio_time = 0; + + uint64_t commit_queuing_num = 0, commit_queuing_time = 0; + uint64_t last_commit_queuing_num = 0, last_commit_queuing_time = 0; + + uint64_t commit_round_num = 0, commit_round_time = 0; + uint64_t last_commit_round_num = 0, last_commit_round_time = 0; + + uint64_t commit_txn_num = 0, commit_txn_time = 0; + uint64_t last_commit_txn_num = 0, last_commit_txn_time = 0; + + uint64_t commit_block_num = 0, commit_block_time = 0; + uint64_t last_commit_block_num = 0, last_commit_block_time = 0; + + uint64_t block_size_num = 0, block_size = 0; + uint64_t last_block_size_num = 0, last_block_size = 0; while (!stop_) { sleep(monitor_sleep_time_); @@ -136,6 +189,66 @@ void Stats::MonitorGlobal() { run_req_num = run_req_num_; run_req_run_time = run_req_run_time_; + queuing_num = queuing_num_; + queuing_time = queuing_time_; + + round_num = round_num_; + round_time = round_time_; + + commit_num = commit_num_; + commit_time = commit_time_; + + execute_queuing_num = execute_queuing_num_; + execute_queuing_time = execute_queuing_time_; + + execute_num = execute_num_; + execute_time = execute_time_; + + commit_running_num = commit_running_num_; + commit_running_time = commit_running_time_; + + commit_delay_num = commit_delay_num_; + commit_delay_time = commit_delay_time_; + + commit_waiting_num = commit_waiting_num_; + commit_waiting_time = commit_waiting_time_; + + execute_prepare_num = execute_prepare_num_; + execute_prepare_time = execute_prepare_time_; + + execute_delay_num = execute_delay_num_; + execute_delay_time = execute_delay_time_; + + commit_interval_num = commit_interval_num_; + commit_interval_time = commit_interval_time_; + + commit_ratio_num = commit_ratio_num_; + commit_ratio_time = commit_ratio_time_; + + commit_queuing_num = commit_queuing_num_; + commit_queuing_time = commit_queuing_time_; + + commit_round_num = commit_round_num_; + commit_round_time = commit_round_time_; + + commit_txn_num = commit_txn_num_; + commit_txn_time = commit_txn_time_; + + commit_block_num = commit_block_num_; + commit_block_time = commit_block_time_; + + block_size_num = block_size_num_; + block_size = block_size_; + + verify_num = verify_num_; + verify_time = verify_time_; + + num_transactions = num_transactions_; + num_consumed_transactions = num_consumed_transactions_; + + num_transactions_time = num_transactions_time_; + num_consumed_transactions_time = num_consumed_transactions_time_; + LOG(ERROR) << "=========== monitor =========\n" << "server call:" << server_call - last_server_call << " server process:" << server_process - last_server_process @@ -183,13 +296,106 @@ void Stats::MonitorGlobal() { << " " "seq fail:" << seq_fail - last_seq_fail << " time:" << time + << " " + "new transactions:" + << (num_transactions - last_num_transactions ) + << " " + "consumed transactions:" + << (num_consumed_transactions - last_num_consumed_transactions) + << " queuing latency :" + << static_cast(queuing_time - + last_queuing_time) / + (queuing_num - last_queuing_num) / 1000000.0 + << " round latency :" + << static_cast(round_time - + last_round_time) / + (round_num - last_round_num) / 1000000.0 + << " commit latency :" + << static_cast(commit_time - + last_commit_time) / + (commit_num - last_commit_num) / 1000000.0 + + << " verify latency :" + << static_cast(verify_time - + last_verify_time) / + (verify_num - last_verify_num) / 1000000.0 + + << " execute_queuing latency :" + << static_cast(execute_queuing_time - + last_execute_queuing_time) / + (execute_queuing_num - last_execute_queuing_num) / 1000000.0 + + << " execute latency :" + << static_cast(execute_time - + last_execute_time) / + (execute_num - last_execute_num) / 1000000.0 + + << " commit_queuing latency :" + << static_cast(commit_queuing_time - + last_commit_queuing_time) / + (commit_queuing_num - last_commit_queuing_num) / 1000000.0 + + << " commit_running latency :" + << static_cast(commit_running_time - + last_commit_running_time) / + (commit_running_num - last_commit_running_num) / 1000000.0 + + << " commit_delay latency :" + << static_cast(commit_delay_time - + last_commit_delay_time) / + (commit_delay_num - last_commit_delay_num) / 1000000.0 + + << " commit_waiting latency :" + << static_cast(commit_waiting_time - + last_commit_waiting_time) / + (commit_waiting_num - last_commit_waiting_num) / 1000000.0 + + << " execute_prepare latency :" + << static_cast(execute_prepare_time - + last_execute_prepare_time) / + (execute_prepare_num - last_execute_prepare_num) / 1000000.0 + + << " execute_delay latency :" + << static_cast(execute_delay_time - + last_execute_delay_time) / + (execute_delay_num - last_execute_delay_num) / 1000000.0 + + << " commit_round latency :" + << static_cast(commit_round_time - + last_commit_round_time) / + (commit_round_num - last_commit_round_num) + + << " commit_interval latency :" + << static_cast(commit_interval_time - + last_commit_interval_time) / + (commit_interval_num - last_commit_interval_num) / 1000000.0 + + << " commit_txn latency :" + << static_cast(commit_txn_time - + last_commit_txn_time) / + (commit_txn_num - last_commit_txn_num) + + << " commit_block latency :" + << static_cast(commit_block_time - + last_commit_block_time) / + (commit_block_num - last_commit_block_num) + + << " block_size latency :" + << static_cast(block_size - + last_block_size) / + (block_size_num - last_block_size_num) + + << " commit_ratio latency :" + << static_cast(commit_ratio_time - + last_commit_ratio_time) / + (commit_ratio_num - last_commit_ratio_num) / 1000000.0 << " " "\n--------------- monitor ------------"; if (run_req_num - last_run_req_num > 0) { LOG(ERROR) << " req client latency:" << static_cast(run_req_run_time - last_run_req_run_time) / - (run_req_num - last_run_req_num) / 1000000000.0; + (run_req_num - last_run_req_num) / 1000000.0; } last_seq_fail = seq_fail; @@ -215,6 +421,63 @@ void Stats::MonitorGlobal() { last_total_request = total_request; last_total_geo_request = total_geo_request; last_geo_request = geo_request; + + last_num_transactions = num_transactions; + last_num_consumed_transactions = num_consumed_transactions; + + last_num_transactions_time = num_transactions_time; + last_num_consumed_transactions_time = num_consumed_transactions_time; + + last_queuing_num = queuing_num; + last_queuing_time = queuing_time; + + last_round_num = round_num; + last_round_time = round_time; + + last_commit_num = commit_num; + last_commit_time = commit_time; + + last_execute_queuing_num = execute_queuing_num; + last_execute_queuing_time = execute_queuing_time; + + last_execute_num = execute_num; + last_execute_time = execute_time; + + last_commit_running_num = commit_running_num; + last_commit_running_time = commit_running_time; + + last_commit_delay_num = commit_delay_num; + last_commit_delay_time = commit_delay_time; + + last_commit_waiting_num = commit_waiting_num; + last_commit_waiting_time = commit_waiting_time; + + last_execute_delay_num = execute_delay_num; + last_execute_delay_time = execute_delay_time; + + last_execute_prepare_num = execute_prepare_num; + last_execute_prepare_time = execute_prepare_time; + + last_commit_interval_num = commit_interval_num; + last_commit_interval_time = commit_interval_time; + + last_commit_ratio_num = commit_ratio_num; + last_commit_ratio_time = commit_ratio_time; + + last_commit_queuing_num = commit_queuing_num; + last_commit_queuing_time = commit_queuing_time; + + last_commit_round_num = commit_round_num; + last_commit_round_time = commit_round_time; + + last_commit_txn_num = commit_txn_num; + last_commit_txn_time = commit_txn_time; + + last_commit_block_num = commit_block_num; + last_commit_block_time = commit_block_time; + + last_verify_num = verify_num; + last_verify_time = verify_time; } } @@ -302,6 +565,14 @@ void Stats::ServerProcess() { server_process_++; } +void Stats::AddNewTransactions(int num) { + num_transactions_++; +} + +void Stats::ConsumeTransactions(int num) { + num_consumed_transactions_++; +} + void Stats::SeqGap(uint64_t seq_gap) { seq_gap_ = seq_gap; } void Stats::AddLatency(uint64_t run_time) { @@ -309,6 +580,97 @@ void Stats::AddLatency(uint64_t run_time) { run_req_run_time_ += run_time; } +void Stats::AddQueuingLatency(uint64_t run_time) { + queuing_num_++; + queuing_time_ += run_time; +} + +void Stats::AddRoundLatency(uint64_t run_time) { + round_num_++; + round_time_ += run_time; +} + +void Stats::AddCommitLatency(uint64_t run_time) { + commit_num_++; + commit_time_ += run_time; +} + +void Stats::AddVerifyLatency(uint64_t run_time) { + verify_num_++; + verify_time_ += run_time; +} + +void Stats::AddExecuteQueuingLatency(uint64_t run_time) { + execute_queuing_num_++; + execute_queuing_time_ += run_time; +} + +void Stats::AddExecuteLatency(uint64_t run_time) { + execute_num_++; + execute_time_ += run_time; +} + +void Stats::AddCommitQueuingLatency(uint64_t run_time) { + commit_queuing_num_++; + commit_queuing_time_ += run_time; +} + +void Stats::AddCommitRuntime(uint64_t run_time) { + commit_running_num_++; + commit_running_time_ += run_time; +} + +void Stats::AddCommitWaitingLatency(uint64_t run_time) { + commit_waiting_num_++; + commit_waiting_time_ += run_time; +} + +void Stats::AddCommitDelay(uint64_t run_time) { + commit_delay_num_++; + commit_delay_time_ += run_time; +} + +void Stats::AddExecutePrepareDelay(uint64_t run_time) { + execute_prepare_num_++; + execute_prepare_time_ += run_time; +} + +void Stats::AddCommitRoundLatency(uint64_t run_time) { + //LOG(ERROR)<<"commit round:"<(prometheus_address); } diff --git a/platform/statistic/stats.h b/platform/statistic/stats.h index cc95f2bcc..a07cbc207 100644 --- a/platform/statistic/stats.h +++ b/platform/statistic/stats.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once @@ -39,6 +33,24 @@ class Stats { void Stop(); void AddLatency(uint64_t run_time); + void AddQueuingLatency(uint64_t run_time); + void AddRoundLatency(uint64_t run_time); + void AddCommitLatency(uint64_t run_time); + void AddCommitQueuingLatency(uint64_t run_time); + void AddVerifyLatency(uint64_t run_time); + void AddExecuteQueuingLatency(uint64_t run_time); + void AddExecuteLatency(uint64_t run_time); + void AddCommitRuntime(uint64_t run_time); + void AddCommitRoundLatency(uint64_t run_time); + void AddCommitWaitingLatency(uint64_t run_time); + void AddCommitDelay(uint64_t run_time); + void AddExecutePrepareDelay(uint64_t run_time); + void AddCommitInterval(uint64_t run_time); + void AddCommitTxn(int num); + void AddCommitBlock(int num); + void AddBlockSize(int size); + void AddCommitRatio(uint64_t num); + void AddExecuteDelay(uint64_t run_time); void Monitor(); void MonitorGlobal(); @@ -69,6 +81,9 @@ class Stats { void ServerProcess(); void SetPrometheus(const std::string& prometheus_address); + void AddNewTransactions(int num); + void ConsumeTransactions(int num); + protected: Stats(int sleep_time = 5); ~Stats(); @@ -96,9 +111,26 @@ class Stats { std::atomic run_req_run_time_; std::atomic seq_gap_; std::atomic total_request_, total_geo_request_, geo_request_; + std::atomic num_transactions_, num_transactions_time_, num_consumed_transactions_, num_consumed_transactions_time_; + std::atomic queuing_num_, queuing_time_, round_num_, round_time_, commit_num_, commit_time_; + std::atomic execute_queuing_num_, execute_queuing_time_, verify_num_, verify_time_; + std::atomic execute_num_, execute_time_; + std::atomic commit_running_num_, commit_running_time_; + std::atomic commit_queuing_num_, commit_queuing_time_; + std::atomic commit_round_num_, commit_round_time_; + std::atomic commit_txn_num_, commit_txn_time_; + std::atomic commit_block_num_, commit_block_time_; + std::atomic commit_delay_num_, commit_delay_time_; + std::atomic commit_waiting_num_, commit_waiting_time_; + std::atomic execute_prepare_num_, execute_prepare_time_; + std::atomic commit_interval_num_, commit_interval_time_; + std::atomic block_size_num_, block_size_; + std::atomic commit_ratio_num_, commit_ratio_time_; + std::atomic execute_delay_num_, execute_delay_time_; int monitor_sleep_time_ = 5; // default 5s. std::unique_ptr prometheus_; + }; } // namespace resdb diff --git a/platform/test/resdb_test.cpp b/platform/test/resdb_test.cpp index 0152a0803..fca03a152 100644 --- a/platform/test/resdb_test.cpp +++ b/platform/test/resdb_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include @@ -109,7 +103,7 @@ class ResDBTest : public Test { void WaitExecutorDone(int received_num) { for (auto executor : executors_) { - while (executor->GetSeqs().size() < received_num) { + while (static_cast(executor->GetSeqs().size()) < received_num) { usleep(10000); } } diff --git a/proto/kv/kv.proto b/proto/kv/kv.proto index ce0d1d260..f07523fe8 100644 --- a/proto/kv/kv.proto +++ b/proto/kv/kv.proto @@ -7,16 +7,47 @@ message KVRequest { NONE = 0; SET = 1; GET = 2; - GETVALUES = 3; + GETALLVALUES = 3; GETRANGE = 4; + SET_WITH_VERSION = 5; + GET_WITH_VERSION = 6; + GET_ALL_ITEMS = 7; + GET_KEY_RANGE = 8; + GET_HISTORY = 9; + GET_TOP = 10; } CMD cmd = 1; string key = 2; bytes value = 3; + int32 version = 4; + // For get key range + string min_key = 5; + string max_key = 6; + // For get history for a key + int32 min_version = 7; + int32 max_version = 8; + // For top history + int32 top_number = 9; +} + +message ValueInfo { + bytes value = 2; + int32 version = 3; +} + +message Item { + string key = 1; + ValueInfo value_info = 2; +} + +message Items { + repeated Item item = 1; } message KVResponse { string key = 1; bytes value = 2; + ValueInfo value_info = 3; + Items items = 4; } diff --git a/scripts/deploy/README.md b/scripts/deploy/README.md index 585831cfd..bf8e54e31 100644 --- a/scripts/deploy/README.md +++ b/scripts/deploy/README.md @@ -4,7 +4,8 @@ This directory includes deployment scripts that help to deploy ResilientDB on mu ## Deploy KV Service -Add the IP addresses and the SSH key of the machines where you wish to deploy ResilientDB replicas and client proxy in the file [config/kv_server.conf](https://github.com/msadoghi/nexres/blob/master/deploy/config/kv_server.conf). +Add the IP addresses of the machines where you wish to deploy ResilientDB replicas and client proxy in the file [config/kv_server.conf](config/kv_server.conf). +Create the ssh key file in the config "config/key.conf" and put your ssh key there (See the [key_example.conf](config/key_example.conf) as an example). We recommend using private IP addresses of each machine. * If you do not require any SSH key to log in to a machine, then you would need to update the scripts. diff --git a/scripts/deploy/config/cassandra.config b/scripts/deploy/config/cassandra.config new file mode 100644 index 000000000..d452da24e --- /dev/null +++ b/scripts/deploy/config/cassandra.config @@ -0,0 +1,10 @@ +{ + "clientBatchNum": 1000, + "enable_viewchange": false, + "recovery_enabled": false, + "max_client_complaint_num":10, + "max_process_txn": 64, + "worker_num": 2, + "input_worker_num": 1, + "output_worker_num": 5 +} diff --git a/scripts/deploy/config/fair.config b/scripts/deploy/config/fair.config new file mode 100644 index 000000000..e2f76f257 --- /dev/null +++ b/scripts/deploy/config/fair.config @@ -0,0 +1,10 @@ +{ + "clientBatchNum": 1000, + "enable_viewchange": false, + "recovery_enabled": false, + "max_client_complaint_num":10, + "max_process_txn": 256, + "worker_num": 2, + "input_worker_num": 1, + "output_worker_num": 5 +} diff --git a/scripts/deploy/config/fides.config b/scripts/deploy/config/fides.config new file mode 100644 index 000000000..f940544e7 --- /dev/null +++ b/scripts/deploy/config/fides.config @@ -0,0 +1,11 @@ +{ + "clientBatchNum": 200, + "enable_viewchange": false, + "recovery_enabled": false, + "max_client_complaint_num":10, + "max_process_txn": 384, + "worker_num": 10, + "input_worker_num": 1, + "output_worker_num": 5, + "failure_num": 1 +} \ No newline at end of file diff --git a/scripts/deploy/config/kv_performance_server.conf b/scripts/deploy/config/kv_performance_server.conf index ef0a21cbc..7816268fc 100644 --- a/scripts/deploy/config/kv_performance_server.conf +++ b/scripts/deploy/config/kv_performance_server.conf @@ -1,9 +1,12 @@ iplist=( -172.31.23.110 -172.31.31.183 -172.31.22.246 -172.31.26.117 -172.31.21.196 +172.17.0.2 +172.17.0.3 +172.17.0.4 +172.17.0.5 +172.17.0.6 +172.17.0.7 +172.17.0.8 +172.17.0.9 ) -key=~/.ssh/junchao.pem +client_num=4 diff --git a/scripts/deploy/config/kv_performance_server_128.conf b/scripts/deploy/config/kv_performance_server_128.conf new file mode 100644 index 000000000..38109f207 --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_128.conf @@ -0,0 +1,262 @@ +iplist=( +172.31.25.224 +172.31.20.228 +172.31.18.224 +172.31.16.230 +172.31.31.229 +172.31.26.233 +172.31.29.231 +172.31.17.244 +172.31.17.236 +172.31.26.249 +172.31.18.247 +172.31.16.151 +172.31.31.151 +172.31.31.155 +172.31.17.155 +172.31.22.98 +172.31.19.156 +172.31.22.106 +172.31.24.98 +172.31.23.110 +172.31.27.109 +172.31.31.111 +172.31.28.110 +172.31.20.117 +172.31.30.116 +172.31.16.120 +172.31.28.119 +172.31.27.136 +172.31.20.133 +172.31.22.136 +172.31.26.136 +172.31.30.139 +172.31.21.137 +172.31.16.140 +172.31.26.139 +172.31.21.141 +172.31.27.140 +172.31.24.142 +172.31.31.142 +172.31.31.146 +172.31.19.145 +172.31.23.149 +172.31.30.149 +172.31.22.218 +172.31.17.214 +172.31.30.221 +172.31.24.220 +172.31.29.162 +172.31.24.221 +172.31.19.167 +172.31.21.166 +172.31.27.178 +172.31.18.177 +172.31.17.183 +172.31.21.179 +172.31.26.129 +172.31.16.190 +172.31.27.133 +172.31.29.133 +172.31.19.250 +172.31.27.250 +172.31.16.251 +172.31.26.250 +172.31.29.254 +172.31.21.252 +172.31.25.199 +172.31.23.195 +172.31.25.200 +172.31.28.199 +172.31.19.203 +172.31.28.201 +172.31.23.204 +172.31.26.203 +172.31.18.213 +172.31.19.208 +172.31.27.27 +172.31.17.24 +172.31.21.30 +172.31.25.29 +172.31.29.31 +172.31.21.54 +172.31.22.53 +172.31.27.60 +172.31.23.56 +172.31.25.63 +172.31.30.61 +172.31.27.2 +172.31.28.0 +172.31.26.4 +172.31.31.3 +172.31.20.8 +172.31.24.6 +172.31.23.21 +172.31.26.11 +172.31.29.23 +172.31.31.21 +172.31.25.82 +172.31.20.81 +172.31.25.87 +172.31.27.85 +172.31.26.93 +172.31.16.90 +172.31.24.94 +172.31.26.94 +172.31.19.95 +172.31.17.94 +172.31.30.44 +172.31.21.33 +172.31.26.47 +172.31.27.47 +172.31.26.50 +172.31.22.49 +172.31.19.122 +172.31.31.121 +172.31.24.127 +172.31.24.126 +172.31.21.65 +172.31.26.65 +172.31.29.70 +172.31.22.66 +172.31.19.72 +172.31.26.70 +172.31.22.74 +172.31.23.72 +172.31.27.76 +172.31.24.75 +172.31.19.81 +172.31.16.81 +172.31.47.249 +172.31.36.247 +172.31.40.246 +172.31.38.242 +172.31.46.241 +172.31.43.240 +172.31.34.239 +172.31.39.239 +172.31.33.198 +172.31.35.197 +172.31.39.194 +172.31.44.252 +172.31.42.252 +172.31.35.251 +172.31.47.251 +172.31.36.250 +172.31.35.223 +172.31.39.222 +172.31.44.219 +172.31.34.219 +172.31.32.217 +172.31.36.216 +172.31.32.212 +172.31.33.208 +172.31.39.186 +172.31.32.185 +172.31.38.183 +172.31.32.174 +172.31.41.172 +172.31.43.168 +172.31.39.167 +172.31.32.160 +172.31.43.146 +172.31.32.145 +172.31.33.135 +172.31.37.134 +172.31.42.132 +172.31.32.190 +172.31.36.190 +172.31.36.188 +172.31.36.97 +172.31.39.97 +172.31.35.97 +172.31.43.156 +172.31.47.155 +172.31.40.150 +172.31.44.149 +172.31.47.148 +172.31.36.111 +172.31.43.108 +172.31.39.107 +172.31.45.106 +172.31.34.104 +172.31.37.104 +172.31.37.102 +172.31.41.98 +172.31.43.121 +172.31.37.120 +172.31.43.119 +172.31.42.116 +172.31.37.116 +172.31.47.116 +172.31.34.115 +172.31.37.111 +172.31.47.231 +172.31.45.230 +172.31.39.230 +172.31.45.229 +172.31.40.228 +172.31.46.227 +172.31.38.227 +172.31.46.71 +172.31.45.71 +172.31.34.70 +172.31.40.68 +172.31.47.127 +172.31.32.127 +172.31.45.126 +172.31.47.125 +172.31.38.94 +172.31.39.90 +172.31.41.85 +172.31.47.85 +172.31.39.81 +172.31.42.76 +172.31.47.76 +172.31.32.75 +172.31.40.35 +172.31.46.35 +172.31.47.35 +172.31.40.34 +172.31.38.34 +172.31.45.33 +172.31.47.33 +172.31.39.95 +172.31.43.47 +172.31.40.47 +172.31.45.46 +172.31.34.43 +172.31.46.41 +172.31.38.41 +172.31.39.37 +172.31.38.36 +172.31.45.5 +172.31.38.3 +172.31.36.63 +172.31.44.53 +172.31.47.52 +172.31.35.49 +172.31.40.49 +172.31.34.49 +172.31.47.17 +172.31.46.15 +172.31.37.13 +172.31.38.13 +172.31.46.10 +172.31.35.9 +172.31.33.9 +172.31.38.7 +172.31.35.31 +172.31.34.30 +172.31.43.29 +172.31.47.28 +172.31.45.25 +172.31.44.22 +172.31.33.21 +172.31.47.19 +172.31.37.31 + +) + +key=~/.ssh/junchao.pem +client_num=128 diff --git a/scripts/deploy/config/kv_performance_server_128_small.conf b/scripts/deploy/config/kv_performance_server_128_small.conf new file mode 100644 index 000000000..05efa7071 --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_128_small.conf @@ -0,0 +1,261 @@ +iplist=( +172.31.25.224 +172.31.20.228 +172.31.18.224 +172.31.16.230 +172.31.31.229 +172.31.26.233 +172.31.29.231 +172.31.17.244 +172.31.17.236 +172.31.26.249 +172.31.18.247 +172.31.16.151 +172.31.31.151 +172.31.31.155 +172.31.17.155 +172.31.22.98 +172.31.19.156 +172.31.22.106 +172.31.24.98 +172.31.23.110 +172.31.27.109 +172.31.31.111 +172.31.28.110 +172.31.20.117 +172.31.30.116 +172.31.16.120 +172.31.28.119 +172.31.27.136 +172.31.20.133 +172.31.22.136 +172.31.26.136 +172.31.30.139 +172.31.21.137 +172.31.16.140 +172.31.26.139 +172.31.21.141 +172.31.27.140 +172.31.24.142 +172.31.31.142 +172.31.31.146 +172.31.19.145 +172.31.23.149 +172.31.30.149 +172.31.22.218 +172.31.17.214 +172.31.30.221 +172.31.24.220 +172.31.29.162 +172.31.24.221 +172.31.19.167 +172.31.21.166 +172.31.27.178 +172.31.18.177 +172.31.17.183 +172.31.21.179 +172.31.26.129 +172.31.16.190 +172.31.27.133 +172.31.29.133 +172.31.19.250 +172.31.27.250 +172.31.16.251 +172.31.26.250 +172.31.29.254 +172.31.21.252 +172.31.25.199 +172.31.23.195 +172.31.25.200 +172.31.28.199 +172.31.19.203 +172.31.28.201 +172.31.23.204 +172.31.26.203 +172.31.18.213 +172.31.19.208 +172.31.27.27 +172.31.17.24 +172.31.21.30 +172.31.25.29 +172.31.29.31 +172.31.21.54 +172.31.22.53 +172.31.27.60 +172.31.23.56 +172.31.25.63 +172.31.30.61 +172.31.27.2 +172.31.28.0 +172.31.26.4 +172.31.31.3 +172.31.20.8 +172.31.24.6 +172.31.23.21 +172.31.26.11 +172.31.29.23 +172.31.31.21 +172.31.25.82 +172.31.20.81 +172.31.25.87 +172.31.27.85 +172.31.26.93 +172.31.16.90 +172.31.24.94 +172.31.26.94 +172.31.19.95 +172.31.17.94 +172.31.30.44 +172.31.21.33 +172.31.26.47 +172.31.27.47 +172.31.26.50 +172.31.22.49 +172.31.19.122 +172.31.31.121 +172.31.24.127 +172.31.24.126 +172.31.21.65 +172.31.26.65 +172.31.29.70 +172.31.22.66 +172.31.19.72 +172.31.26.70 +172.31.22.74 +172.31.23.72 +172.31.27.76 +172.31.24.75 +172.31.19.81 +172.31.16.81 +172.31.35.29 +172.31.39.3 +172.31.37.1 +172.31.38.59 +172.31.41.56 +172.31.47.53 +172.31.46.47 +172.31.36.45 +172.31.44.45 +172.31.43.21 +172.31.40.17 +172.31.39.16 +172.31.34.14 +172.31.44.12 +172.31.44.8 +172.31.34.6 +172.31.33.5 +172.31.37.85 +172.31.42.84 +172.31.36.83 +172.31.47.82 +172.31.32.82 +172.31.46.80 +172.31.34.79 +172.31.32.79 +172.31.35.44 +172.31.42.39 +172.31.35.39 +172.31.34.37 +172.31.35.36 +172.31.41.32 +172.31.44.91 +172.31.43.89 +172.31.46.126 +172.31.41.120 +172.31.47.120 +172.31.41.118 +172.31.40.118 +172.31.43.116 +172.31.34.116 +172.31.47.111 +172.31.47.78 +172.31.44.75 +172.31.34.75 +172.31.35.72 +172.31.33.71 +172.31.41.71 +172.31.35.68 +172.31.47.64 +172.31.40.98 +172.31.36.158 +172.31.35.157 +172.31.33.156 +172.31.36.154 +172.31.32.153 +172.31.35.153 +172.31.45.153 +172.31.33.110 +172.31.47.108 +172.31.45.105 +172.31.45.104 +172.31.41.104 +172.31.41.101 +172.31.40.99 +172.31.43.98 +172.31.40.138 +172.31.46.137 +172.31.45.137 +172.31.43.132 +172.31.39.131 +172.31.33.131 +172.31.46.130 +172.31.34.129 +172.31.39.153 +172.31.37.152 +172.31.34.151 +172.31.43.148 +172.31.45.141 +172.31.39.140 +172.31.41.139 +172.31.35.139 +172.31.39.178 +172.31.39.177 +172.31.47.176 +172.31.37.176 +172.31.43.175 +172.31.33.173 +172.31.46.170 +172.31.33.169 +172.31.38.190 +172.31.35.188 +172.31.44.187 +172.31.38.185 +172.31.35.183 +172.31.39.182 +172.31.36.182 +172.31.43.179 +172.31.40.220 +172.31.37.219 +172.31.32.215 +172.31.46.215 +172.31.40.215 +172.31.42.214 +172.31.41.212 +172.31.39.207 +172.31.37.166 +172.31.34.163 +172.31.37.162 +172.31.43.162 +172.31.36.161 +172.31.39.160 +172.31.36.223 +172.31.44.221 +172.31.32.248 +172.31.41.246 +172.31.35.246 +172.31.44.245 +172.31.44.243 +172.31.43.235 +172.31.44.226 +172.31.42.206 +172.31.33.204 +172.31.45.199 +172.31.44.196 +172.31.35.194 +172.31.39.193 +172.31.36.254 +172.31.40.252 +) + +key=~/.ssh/junchao.pem +client_num=128 diff --git a/scripts/deploy/config/kv_performance_server_16.conf b/scripts/deploy/config/kv_performance_server_16.conf new file mode 100644 index 000000000..cc3def695 --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_16.conf @@ -0,0 +1,37 @@ +iplist=( +172.31.25.224 +172.31.20.228 +172.31.18.224 +172.31.16.230 +172.31.31.229 +172.31.26.233 +172.31.29.231 +172.31.17.244 +172.31.17.236 +172.31.26.249 +172.31.18.247 +172.31.16.151 +172.31.31.151 +172.31.31.155 +172.31.17.155 +172.31.22.98 +172.31.19.156 +172.31.22.106 +172.31.24.98 +172.31.23.110 +172.31.27.109 +172.31.31.111 +172.31.28.110 +172.31.20.117 +172.31.30.116 +172.31.16.120 +172.31.28.119 +172.31.27.136 +172.31.20.133 +172.31.22.136 +172.31.26.136 +172.31.30.139 +) + +key=~/.ssh/junchao.pem +client_num=16 diff --git a/scripts/deploy/config/kv_performance_server_16_2.conf b/scripts/deploy/config/kv_performance_server_16_2.conf new file mode 100644 index 000000000..e77ce5698 --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_16_2.conf @@ -0,0 +1,53 @@ +iplist=( +172.31.25.224 +172.31.20.228 +172.31.18.224 +172.31.16.230 +172.31.31.229 +172.31.26.233 +172.31.29.231 +172.31.17.244 +172.31.17.236 +172.31.26.249 +172.31.18.247 +172.31.16.151 +172.31.31.151 +172.31.31.155 +172.31.17.155 +172.31.22.98 +172.31.19.156 +172.31.22.106 +172.31.24.98 +172.31.23.110 +172.31.27.109 +172.31.31.111 +172.31.28.110 +172.31.20.117 +172.31.30.116 +172.31.16.120 +172.31.28.119 +172.31.27.136 +172.31.20.133 +172.31.22.136 +172.31.26.136 +172.31.30.139 +172.31.21.137 +172.31.16.140 +172.31.26.139 +172.31.21.141 +172.31.27.140 +172.31.24.142 +172.31.31.142 +172.31.31.146 +172.31.19.145 +172.31.23.149 +172.31.30.149 +172.31.22.218 +172.31.17.214 +172.31.30.221 +172.31.24.220 +172.31.29.162 +) + +key=~/.ssh/junchao.pem +client_num=32 diff --git a/scripts/deploy/config/kv_performance_server_32.conf b/scripts/deploy/config/kv_performance_server_32.conf new file mode 100644 index 000000000..7a428de10 --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_32.conf @@ -0,0 +1,69 @@ +iplist=( +172.31.25.224 +172.31.20.228 +172.31.18.224 +172.31.16.230 +172.31.31.229 +172.31.26.233 +172.31.29.231 +172.31.17.244 +172.31.17.236 +172.31.26.249 +172.31.18.247 +172.31.16.151 +172.31.31.151 +172.31.31.155 +172.31.17.155 +172.31.22.98 +172.31.19.156 +172.31.22.106 +172.31.24.98 +172.31.23.110 +172.31.27.109 +172.31.31.111 +172.31.28.110 +172.31.20.117 +172.31.30.116 +172.31.16.120 +172.31.28.119 +172.31.27.136 +172.31.20.133 +172.31.22.136 +172.31.26.136 +172.31.30.139 +172.31.21.137 +172.31.16.140 +172.31.26.139 +172.31.21.141 +172.31.27.140 +172.31.24.142 +172.31.31.142 +172.31.31.146 +172.31.19.145 +172.31.23.149 +172.31.30.149 +172.31.22.218 +172.31.17.214 +172.31.30.221 +172.31.24.220 +172.31.29.162 +172.31.24.221 +172.31.19.167 +172.31.21.166 +172.31.27.178 +172.31.18.177 +172.31.17.183 +172.31.21.179 +172.31.26.129 +172.31.16.190 +172.31.27.133 +172.31.29.133 +172.31.19.250 +172.31.27.250 +172.31.16.251 +172.31.26.250 +172.31.29.254 +) + +key=~/.ssh/junchao.pem +client_num=32 diff --git a/scripts/deploy/config/kv_performance_server_64.conf b/scripts/deploy/config/kv_performance_server_64.conf new file mode 100644 index 000000000..062b1c0e3 --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_64.conf @@ -0,0 +1,133 @@ +iplist=( +172.31.25.224 +172.31.20.228 +172.31.18.224 +172.31.16.230 +172.31.31.229 +172.31.26.233 +172.31.29.231 +172.31.17.244 +172.31.17.236 +172.31.26.249 +172.31.18.247 +172.31.16.151 +172.31.31.151 +172.31.31.155 +172.31.17.155 +172.31.22.98 +172.31.19.156 +172.31.22.106 +172.31.24.98 +172.31.23.110 +172.31.27.109 +172.31.31.111 +172.31.28.110 +172.31.20.117 +172.31.30.116 +172.31.16.120 +172.31.28.119 +172.31.27.136 +172.31.20.133 +172.31.22.136 +172.31.26.136 +172.31.30.139 +172.31.21.137 +172.31.16.140 +172.31.26.139 +172.31.21.141 +172.31.27.140 +172.31.24.142 +172.31.31.142 +172.31.31.146 +172.31.19.145 +172.31.23.149 +172.31.30.149 +172.31.22.218 +172.31.17.214 +172.31.30.221 +172.31.24.220 +172.31.29.162 +172.31.24.221 +172.31.19.167 +172.31.21.166 +172.31.27.178 +172.31.18.177 +172.31.17.183 +172.31.21.179 +172.31.26.129 +172.31.16.190 +172.31.27.133 +172.31.29.133 +172.31.19.250 +172.31.27.250 +172.31.16.251 +172.31.26.250 +172.31.29.254 +172.31.21.252 +172.31.25.199 +172.31.23.195 +172.31.25.200 +172.31.28.199 +172.31.19.203 +172.31.28.201 +172.31.23.204 +172.31.26.203 +172.31.18.213 +172.31.19.208 +172.31.27.27 +172.31.17.24 +172.31.21.30 +172.31.25.29 +172.31.29.31 +172.31.21.54 +172.31.22.53 +172.31.27.60 +172.31.23.56 +172.31.25.63 +172.31.30.61 +172.31.27.2 +172.31.28.0 +172.31.26.4 +172.31.31.3 +172.31.20.8 +172.31.24.6 +172.31.23.21 +172.31.26.11 +172.31.29.23 +172.31.31.21 +172.31.25.82 +172.31.20.81 +172.31.25.87 +172.31.27.85 +172.31.26.93 +172.31.16.90 +172.31.24.94 +172.31.26.94 +172.31.19.95 +172.31.17.94 +172.31.30.44 +172.31.21.33 +172.31.26.47 +172.31.27.47 +172.31.26.50 +172.31.22.49 +172.31.19.122 +172.31.31.121 +172.31.24.127 +172.31.24.126 +172.31.21.65 +172.31.26.65 +172.31.29.70 +172.31.22.66 +172.31.19.72 +172.31.26.70 +172.31.22.74 +172.31.23.72 +172.31.27.76 +172.31.24.75 +172.31.19.81 +172.31.16.81 +) + +key=~/.ssh/junchao.pem +client_num=64 diff --git a/scripts/deploy/config/kv_performance_server_8.conf b/scripts/deploy/config/kv_performance_server_8.conf new file mode 100644 index 000000000..a97d27ce2 --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_8.conf @@ -0,0 +1,21 @@ +iplist=( +172.31.25.224 +172.31.20.228 +172.31.18.224 +172.31.16.230 +172.31.31.229 +172.31.26.233 +172.31.29.231 +172.31.17.244 +172.31.17.236 +172.31.26.249 +172.31.18.247 +172.31.16.151 +172.31.31.151 +172.31.31.155 +172.31.17.155 +172.31.22.98 +) + +key=~/.ssh/junchao.pem +client_num=8 diff --git a/scripts/deploy/config/kv_performance_server_small_128.conf b/scripts/deploy/config/kv_performance_server_small_128.conf new file mode 100644 index 000000000..af9522d3b --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_small_128.conf @@ -0,0 +1,261 @@ +iplist=( +172.31.41.159 +172.31.37.96 +172.31.45.102 +172.31.41.102 +172.31.39.152 +172.31.43.155 +172.31.45.156 +172.31.45.157 +172.31.37.117 +172.31.45.118 +172.31.37.119 +172.31.39.120 +172.31.37.103 +172.31.45.103 +172.31.47.105 +172.31.37.115 +172.31.45.124 +172.31.33.126 +172.31.35.64 +172.31.37.65 +172.31.39.121 +172.31.37.121 +172.31.33.123 +172.31.45.123 +172.31.35.81 +172.31.37.83 +172.31.39.88 +172.31.43.89 +172.31.33.65 +172.31.47.70 +172.31.45.70 +172.31.39.77 +172.31.39.33 +172.31.35.34 +172.31.37.35 +172.31.33.40 +172.31.35.90 +172.31.41.91 +172.31.43.93 +172.31.41.93 +172.31.37.46 +172.31.45.50 +172.31.39.54 +172.31.47.58 +172.31.35.41 +172.31.45.42 +172.31.39.42 +172.31.41.44 +172.31.47.0 +172.31.39.0 +172.31.43.3 +172.31.37.12 +172.31.41.60 +172.31.47.60 +172.31.45.62 +172.31.33.0 +172.31.37.20 +172.31.47.24 +172.31.35.30 +172.31.43.30 +172.31.47.14 +172.31.45.15 +172.31.37.17 +172.31.45.19 +172.31.32.227 +172.31.40.229 +172.31.44.232 +172.31.44.234 +172.31.39.30 +172.31.43.31 +172.31.32.225 +172.31.38.225 +172.31.32.243 +172.31.34.243 +172.31.32.247 +172.31.40.252 +172.31.46.234 +172.31.40.235 +172.31.34.235 +172.31.32.242 +172.31.32.196 +172.31.32.201 +172.31.36.204 +172.31.36.208 +172.31.34.253 +172.31.34.254 +172.31.44.254 +172.31.40.193 +172.31.38.165 +172.31.36.172 +172.31.40.172 +172.31.32.173 +172.31.40.210 +172.31.34.212 +172.31.38.215 +172.31.46.216 +172.31.40.175 +172.31.38.176 +172.31.38.178 +172.31.34.128 +172.31.44.173 +172.31.38.173 +172.31.44.174 +172.31.42.174 +172.31.38.136 +172.31.36.141 +172.31.46.141 +172.31.42.147 +172.31.34.130 +172.31.40.130 +172.31.46.132 +172.31.32.135 +172.31.38.151 +172.31.32.151 +172.31.44.152 +172.31.40.153 +172.31.40.147 +172.31.42.149 +172.31.46.149 +172.31.32.150 +172.31.46.96 +172.31.34.98 +172.31.44.100 +172.31.46.102 +172.31.40.154 +172.31.38.156 +172.31.38.158 +172.31.36.159 +172.31.34.113 +172.31.46.113 +172.31.38.118 +172.31.40.119 +172.31.40.104 +172.31.42.105 +172.31.34.106 +172.31.36.106 +172.31.36.125 +172.31.46.69 +172.31.42.70 +172.31.44.72 +172.31.44.123 +172.31.40.124 +172.31.38.124 +172.31.36.124 +172.31.36.76 +172.31.40.77 +172.31.46.78 +172.31.44.78 +172.31.32.72 +172.31.44.73 +172.31.32.73 +172.31.32.74 +172.31.44.85 +172.31.38.86 +172.31.46.87 +172.31.36.88 +172.31.36.80 +172.31.36.82 +172.31.42.83 +172.31.32.84 +172.31.44.92 +172.31.34.92 +172.31.42.94 +172.31.32.95 +172.31.46.89 +172.31.34.90 +172.31.46.91 +172.31.34.91 +172.31.46.39 +172.31.40.39 +172.31.42.41 +172.31.44.46 +172.31.42.34 +172.31.38.35 +172.31.42.36 +172.31.38.39 +172.31.32.63 +172.31.46.0 +172.31.40.2 +172.31.38.2 +172.31.46.54 +172.31.32.55 +172.31.40.56 +172.31.34.57 +172.31.34.7 +172.31.42.12 +172.31.36.12 +172.31.34.16 +172.31.36.3 +172.31.42.3 +172.31.42.5 +172.31.38.5 +172.31.36.26 +172.31.42.27 +172.31.38.27 +172.31.42.28 +172.31.44.19 +172.31.38.20 +172.31.34.21 +172.31.32.23 +172.31.43.233 +172.31.47.235 +172.31.37.235 +172.31.39.236 +172.31.41.226 +172.31.47.229 +172.31.41.229 +172.31.47.230 +172.31.35.245 +172.31.33.246 +172.31.45.248 +172.31.41.252 +172.31.33.236 +172.31.45.238 +172.31.35.242 +172.31.47.242 +172.31.45.192 +172.31.47.199 +172.31.45.202 +172.31.35.203 +172.31.47.253 +172.31.45.253 +172.31.37.253 +172.31.35.255 +172.31.45.208 +172.31.43.218 +172.31.45.218 +172.31.47.222 +172.31.47.203 +172.31.45.204 +172.31.41.207 +172.31.47.207 +172.31.33.165 +172.31.43.171 +172.31.37.173 +172.31.39.174 +172.31.33.160 +172.31.33.162 +172.31.45.163 +172.31.37.164 +172.31.45.183 +172.31.41.184 +172.31.41.188 +172.31.43.131 +172.31.41.175 +172.31.45.178 +172.31.33.180 +172.31.33.181 +172.31.39.135 +172.31.47.135 +172.31.37.138 +172.31.45.149 +172.31.39.132 +172.31.35.132 +172.31.33.133 +172.31.41.134 +) + +key=~/.ssh/junchao.pem +client_num=128 diff --git a/scripts/deploy/config/kv_performance_server_small_16.conf b/scripts/deploy/config/kv_performance_server_small_16.conf new file mode 100644 index 000000000..ec34db0ad --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_small_16.conf @@ -0,0 +1,37 @@ +iplist=( +172.31.41.159 +172.31.37.96 +172.31.45.102 +172.31.41.102 +172.31.39.152 +172.31.43.155 +172.31.45.156 +172.31.45.157 +172.31.37.117 +172.31.45.118 +172.31.37.119 +172.31.39.120 +172.31.37.103 +172.31.45.103 +172.31.47.105 +172.31.37.115 +172.31.45.124 +172.31.33.126 +172.31.35.64 +172.31.37.65 +172.31.39.121 +172.31.37.121 +172.31.33.123 +172.31.45.123 +172.31.35.81 +172.31.37.83 +172.31.39.88 +172.31.43.89 +172.31.33.65 +172.31.47.70 +172.31.45.70 +172.31.39.77 +) + +key=~/.ssh/junchao.pem +client_num=16 diff --git a/scripts/deploy/config/kv_performance_server_small_32.conf b/scripts/deploy/config/kv_performance_server_small_32.conf new file mode 100644 index 000000000..88424ea58 --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_small_32.conf @@ -0,0 +1,69 @@ +iplist=( +172.31.41.159 +172.31.37.96 +172.31.45.102 +172.31.41.102 +172.31.39.152 +172.31.43.155 +172.31.45.156 +172.31.45.157 +172.31.37.117 +172.31.45.118 +172.31.37.119 +172.31.39.120 +172.31.37.103 +172.31.45.103 +172.31.47.105 +172.31.37.115 +172.31.45.124 +172.31.33.126 +172.31.35.64 +172.31.37.65 +172.31.39.121 +172.31.37.121 +172.31.33.123 +172.31.45.123 +172.31.35.81 +172.31.37.83 +172.31.39.88 +172.31.43.89 +172.31.33.65 +172.31.47.70 +172.31.45.70 +172.31.39.77 +172.31.39.33 +172.31.35.34 +172.31.37.35 +172.31.33.40 +172.31.35.90 +172.31.41.91 +172.31.43.93 +172.31.41.93 +172.31.37.46 +172.31.45.50 +172.31.39.54 +172.31.47.58 +172.31.35.41 +172.31.45.42 +172.31.39.42 +172.31.41.44 +172.31.47.0 +172.31.39.0 +172.31.43.3 +172.31.37.12 +172.31.41.60 +172.31.47.60 +172.31.45.62 +172.31.33.0 +172.31.37.20 +172.31.47.24 +172.31.35.30 +172.31.43.30 +172.31.47.14 +172.31.45.15 +172.31.37.17 +172.31.45.19 +) + +key=~/.ssh/junchao.pem +client_num=32 diff --git a/scripts/deploy/config/kv_performance_server_small_64.conf b/scripts/deploy/config/kv_performance_server_small_64.conf new file mode 100644 index 000000000..0a176d2ee --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_small_64.conf @@ -0,0 +1,133 @@ +iplist=( +172.31.41.159 +172.31.37.96 +172.31.45.102 +172.31.41.102 +172.31.39.152 +172.31.43.155 +172.31.45.156 +172.31.45.157 +172.31.37.117 +172.31.45.118 +172.31.37.119 +172.31.39.120 +172.31.37.103 +172.31.45.103 +172.31.47.105 +172.31.37.115 +172.31.45.124 +172.31.33.126 +172.31.35.64 +172.31.37.65 +172.31.39.121 +172.31.37.121 +172.31.33.123 +172.31.45.123 +172.31.35.81 +172.31.37.83 +172.31.39.88 +172.31.43.89 +172.31.33.65 +172.31.47.70 +172.31.45.70 +172.31.39.77 +172.31.39.33 +172.31.35.34 +172.31.37.35 +172.31.33.40 +172.31.35.90 +172.31.41.91 +172.31.43.93 +172.31.41.93 +172.31.37.46 +172.31.45.50 +172.31.39.54 +172.31.47.58 +172.31.35.41 +172.31.45.42 +172.31.39.42 +172.31.41.44 +172.31.47.0 +172.31.39.0 +172.31.43.3 +172.31.37.12 +172.31.41.60 +172.31.47.60 +172.31.45.62 +172.31.33.0 +172.31.37.20 +172.31.47.24 +172.31.35.30 +172.31.43.30 +172.31.47.14 +172.31.45.15 +172.31.37.17 +172.31.45.19 +172.31.32.227 +172.31.40.229 +172.31.44.232 +172.31.44.234 +172.31.39.30 +172.31.43.31 +172.31.32.225 +172.31.38.225 +172.31.32.243 +172.31.34.243 +172.31.32.247 +172.31.40.252 +172.31.46.234 +172.31.40.235 +172.31.34.235 +172.31.32.242 +172.31.32.196 +172.31.32.201 +172.31.36.204 +172.31.36.208 +172.31.34.253 +172.31.34.254 +172.31.44.254 +172.31.40.193 +172.31.38.165 +172.31.36.172 +172.31.40.172 +172.31.32.173 +172.31.40.210 +172.31.34.212 +172.31.38.215 +172.31.46.216 +172.31.40.175 +172.31.38.176 +172.31.38.178 +172.31.34.128 +172.31.44.173 +172.31.38.173 +172.31.44.174 +172.31.42.174 +172.31.38.136 +172.31.36.141 +172.31.46.141 +172.31.42.147 +172.31.34.130 +172.31.40.130 +172.31.46.132 +172.31.32.135 +172.31.38.151 +172.31.32.151 +172.31.44.152 +172.31.40.153 +172.31.40.147 +172.31.42.149 +172.31.46.149 +172.31.32.150 +172.31.46.96 +172.31.34.98 +172.31.44.100 +172.31.46.102 +172.31.40.154 +172.31.38.156 +172.31.38.158 +172.31.36.159 +) + +key=~/.ssh/junchao.pem +client_num=64 diff --git a/scripts/deploy/config/kv_performance_server_small_8.conf b/scripts/deploy/config/kv_performance_server_small_8.conf new file mode 100644 index 000000000..3a807201a --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_small_8.conf @@ -0,0 +1,20 @@ +iplist=( +172.31.41.159 +172.31.37.96 +172.31.45.102 +172.31.41.102 +172.31.39.152 +172.31.43.155 +172.31.45.156 +172.31.45.157 +172.31.37.117 +172.31.45.118 +172.31.37.119 +172.31.39.120 +172.31.37.103 +172.31.45.103 +172.31.47.105 +172.31.37.115 +) + +client_num=8 diff --git a/scripts/deploy/config/kv_performance_server_test_5.conf b/scripts/deploy/config/kv_performance_server_test_5.conf new file mode 100644 index 000000000..f064b8305 --- /dev/null +++ b/scripts/deploy/config/kv_performance_server_test_5.conf @@ -0,0 +1,10 @@ +iplist=( +172.31.66.2 +172.31.72.164 +172.31.73.238 +172.31.77.118 +172.31.74.248 +) + +key=~/.ssh/junchao.pem +client_num=1 diff --git a/scripts/deploy/config/kv_server.conf b/scripts/deploy/config/kv_server.conf index 8b5358b2c..a811f7681 100644 --- a/scripts/deploy/config/kv_server.conf +++ b/scripts/deploy/config/kv_server.conf @@ -6,4 +6,3 @@ iplist=( 172.31.57.186 ) -key=~/.ssh/your_key diff --git a/scripts/deploy/config/poe.config b/scripts/deploy/config/poe.config new file mode 100644 index 000000000..c5092a94c --- /dev/null +++ b/scripts/deploy/config/poe.config @@ -0,0 +1,10 @@ +{ + "clientBatchNum": 100, + "enable_viewchange": false, + "recovery_enabled": false, + "max_client_complaint_num":10, + "max_process_txn": 32, + "worker_num": 2, + "input_worker_num": 1, + "output_worker_num": 10 +} diff --git a/scripts/deploy/config/rcc.config b/scripts/deploy/config/rcc.config new file mode 100644 index 000000000..eec20b8c8 --- /dev/null +++ b/scripts/deploy/config/rcc.config @@ -0,0 +1,10 @@ +{ + "clientBatchNum": 1000, + "enable_viewchange": false, + "recovery_enabled": false, + "max_client_complaint_num":10, + "max_process_txn": 32, + "worker_num": 30, + "input_worker_num": 1, + "output_worker_num": 10 +} diff --git a/scripts/deploy/config/template.config b/scripts/deploy/config/template.config new file mode 100644 index 000000000..9f66f5289 --- /dev/null +++ b/scripts/deploy/config/template.config @@ -0,0 +1,10 @@ +{ + "clientBatchNum": 800, + "enable_viewchange": false, + "recovery_enabled": false, + "max_client_complaint_num":10, + "max_process_txn": 512, + "worker_num": 16, + "input_worker_num": 5, + "output_worker_num": 5 +} diff --git a/scripts/deploy/config/tusk.config b/scripts/deploy/config/tusk.config new file mode 100644 index 000000000..f940544e7 --- /dev/null +++ b/scripts/deploy/config/tusk.config @@ -0,0 +1,11 @@ +{ + "clientBatchNum": 200, + "enable_viewchange": false, + "recovery_enabled": false, + "max_client_complaint_num":10, + "max_process_txn": 384, + "worker_num": 10, + "input_worker_num": 1, + "output_worker_num": 5, + "failure_num": 1 +} \ No newline at end of file diff --git a/scripts/deploy/manage_alicloud_instance.sh b/scripts/deploy/manage_alicloud_instance.sh new file mode 100755 index 000000000..857c1afd4 --- /dev/null +++ b/scripts/deploy/manage_alicloud_instance.sh @@ -0,0 +1,314 @@ +#!/bin/bash + +# Sample: ./manage_alicloud_instance.sh new wan 8 write run shutdown + +# function: distribute the total number +distribute_evenly() { + local total=$1 + local listsize=$2 + + local base_value=$((total / listsize)) + local remainder=$((total % listsize)) + + # 初始化数组并分配 + for ((i = 0; i < listsize; i++)); do + if ((i < remainder)); then + echo $((base_value + 1)) + else + echo $base_value + fi + done +} + +rearrange_ips() { + local ip_list=("$@") # 所有 IP 地址列表 + local amount_list=("${!#}") # 最后一个参数是以空格分隔的 amount_list + IFS=' ' read -r -a amount_list <<< "$amount_list" + + # 初始化子列表 + local sublists=() + local start=0 + for amount in "${amount_list[@]}"; do + sublists+=("$(IFS=','; echo "${ip_list[@]:$start:$amount}")") + start=$((start + amount)) + done + + # 获取最大 region 长度 + local max_amount=${amount_list[0]} + for amount in "${amount_list[@]}"; do + if [[ $amount -gt $max_amount ]]; then + max_amount=$amount + fi + done + + # 轮流排序 IP + local final_ips=() + for i in $(seq 0 $((max_amount - 1))); do + for j in "${!sublists[@]}"; do + local region_ips=(${sublists[$j]//,/ }) + if [[ $i -lt ${#region_ips[@]} ]]; then + final_ips+=("${region_ips[$i]}") + fi + done + done + + echo "${final_ips[@]}" # 返回排序后的 IP 列表 +} + +mode=$1 +shift +network=$1 +shift +amount=$1 +shift +listsize=0 +echo $mode, $network + +region_list=('eu-central-1' 'us-west-1' 'ap-southeast-1' 'me-east-1') +imageid_list=('m-gw8atjzmmv35esf7t0ol' 'm-rj9hvjdzwmn5hszxi7rl' 'm-t4n9apvlakv21suofn9c' 'm-eb32jb9t0l0fabyiuswx') +zoneid_list=('eu-central-1a' 'us-west-1a' 'ap-southeast-1a' 'me-east-1a') +instance_type_list=('ecs.e-c1m4.large' 'ecs.e-c1m4.large' 'ecs.e-c1m4.large' 'ecs.g6.large') +security_groupid_list=('sg-gw882198cp93dc3he2pp' 'sg-rj91tgsgh70v6v1y0sqw' 'sg-t4ngrbld64k3fls433bj' 'sg-eb32jb9t0l0f9u76i0n0') +vpc_list=('vpc-gw87tw2ohh8amcdkvoeci' 'vpc-rj9jfm8myo5eug7gbbi31' 'vpc-t4nskgim87ibkhz04y4up' 'vpc-eb3nl8lrg1jh792ahzzny') +vswich_list=('vsw-gw818gr9injn3xq6wqvhv' 'vsw-rj9uoqiwyrorgxnrfr7tc' 'vsw-t4ny2ave4421x41cicpah' 'vsw-eb3ge3h2j2s0rsqwaigcy') +disk_cata_list=('cloud_auto' 'cloud_auto' 'cloud_auto' 'cloud_essd') + +listsize=${#region_list[@]} + +amount_list=($(distribute_evenly $amount $listsize)) + +if [[ $mode == "new" ]]; then + if [[ $network == "lan" ]]; then + region='cn-hongkong' + imageid='m-j6c7k48y8pips9b3gark' + zoneid='cn-hongkong-b' + instance_type='ecs.g7t.large' + security_groupid='sg-j6c983lbmrcoilavm6vf' + vswichid='vsw-j6ctft5mb2zny49xzub9j' + + aliyun ecs RunInstances \ + --RegionId $region \ + --ImageId $imageid \ + --ZoneId $zoneid \ + --InstanceType $instance_type \ + --SecurityGroupId $security_groupid \ + --VSwitchId $vswichid \ + --InstanceName 'shaokang-fides-instance' \ + --InternetMaxBandwidthIn 100 \ + --InternetMaxBandwidthOut 100 \ + --HostName 'fides-instance' \ + --UniqueSuffix true \ + --InternetChargeType 'PayByTraffic' \ + --SystemDisk.Size 80 \ + --SystemDisk.Category cloud_auto \ + --Tag.1.Key name \ + --Tag.1.Value 'fides-instance' \ + --Amount $amount + + echo "sleep 60" + sleep 60 + + elif [[ $network == "wan" ]]; then + + + # 遍历每个区域的配置并运行实例 + for ((i = 0; i < listsize; i++)); do + region=${region_list[i]} + imageid=${imageid_list[i]} + zoneid=${zoneid_list[i]} + instance_type=${instance_type_list[i]} + security_groupid=${security_groupid_list[i]} + vswichid=${vswich_list[i]} + amount=${amount_list[i]} + disk_cata=${disk_cata_list[i]} + + echo "$region, $imageid, $zoneid, $instance_type, $security_groupid, $vswichid, $amount" + + aliyun ecs RunInstances \ + --RegionId "$region" \ + --ImageId "$imageid" \ + --ZoneId "$zoneid" \ + --InstanceType "$instance_type" \ + --SecurityGroupId "$security_groupid" \ + --VSwitchId "$vswichid" \ + --InstanceName 'shaokang-fides-instance' \ + --InternetMaxBandwidthIn 100 \ + --InternetMaxBandwidthOut 100 \ + --HostName 'fides-instance' \ + --UniqueSuffix true \ + --InternetChargeType 'PayByTraffic' \ + --SystemDisk.Size 80 \ + --SystemDisk.Category "$disk_cata" \ + --Tag.1.Key name \ + --Tag.1.Value 'fides-instance' \ + --Amount $amount + + # wait for some time + sleep 0.5 + done + + echo "sleep 60" + sleep 60 + fi +fi + + +# Describe Instances +instance_ids=() +public_ips=() +private_ips=() + +need_describe=false + +for arg in "$@"; do + if [[ "$arg" == "shutdown" || "$arg" == "write" ]]; then + need_describe=true + break + fi +done + +if [[ "$need_describe" == true ]]; then + echo Need Describe. + + if [[ $network == "lan" ]]; then + + data=$(aliyun ecs DescribeInstances \ + --region cn-hongkong \ + --Tag.1.Key name \ + --Tag.1.Value fides-instance \ + --MaxResults 100 \ + --output cols=InstanceId,PublicIpAddress,VpcAttributes.PrivateIpAddress rows=Instances.Instance[]) + # --output cols=InstanceId,InstanceName,PublicIpAddress,VpcAttributes.PrivateIpAddress rows=Instances.Instance[]) + # echo $info + + # Sample return data + # data="InstanceId | PublicIpAddress | VpcAttributes.PrivateIpAddress ---------- | --------------- | ------------------------------ i-j6c48395f9rus4psiw7y | map[IpAddress:[47.242.8.123]] | map[IpAddress:[172.18.218.174]] i-j6c48395f9rus4psiw7z | map[IpAddress:[47.242.220.33]] | map[IpAddress:[172.18.218.173]] i-j6c48395f9rus4psiw7x | map[IpAddress:[47.242.222.206]] | map[IpAddress:[172.18.218.175]]" + + # Replace 'i-' into '\n' + formatted_data=$(echo "$data" | sed 's/i-/\ni-/g') + + # Iterate each row. + while read -r line; do + instance_id=$(echo "$line" | awk -F '|' '{print $1}' | xargs) + instance_ids+=("$instance_id") + public_ip=$(echo "$line" | awk -F '|' '{print $2}' | sed 's/.*IpAddress:\[\(.*\)\].*/\1/' | sed 's/]//g' | xargs) + public_ips+=("$public_ip") + private_ip=$(echo "$line" | awk -F '|' '{print $3}' | sed 's/.*IpAddress:\[\(.*\)\].*/\1/' | sed 's/]//g' | xargs) + private_ips+=("$private_ip") + # echo "$instance_id, $public_ip, $private_ip" + done <<< "$(echo "$formatted_data" | grep 'i-')" + + echo "Instance IDs: ${instance_ids[@]}" + echo "Public IPs: ${public_ips[@]}" + echo "Private IPs: ${private_ips[@]}" + + elif [[ $network == "wan" ]]; then + for region in "${region_list[@]}"; do + data=$(aliyun ecs DescribeInstances \ + --region $region \ + --Tag.1.Key name \ + --Tag.1.Value fides-instance \ + --MaxResults 100 \ + --output cols=InstanceId,PublicIpAddress,VpcAttributes.PrivateIpAddress rows=Instances.Instance[]) + echo $data + # Replace 'i-' into '\n' + formatted_data=$(echo "$data" | sed 's/i-/\ni-/g') + + # Iterate each row. + while read -r line; do + instance_id=$(echo "$line" | awk -F '|' '{print $1}' | xargs) + instance_ids+=("$instance_id") + public_ip=$(echo "$line" | awk -F '|' '{print $2}' | sed 's/.*IpAddress:\[\(.*\)\].*/\1/' | sed 's/]//g' | xargs) + public_ips+=("$public_ip") + private_ip=$(echo "$line" | awk -F '|' '{print $3}' | sed 's/.*IpAddress:\[\(.*\)\].*/\1/' | sed 's/]//g' | xargs) + private_ips+=("$private_ip") + done <<< "$(echo "$formatted_data" | grep 'i-')" + done + + echo "Instance IDs: ${instance_ids[@]}" + echo "Public IPs: ${public_ips[@]}" + echo "Private IPs: ${private_ips[@]}" + fi + +fi + +# public_ips=(11 12 13 21 22 23 31 32 41 42) + +if [[ $1 == "write" ]]; then + shift + # 定义文件名 + output_file="config/kv_performance_server.conf" + client_num=$(( ${#instance_ids[@]} / 2 )) + # 写入到文件中 + final_ips=() + if [[ $network == "wan" ]]; then + final_ips=($(rearrange_ips "${public_ips[@]}" "${amount_list[*]}")) + elif [[ $network == "lan" ]]; then + final_ips=("${private_ips[@]}") + fi + { + echo "iplist=(" + for ip in "${final_ips[@]}"; do + echo "$ip" + done + echo ")" + echo "" + echo "client_num=$client_num" + } > "$output_file" + + # 显示生成的文件内容 + cat "$output_file" +fi + +if [[ $1 == "run" ]]; then + shift + if [[ $network == "lan" ]]; then + # bash ./start_evaluation.sh simulate + bash ./start_evaluation.sh sgx + elif [[ $network == "wan" ]]; then + bash ./start_evaluation.sh simulate + fi +fi + + + +if [[ $1 == "shutdown" ]]; then + # Form a delete command containing all the instance_ids. + # Sample: + # aliyun ecs DeleteInstances \ + # --region cn-hongkong \ + # --InstanceId.1 i-1 \ + # --InstanceId.2 i-2 \ + # --Force true + + if [[ $network == "lan" ]]; then + counter=1 + delete_command="aliyun ecs DeleteInstances --region cn-hongkong" + for instance_id in "${instance_ids[@]}"; do + delete_command="$delete_command --InstanceId.$counter $instance_id" + ((counter++)) + done + delete_command="$delete_command --Force true" + echo $delete_command + $delete_command + elif [[ $network == "wan" ]]; then + echo shutdown in wan + instance_index=0 + for ((i = 0; i < listsize; i++)); do + if [[ ${amount_list[$i]} -gt 0 ]]; then + counter=1 + delete_command="aliyun ecs DeleteInstances --region ${region_list[$i]}" + # for instance_id in "${instance_ids[@]}"; do + + for ((j = 0; j < ${amount_list[$i]}; j++)); do + delete_command="$delete_command --InstanceId.$counter ${instance_ids[$instance_index]}" + ((counter++)) + ((instance_index++)) + done + delete_command="$delete_command --Force true" + echo $delete_command + $delete_command + fi + done + fi +fi \ No newline at end of file diff --git a/scripts/deploy/performance/calculate_result.py b/scripts/deploy/performance/calculate_result.py index 5fa595980..04f418d90 100644 --- a/scripts/deploy/performance/calculate_result.py +++ b/scripts/deploy/performance/calculate_result.py @@ -1,6 +1,23 @@ -import sys +# 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. +import sys +total = 0 def read_tps(file): tps = [] lat = [] @@ -8,36 +25,127 @@ def read_tps(file): for l in f.readlines(): s = l.split() for r in s: - if(r.split(':')[0] == 'txn'): - tps.append(int(r.split(':')[1])) + try: + if(r.split(':')[0] == 'txn'): + tps.append(int(r.split(':')[1])) + except: + print("s:",s) if l.find("client latency") > 0: + print("get lat:",s) lat.append(float(s[-1].split(':')[-1])) return tps, lat -def cal_tps(tps): +def cal_tps(tps, tot): tps_sum = [] tps_max = 0 for v in tps: if v == 0: continue + if v < 1000: + continue tps_max = max(tps_max, v) tps_sum.append(v) + tps_sum.sort() + # tps_sum = tps_sum[1:-1] + # tps_sum = tps_sum[tot:-tot] + print("tsp:",tps_sum) print("max throughput:",tps_max) print("average throughput:",sum(tps_sum)/len(tps_sum)) + return tps_max, sum(tps_sum)/len(tps_sum) def cal_lat(lat): lat_sum = [] lat_max = 0 for v in lat: - if v == 0: + if v <= 0: continue lat_max = max(lat_max, v) lat_sum.append(v) print("max latency:",lat_max) print("average latency:",sum(lat_sum)/len(lat_sum)) + return lat_max, sum(lat_sum)/len(lat_sum) + +def read_breakdown(file): + queueing=[] # queuing latency + receive_proposal=[] # execute_prepare latency + verify_proposal=[] # verify latency + + commit=[] # commit latency + + commit_runtime=[] # commit_running + execute_queueing=[] # execute_queuing + execute=[] # execute latency + + commit_round=[] # how many round needed for commit. commit_round latency + + with open(file) as f: + for line in f: + if "queuing latency" in line: + lat=parse_latency(line, "queuing latency") + if (lat != float('nan') and lat>0.0): + queueing.append(lat) + if "execute_prepare latency" in line: + lat=parse_latency(line, "execute_prepare latency") + if (lat != float('nan') and lat>0.0): + receive_proposal.append(lat) + if "verify latency" in line: + lat=parse_latency(line, "verify latency") + if (lat != float('nan') and lat>0.0): + verify_proposal.append(lat) + if "commit latency" in line: + lat=parse_latency(line, "commit latency") + if (lat != float('nan') and lat>0.0): + commit.append(lat) + if "commit_running latency" in line: + lat=parse_latency(line, "commit_running latency") + if (lat != float('nan') and lat>0.0): + commit_runtime.append(lat) + if "execute_queuing latency" in line: + lat=parse_latency(line, "execute_queuing latency") + if (lat != float('nan') and lat>0.0): + execute_queueing.append(lat) + if "execute latency" in line: + lat=parse_latency(line, "execute latency") + if (lat != float('nan') and lat>0.0): + execute.append(lat) + if "commit_round latency" in line: + lat=parse_latency(line, "commit_round latency") + if (lat != float('nan') and lat>0.0): + commit_round.append(lat) + + return { + "queueing": queueing, + "receive_proposal": receive_proposal, + "verify_proposal": verify_proposal, + "commit": commit, + "commit_runtime": commit_runtime, + "execute_queueing": execute_queueing, + "execute": execute, + "commit_round": commit_round, + } + +def parse_latency(line, key): + """Extract latency value from a log line based on a key.""" + try: + return float(line.split(f"{key} :")[1].split()[0]) + except (IndexError, ValueError): + return None + +def analyze_breakdown(data): + """Analyze breakdown data: calculate average and max latencies.""" + for key, values in data.items(): + if values: + avg = sum(values) / len(values) + max_val = max(values) + min_val = min(values) + print(f"{key}: min = {min_val:.6f}, max = {max_val:.6f}, avg = {avg:.6f}") + else: + print(f"{key}: No data available.") + + if __name__ == '__main__': files = sys.argv[1:] @@ -46,10 +154,36 @@ def cal_lat(lat): tps = [] lat = [] + breakdown_data = { + "queueing": [], + "receive_proposal": [], + "verify_proposal": [], + "commit_runtime": [], + "commit": [], + "execute_queueing": [], + "execute": [], + "commit_round": [], + } + total = len(files) for f in files: t, l=read_tps(f) tps += t lat += l - cal_tps(tps) - cal_lat(lat) + # Read breakdown data + breakdown = read_breakdown(f) + for key in breakdown_data: + breakdown_data[key].extend(breakdown[key]) + + + # Analyze breakdown data + print("\nBreakdown Analysis:") + analyze_breakdown(breakdown_data) + + print() + max_tps, avg_tps = cal_tps(tps, len(files)) + max_lat, avg_lat = cal_lat(lat) + + print("max throughput:{} average throughput:{} " + "max latency:{} average latency:{} " + "replica num:{}".format(max_tps, avg_tps, max_lat, avg_lat, total)) diff --git a/scripts/deploy/performance/cassandra_performance.sh b/scripts/deploy/performance/cassandra_performance.sh new file mode 100755 index 000000000..a461f6dbb --- /dev/null +++ b/scripts/deploy/performance/cassandra_performance.sh @@ -0,0 +1,4 @@ +export server=//benchmark/protocols/cassandra:kv_server_performance +export TEMPLATE_PATH=$PWD/config/cassandra.config + +./performance/run_performance.sh $* diff --git a/scripts/deploy/performance/fair_performance.sh b/scripts/deploy/performance/fair_performance.sh new file mode 100755 index 000000000..fb0535efe --- /dev/null +++ b/scripts/deploy/performance/fair_performance.sh @@ -0,0 +1,4 @@ +export server=//benchmark/protocols/fairdag:kv_server_performance +export TEMPLATE_PATH=$PWD/config/fair.config + +./performance/run_performance.sh $* diff --git a/scripts/deploy/performance/fides_performance.sh b/scripts/deploy/performance/fides_performance.sh new file mode 100755 index 000000000..826c7fc81 --- /dev/null +++ b/scripts/deploy/performance/fides_performance.sh @@ -0,0 +1,5 @@ +export server=//benchmark/protocols/fides:kv_server_performance +export TEMPLATE_PATH=$PWD/config/fides.config + +./performance/run_performance.sh $* + diff --git a/scripts/deploy/performance/hs_performance.sh b/scripts/deploy/performance/hs_performance.sh new file mode 100755 index 000000000..94417439c --- /dev/null +++ b/scripts/deploy/performance/hs_performance.sh @@ -0,0 +1,49 @@ +export server=//benchmark/protocols/hs:kv_server_performance + +./script/deploy.sh $1 + +. ./script/load_config.sh $1 + +server_name=`echo "$server" | awk -F':' '{print $NF}'` +server_bin=${server_name} + +bazel run //benchmark/protocols/pbft:kv_service_tools + +for((i=1;;i++)) +do +config_file=$PWD/config_out/client${i}.config +if [ ! -f "$config_file" ]; then + break; +fi +echo "get cofigfile:"$config_file +/root/nexres/bazel-bin/benchmark/protocols/pbft/kv_service_tools $config_file +done + +sleep 60 + +echo "benchmark done" +count=1 +for ip in ${iplist[@]}; +do +`ssh $ssh_options_cloud -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "killall -9 ${server_bin}"` +((count++)) +done + +while [ $count -gt 0 ]; do + wait $pids + count=`expr $count - 1` +done + + +echo "getting results" +for ip in ${iplist[@]}; +do + echo "scp -i ${key} root@${ip}:/root/${server_bin}.log ./${ip}_log" + `scp -i ${key} root@${ip}:/root/${server_bin}.log result_${ip}_log` +done + +python3 performance/calculate_result.py `ls result_*_log` > results.log + +rm -rf result_*_log +echo "save result to results.log" +cat results.log diff --git a/scripts/deploy/performance/ooohs_performance.sh b/scripts/deploy/performance/ooohs_performance.sh new file mode 100755 index 000000000..eb74144a1 --- /dev/null +++ b/scripts/deploy/performance/ooohs_performance.sh @@ -0,0 +1,50 @@ +export server=//benchmark/protocols/ooo_hs:kv_server_performance + +./script/deploy.sh $1 + +. ./script/load_config.sh $1 + +server_name=`echo "$server" | awk -F':' '{print $NF}'` +server_bin=${server_name} + + +bazel run //benchmark/protocols/pbft:kv_service_tools + +for((i=1;;i++)) +do +config_file=$PWD/config_out/client${i}.config +if [ ! -f "$config_file" ]; then + break; +fi +echo "get cofigfile:"$config_file +/root/nexres/bazel-bin/benchmark/protocols/pbft/kv_service_tools $config_file +done + +sleep 60 + +echo "benchmark done" +count=1 +for ip in ${iplist[@]}; +do +`ssh $ssh_options_cloud -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "killall -9 ${server_bin}"` +((count++)) +done + +while [ $count -gt 0 ]; do + wait $pids + count=`expr $count - 1` +done + + +echo "getting results" +for ip in ${iplist[@]}; +do + echo "scp -i ${key} root@${ip}:/root/${server_bin}.log ./${ip}_log" + `scp -i ${key} root@${ip}:/root/${server_bin}.log result_${ip}_log` +done + +python3 performance/calculate_result.py `ls result_*_log` > results.log + +rm -rf result_*_log +echo "save result to results.log" +cat results.log diff --git a/scripts/deploy/performance/poe_performance.sh b/scripts/deploy/performance/poe_performance.sh new file mode 100755 index 000000000..3fd671290 --- /dev/null +++ b/scripts/deploy/performance/poe_performance.sh @@ -0,0 +1,6 @@ +export server=//benchmark/protocols/poe:kv_server_performance +export TEMPLATE_PATH=$PWD/config/poe.config +#export COPTS="--define enable_leveldb=True" +#export COPTS="-pg" + +./performance/run_performance.sh $* diff --git a/scripts/deploy/performance/rcc_performance.sh b/scripts/deploy/performance/rcc_performance.sh new file mode 100755 index 000000000..0602a8ef1 --- /dev/null +++ b/scripts/deploy/performance/rcc_performance.sh @@ -0,0 +1,6 @@ +export server=//benchmark/protocols/rcc:kv_server_performance +export TEMPLATE_PATH=$PWD/config/rcc.config +#export COPTS="--define enable_leveldb=True" +#export COPTS="-pg" + +./performance/run_performance.sh $* diff --git a/scripts/deploy/performance/run_performance.sh b/scripts/deploy/performance/run_performance.sh index 68bc9c26b..76749d466 100755 --- a/scripts/deploy/performance/run_performance.sh +++ b/scripts/deploy/performance/run_performance.sh @@ -1,4 +1,4 @@ -export server=//benchmark/protocols/pbft:kv_server_performance +#export COPTS="--define enable_leveldb=True" ./script/deploy.sh $1 @@ -7,30 +7,50 @@ export server=//benchmark/protocols/pbft:kv_server_performance server_name=`echo "$server" | awk -F':' '{print $NF}'` server_bin=${server_name} -bazel run //benchmark/protocols/pbft:kv_service_tools -- $PWD/config_out/client.config +bazel run //benchmark/protocols/pbft:kv_service_tools + +for((i=1;;i++)) +do +config_file=$PWD/config_out/client${i}.config +if [ ! -f "$config_file" ]; then + break; +fi +echo "get cofigfile:"$config_file +../../bazel-bin/benchmark/protocols/pbft/kv_service_tools $config_file +done sleep 60 +# for ip in ${iplist[@]}; +# do +# ssh $ssh_options_cloud -p 22 -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "tc qdisc del dev eth0 root" & +# done +# wait + + echo "benchmark done" count=1 for ip in ${iplist[@]}; do -`ssh -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no ubuntu@${ip} "killall -9 ${server_bin}"` +`ssh $ssh_options_cloud -p 2222 -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "killall -9 ${server_bin}"` & +# `ssh $ssh_options_cloud -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "killall -9 ${server_bin}"` ((count++)) done +wait -while [ $count -gt 0 ]; do - wait $pids - count=`expr $count - 1` -done - +# while [ $count -gt 0 ]; do +# wait $pids +# count=`expr $count - 1` +# done echo "getting results" for ip in ${iplist[@]}; do - echo "scp -i ${key} ubuntu@${ip}:/home/ubuntu/${server_bin}.log ./${ip}_log" - `scp -i ${key} ubuntu@${ip}:/home/ubuntu/${server_bin}.log result_${ip}_log` + # echo "scp $ssh_options_cloud -i ${key} root@${ip}:/root/${server_bin}.log ./${ip}_log" + `scp $ssh_options_cloud -P 2222 -i ${key} root@${ip}:/root/${server_bin}.log result_${ip}_log` & + # `scp $ssh_options_cloud -i ${key} root@${ip}:/root/${server_bin}.log result_${ip}_log` done +wait python3 performance/calculate_result.py `ls result_*_log` > results.log diff --git a/scripts/deploy/poe_performance.sh b/scripts/deploy/poe_performance.sh new file mode 100755 index 000000000..0602a8ef1 --- /dev/null +++ b/scripts/deploy/poe_performance.sh @@ -0,0 +1,6 @@ +export server=//benchmark/protocols/rcc:kv_server_performance +export TEMPLATE_PATH=$PWD/config/rcc.config +#export COPTS="--define enable_leveldb=True" +#export COPTS="-pg" + +./performance/run_performance.sh $* diff --git a/scripts/deploy/script/deploy.sh b/scripts/deploy/script/deploy.sh index 87ab7dc92..12b7e7a58 100755 --- a/scripts/deploy/script/deploy.sh +++ b/scripts/deploy/script/deploy.sh @@ -8,9 +8,15 @@ set -e script_path=${BAZEL_WORKSPACE_PATH}/scripts -if [[ -z $server ]]; +echo "server is: $server" + +if [[ -z $server ]]; then + server=//service/kv:kv_service +fi + +if [[ -z $client_num ]]; then -server=//service/kv:kv_service +client_num=1 fi # obtain the src path @@ -18,7 +24,8 @@ server_path=`echo "$server" | sed 's/:/\//g'` server_path=${server_path:1} server_name=`echo "$server" | awk -F':' '{print $NF}'` server_bin=${server_name} -grafna_port=8090 +enclave_path=${BAZEL_WORKSPACE_PATH}/enclave/sgxcode/build/enclave/enclave.signed +#grafna_port=8090 bin_path=${BAZEL_WORKSPACE_PATH}/bazel-bin/${server_path} output_path=${script_path}/deploy/config_out @@ -39,6 +46,7 @@ echo "server name:"${server_bin} echo "admin config path:"${admin_key_path} echo "output path:"${output_path} echo "deploy to :"${deploy_iplist[@]} +echo "client num :"${client_num} # generate keys and certificates. @@ -46,10 +54,10 @@ cd ${script_path} echo "where am i:"$PWD deploy/script/generate_key.sh ${BAZEL_WORKSPACE_PATH} ${output_key_path} ${#iplist[@]} -deploy/script/generate_config.sh ${BAZEL_WORKSPACE_PATH} ${output_key_path} ${output_cert_path} ${output_path} ${admin_key_path} ${deploy_iplist[@]} +deploy/script/generate_config.sh ${BAZEL_WORKSPACE_PATH} ${output_key_path} ${output_cert_path} ${output_path} ${admin_key_path} ${client_num} ${deploy_iplist[@]} # build kv server -bazel build ${server} +bazel build ${server} if [ $? != 0 ] then @@ -62,7 +70,8 @@ function run_cmd(){ count=1 for ip in ${deploy_iplist[@]}; do - ssh -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no ubuntu@${ip} "$1" & + ssh $ssh_options_cloud -p 2222 -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "$1" & + # ssh $ssh_options_cloud -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "$1" & ((count++)) done @@ -73,11 +82,13 @@ function run_cmd(){ } function run_one_cmd(){ - ssh -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no ubuntu@${ip} "$1" + ssh $ssh_options_cloud -p 2222 -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "$1" + # ssh $ssh_options_cloud -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "$1" } run_cmd "killall -9 ${server_bin}" -run_cmd "rm -rf ${server_bin}; rm ${server_bin}*.log; rm -rf server.config; rm -rf cert;" +run_cmd "rm -rf ${server_bin}; rm ${server_bin}*.log; rm -rf server.config; rm -rf cert; rm -rf wal_log" +#run_cmd "rm -rf ${server_bin}; rm -rf server.config;" sleep 1 @@ -86,14 +97,23 @@ echo "upload configs" count=0 for ip in ${deploy_iplist[@]}; do - scp -i ${key} -r ${bin_path} ${output_path}/server.config ${output_path}/cert ubuntu@${ip}:/home/ubuntu/ & + # scp -i ${key} -r ${bin_path} ${output_path}/server.config ${output_path}/cert ${enclave_path} root@${ip}:/root/ > null 2>&1 & + scp $ssh_options_cloud -P 2222 -i ${key} -r ${bin_path} ${output_path}/server.config ${output_path}/cert ${enclave_path} root@${ip}:/root/ > null 2>&1 & + # scp $ssh_options_cloud -i ${key} -r ${bin_path} ${output_path}/server.config ${output_path}/cert ${enclave_path} root@${ip}:/root/ > null 2>&1 & ((count++)) done +wait -while [ $count -gt 0 ]; do - wait $pids - count=`expr $count - 1` -done +# while [ $count -gt 0 ]; do +# wait $pids +# count=`expr $count - 1` +# done + +# for ip in ${deploy_iplist[@]}; +# do +# ssh $ssh_options_cloud -p 22 -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "tc qdisc add dev eth0 root netem delay 40ms 0ms" & +# done +# wait echo "start to run" # Start server @@ -103,16 +123,20 @@ for ip in ${deploy_iplist[@]}; do private_key="cert/node_"${idx}".key.pri" cert="cert/cert_"${idx}".cert" - run_one_cmd "nohup ./${server_bin} server.config ${private_key} ${cert} ${grafna_port} > ${server_bin}.log 2>&1 &" & + enclave="./enclave.signed" + echo "nohup ./${server_bin} server.config ${private_key} ${cert} ${enclave} --simulate" + run_one_cmd "nohup ./${server_bin} server.config ${private_key} ${cert} ${enclave} --simulate > ~/${server_bin}.log 2>&1 &" & ((count++)) ((idx++)) done +wait -while [ $count -gt 0 ]; do - wait $pids - count=`expr $count - 1` -done +# while [ $count -gt 0 ]; do +# wait $pids +# count=`expr $count - 1` +# done +echo "Check ready logs" # Check ready logs idx=1 for ip in ${deploy_iplist[@]}; @@ -120,7 +144,9 @@ do resp="" while [ "$resp" = "" ] do - resp=`ssh -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no ubuntu@${ip} "grep \"receive public size:${#iplist[@]}\" ${server_bin}.log"` + # echo ssh $ssh_options_cloud -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "grep \"receive public size:${#iplist[@]}\" ${server_bin}.log" + resp=`ssh $ssh_options_cloud -p 2222 -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "grep \"receive public size:${#iplist[@]}\" ${server_bin}.log"` + # resp=`ssh $ssh_options_cloud -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no root@${ip} "grep \"receive public size:${#iplist[@]}\" ${server_bin}.log"` if [ "$resp" = "" ]; then sleep 1 fi diff --git a/scripts/deploy/script/env.sh b/scripts/deploy/script/env.sh index 8b03b76b5..71fee1d58 100755 --- a/scripts/deploy/script/env.sh +++ b/scripts/deploy/script/env.sh @@ -3,6 +3,8 @@ set +e CURRENT_PATH=$PWD +ssh_options_cloud='-o StrictHostKeyChecking=no -o LogLevel=ERROR -o UserKnownHostsFile=/dev/null -o ServerAliveInterval=60' + i=0 while [ ! -f "WORKSPACE" ] do diff --git a/scripts/deploy/script/generate_config.sh b/scripts/deploy/script/generate_config.sh index 8f3db7625..b396c00fb 100755 --- a/scripts/deploy/script/generate_config.sh +++ b/scripts/deploy/script/generate_config.sh @@ -3,7 +3,7 @@ key_path=$1; shift output_cert_path=$1; shift output_path=$1; shift admin_key_path=$1; shift - +client_num=$1; shift iplist=$@ echo "generage certificates" @@ -12,19 +12,30 @@ echo "base path:"$base_path echo "key path:"$key_path echo "output cert path:"$output_cert_path echo "output path:"$output_path -echo "admin_key_path:"$admin_key_path +echo "admin_key_path?:"$admin_key_path +echo "tempalte path:",${TEMPLATE_PATH} + +if [ "${TEMPLATE_PATH}" = "" ] +then + TEMPLATE_PATH="../config/template.config" +fi + +echo "tempalte path:",${TEMPLATE_PATH} cd ${output_path} ADMIN_PRIVATE_KEY=${admin_key_path}/admin.key.pri ADMIN_PUBLIC_KEY=${admin_key_path}/admin.key.pub + + + CERT_TOOLS_BIN=${base_path}/bazel-bin/tools/certificate_tools CONFIG_TOOLS_BIN=${base_path}/bazel-bin/tools/generate_region_config -USERNAME=ubuntu -BASE_PORT=17000 -CLIENT_NUM=1 +USERNAME=root +BASE_PORT=10000 +CLIENT_NUM=${client_num} echo "" > client.config echo "" > server.config @@ -40,7 +51,7 @@ do done echo "node num:"$tot - +client_idx=1 for ip in ${iplist[@]}; do port=$((${BASE_PORT}+${idx})) @@ -52,6 +63,8 @@ do if [ $(($idx+$CLIENT_NUM)) -gt $tot ] ; then $CERT_TOOLS_BIN ${output_cert_path} ${ADMIN_PRIVATE_KEY} ${ADMIN_PUBLIC_KEY} ${public_key} ${idx} ${ip} ${port} client echo "${idx} ${ip} ${port}" >> client.config + echo "${idx} ${ip} ${port}" >> client${client_idx}.config + client_idx=$((client_idx+1)) else $CERT_TOOLS_BIN ${output_cert_path} ${ADMIN_PRIVATE_KEY} ${ADMIN_PUBLIC_KEY} ${public_key} ${idx} ${ip} ${port} replica echo "${idx} ${ip} ${port}" >> server.config @@ -60,5 +73,5 @@ do idx=$(($idx+1)) done -python3 ${CONFIG_TOOLS_BIN} ./server.config ./server.config.json +python3 ${CONFIG_TOOLS_BIN} ./server.config ./server.config.json ${TEMPLATE_PATH} mv server.config.json server.config diff --git a/scripts/deploy/script/load_config.sh b/scripts/deploy/script/load_config.sh index ff9ceaccc..85abfddda 100755 --- a/scripts/deploy/script/load_config.sh +++ b/scripts/deploy/script/load_config.sh @@ -1,2 +1,8 @@ - +KEY_FILE="config/key.conf" . $1 + +if [ ! -f "${KEY_FILE}" ]; then +"please create \"${KEY_FILE}\" and put your ssh key in it" +exit -1 +fi +. ${KEY_FILE} diff --git a/scripts/deploy/script/prepare.sh b/scripts/deploy/script/prepare.sh new file mode 100755 index 000000000..eff024677 --- /dev/null +++ b/scripts/deploy/script/prepare.sh @@ -0,0 +1,20 @@ +#export COPTS="--define enable_leveldb=True" + +ssh_options_cloud='-o StrictHostKeyChecking=no -o LogLevel=ERROR -o UserKnownHostsFile=/dev/null -o ServerAliveInterval=60' + + +#!/bin/bash +eval "$(cat $1)" + +echo "IP List:" +for ip in "${iplist[@]}"; do + echo "$ip" +done + +for ip in ${iplist[@]}; +do + ssh $ssh_options_cloud -p 2222 root@$ip 'echo "deb http://security.ubuntu.com/ubuntu focal-security main" | sudo tee -a /etc/apt/sources.list && sudo apt update && sudo apt install openssl=1.1.1f-1ubuntu2.22 --allow-downgrades -y' & + # ssh $ssh_options_cloud root@$ip 'echo "deb http://security.ubuntu.com/ubuntu focal-security main" | sudo tee -a /etc/apt/sources.list && sudo apt update && sudo apt install openssl=1.1.1f-1ubuntu2.22 --allow-downgrades -y' & +done +wait + diff --git a/scripts/deploy/start_evaluation.sh b/scripts/deploy/start_evaluation.sh new file mode 100755 index 000000000..398f229b1 --- /dev/null +++ b/scripts/deploy/start_evaluation.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +ssh_options_cloud='-o StrictHostKeyChecking=no -o LogLevel=ERROR -o UserKnownHostsFile=/dev/null -o ServerAliveInterval=60' + + +# cat < config/kv_performance_server.conf + +# iplist=( +# 172.17.0.2 +# 172.18.218.170 +# ) + +# client_num=1 +# EOF + +source config/kv_performance_server.conf + +echo "IP List:" +for ip in "${iplist[@]}"; do + echo "$ip" +done + +# for ip in ${iplist[@]}; +# do +# ssh $ssh_options_cloud root@$ip 'wget http://nz2.archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb && sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb' & +# # ssh $ssh_options_cloud root@$ip "sudo ip addr add $ip/32 dev eth0" & +# # echo "sudo ip addr add $ip/32 dev eth0" +# # ssh $ssh_options_cloud root@$ip 'echo "deb http://security.ubuntu.com/ubuntu focal-security main" | sudo tee -a /etc/apt/sources.list && sudo apt update && sudo apt install openssl=1.1.1f-1ubuntu2.22 --allow-downgrades -y' & +# done +# wait + +mode=$1 +if [[ "$mode" != "sgx" && "$mode" != "simulate" ]]; then + echo "Invalid mode. Please specify 'sgx' or 'simulate'." + exit 1 +fi + +deploy_file='./script/deploy.sh' +if [[ "$mode" == "sgx" ]]; then + if grep -q '${enclave} --simulate' "$deploy_file"; then + sed -i 's/${enclave} --simulate/${enclave}/g' "$deploy_file" + fi +else + if ! grep -q '${enclave} --simulate' "$deploy_file"; then + sed -i 's/${enclave}/${enclave} --simulate/g' "$deploy_file" + fi +fi + +./performance/fides_performance.sh config/kv_performance_server.conf +# ./performance/run_performance.sh config/kv_performance_server.conf + + + +# ldconfig /usr/local/lib64/ -> +# libssl.so.3: cannot open shared object file: No such file or directory +# apt-get install linux-headers-$(uname -r) diff --git a/scripts/null b/scripts/null new file mode 100644 index 000000000..e69de29bb diff --git a/service/contract/contract_service.cpp b/service/contract/contract_service.cpp index 22833c27b..73826af9d 100644 --- a/service/contract/contract_service.cpp +++ b/service/contract/contract_service.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include diff --git a/service/kv/BUILD b/service/kv/BUILD index eed3f0be8..56b45ae16 100644 --- a/service/kv/BUILD +++ b/service/kv/BUILD @@ -6,8 +6,8 @@ cc_binary( name = "kv_service", srcs = ["kv_service.cpp"], copts = select({ - "//executor/kv:enable_leveldb_setting": ["-DENABLE_LEVELDB"], - "//executor/kv:enable_rocksdb_setting": ["-DENABLE_ROCKSDB"], + "//chain/storage/setting:enable_leveldb_setting": ["-DENABLE_LEVELDB"], + "//chain/storage/setting:enable_rocksdb_setting": ["-DENABLE_ROCKSDB"], "//conditions:default": [], }), deps = [ @@ -15,11 +15,11 @@ cc_binary( "//executor/kv:kv_executor", "//service/utils:server_factory", "//common:comm", - "//chain/state:chain_state", "//proto/kv:kv_cc_proto", + "//chain/storage:memory_db", ] + select({ - "//executor/kv:enable_leveldb_setting": ["//storage:res_leveldb"], - "//executor/kv:enable_rocksdb_setting": ["//storage:res_rocksdb"], + "//chain/storage/setting:enable_leveldb_setting": ["//chain/storage:leveldb"], + "//chain/storage/setting:enable_rocksdb_setting": ["//chain/storage:rocksdb"], "//conditions:default": [], }), ) diff --git a/service/kv/kv_service.cpp b/service/kv/kv_service.cpp index 2ab9d5ff4..3f283419b 100644 --- a/service/kv/kv_service.cpp +++ b/service/kv/kv_service.cpp @@ -1,64 +1,57 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include -#include "chain/state/chain_state.h" +#include "chain/storage/memory_db.h" #include "executor/kv/kv_executor.h" #include "platform/config/resdb_config_utils.h" #include "platform/statistic/stats.h" #include "service/utils/server_factory.h" #ifdef ENABLE_LEVELDB -#include "chain/storage/res_leveldb.h" +#include "chain/storage/leveldb.h" #endif #ifdef ENABLE_ROCKSDB -#include "chain/storage/res_rocksdb.h" +#include "chain/storage/rocksdb.h" #endif using namespace resdb; +using namespace resdb::storage; void ShowUsage() { printf(" [logging_dir]\n"); } -std::unique_ptr NewState(const std::string& cert_file, - const ResConfigData& config_data) { - std::unique_ptr storage = nullptr; - +std::unique_ptr NewStorage(const std::string& db_path, + const ResConfigData& config_data) { #ifdef ENABLE_ROCKSDB - storage = NewResRocksDB(cert_file.c_str(), config_data); LOG(INFO) << "use rocksdb storage."; + return NewResRocksDB(db_path, config_data); #endif #ifdef ENABLE_LEVELDB - storage = NewResLevelDB(cert_file.c_str(), config_data); LOG(INFO) << "use leveldb storage."; + return NewResLevelDB(db_path, config_data); #endif - std::unique_ptr state = - std::make_unique(std::move(storage)); - return state; + + LOG(INFO) << "use memory storage."; + return NewMemoryDB(); } int main(int argc, char** argv) { @@ -66,12 +59,13 @@ int main(int argc, char** argv) { ShowUsage(); exit(0); } + google::InitGoogleLogging(argv[0]); char* config_file = argv[1]; char* private_key_file = argv[2]; char* cert_file = argv[3]; - if (argc == 5) { + if (argc == 6) { std::string grafana_port = argv[4]; std::string grafana_address = "0.0.0.0:" + grafana_port; @@ -84,8 +78,11 @@ int main(int argc, char** argv) { GenerateResDBConfig(config_file, private_key_file, cert_file); ResConfigData config_data = config->GetConfigData(); + std::string db_path = std::to_string(config->GetSelfInfo().port()) + "_db/"; + LOG(INFO) << "db path:" << db_path; + auto server = GenerateResDBServer( config_file, private_key_file, cert_file, - std::make_unique(NewState(cert_file, config_data)), nullptr); + std::make_unique(NewStorage(db_path, config_data)), nullptr); server->Run(); } diff --git a/service/tools/config/server/server.config b/service/tools/config/server/server.config index 87c9b37ee..20a8b7711 100644 --- a/service/tools/config/server/server.config +++ b/service/tools/config/server/server.config @@ -27,17 +27,12 @@ num_threads:1, write_buffer_size_mb:32, write_batch_size:1, - generate_unique_pathnames:true, }, leveldb_info : { write_buffer_size_mb:128, write_batch_size:1, - generate_unique_pathnames:true, }, require_txn_validation:false, - recovery_enabled : true, - recovery_path : "./log/", - recovery_buffer_size : 1024, } diff --git a/service/tools/contract/api_tools/contract_tools.cpp b/service/tools/contract/api_tools/contract_tools.cpp index 430e9e5bc..0883db4ed 100644 --- a/service/tools/contract/api_tools/contract_tools.cpp +++ b/service/tools/contract/api_tools/contract_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include diff --git a/service/tools/contract/service_tools/start_contract_service.sh b/service/tools/contract/service_tools/start_contract_service.sh index 7eccb0234..dad26d75d 100755 --- a/service/tools/contract/service_tools/start_contract_service.sh +++ b/service/tools/contract/service_tools/start_contract_service.sh @@ -1,11 +1,11 @@ -killall -9 contract_server +killall -9 contract_service -SERVER_PATH=./bazel-bin/service/contract/server/contract_server +SERVER_PATH=./bazel-bin/service/contract/contract_service SERVER_CONFIG=service/tools/config/server/server.config WORK_PATH=$PWD CERT_PATH=${WORK_PATH}/service/tools/data/cert/ -bazel build //service/contract/server:contract_server +bazel build //service/contract:contract_service nohup $SERVER_PATH $SERVER_CONFIG $CERT_PATH/node1.key.pri $CERT_PATH/cert_1.cert > server0.log & nohup $SERVER_PATH $SERVER_CONFIG $CERT_PATH/node2.key.pri $CERT_PATH/cert_2.cert > server1.log & nohup $SERVER_PATH $SERVER_CONFIG $CERT_PATH/node3.key.pri $CERT_PATH/cert_3.cert > server2.log & diff --git a/service/tools/kv/api_tools/kv_client_txn_tools.cpp b/service/tools/kv/api_tools/kv_client_txn_tools.cpp index d73271d1e..4ebff4de3 100644 --- a/service/tools/kv/api_tools/kv_client_txn_tools.cpp +++ b/service/tools/kv/api_tools/kv_client_txn_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include diff --git a/service/tools/kv/api_tools/kv_service_tools.cpp b/service/tools/kv/api_tools/kv_service_tools.cpp index f461e42c5..b5cd53444 100644 --- a/service/tools/kv/api_tools/kv_service_tools.cpp +++ b/service/tools/kv/api_tools/kv_service_tools.cpp @@ -1,29 +1,24 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include +#include #include #include #include @@ -40,13 +35,39 @@ using resdb::KVClient; using resdb::ReplicaInfo; using resdb::ResDBConfig; -int main(int argc, char** argv) { - if (argc < 3) { - printf( - " (set/get/getvalues/getrange), [key] " - "[value/key2]\n"); - return 0; - } +void ShowUsage() { + printf( + "--config: config path\n" + "--cmd " + "set/get/set_with_version/get_with_version/get_key_range/" + "get_key_range_with_version/get_top/get_history\n" + "--key key\n" + "--value value, if cmd is a get operation\n" + "--version version of the value, if cmd is vesion based\n" + "--min_key the min key if cmd is get_key_range\n" + "--max_key the max key if cmd is get_key_range\n" + "--min_version, if cmd is get_history\n" + "--max_version, if cmd is get_history\n" + "--top, if cmd is get_top\n" + "\n" + "More examples can be found from README.\n"); +} + +static struct option long_options[] = { + {"help", no_argument, NULL, 'h'}, + {"config", required_argument, NULL, 'c'}, + {"cmd", required_argument, NULL, 'f'}, + {"key", required_argument, NULL, 'K'}, + {"value", required_argument, NULL, 'V'}, + {"version", required_argument, NULL, 'v'}, + {"min_version", required_argument, NULL, 's'}, + {"max_version", required_argument, NULL, 'S'}, + {"min_key", required_argument, NULL, 'y'}, + {"max_key", required_argument, NULL, 'Y'}, + {"top", required_argument, NULL, 't'}, +}; + +void OldAPI(char** argv) { std::string client_config_file = argv[1]; std::string cmd = argv[2]; std::string key; @@ -80,7 +101,7 @@ int main(int argc, char** argv) { printf("client get value fail\n"); } } else if (cmd == "getvalues") { - auto res = client.GetValues(); + auto res = client.GetAllValues(); if (res != nullptr) { printf("client getvalues value = %s\n", res->c_str()); } else { @@ -95,3 +116,165 @@ int main(int argc, char** argv) { } } } + +int main(int argc, char** argv) { + std::string key; + int version = -1; + int option_index = 0; + int min_version = -1, max_version = -1; + std::string min_key, max_key; + std::string value; + std::string client_config_file; + int top = 0; + char c; + std::string cmd; + + if (argc >= 3) { + cmd = argv[2]; + if (cmd == "get" || cmd == "set" || cmd == "getvalues" || + cmd == "getrange") { + OldAPI(argv); + return 0; + } + } + + while ((c = getopt_long(argc, argv, "h", long_options, &option_index)) != + -1) { + switch (c) { + case 'c': + client_config_file = optarg; + break; + case 'f': + cmd = optarg; + break; + case 'K': + key = optarg; + break; + case 'V': + value = optarg; + break; + case 'v': + version = strtoull(optarg, NULL, 10); + break; + case 's': + min_version = strtoull(optarg, NULL, 10); + break; + case 'S': + max_version = strtoull(optarg, NULL, 10); + break; + case 'y': + min_key = optarg; + break; + case 'Y': + max_key = optarg; + break; + case 't': + top = strtoull(optarg, NULL, 10); + break; + case 'h': + ShowUsage(); + break; + } + } + + ResDBConfig config = GenerateResDBConfig(client_config_file); + + config.SetClientTimeoutMs(100000); + KVClient client(config); + if (cmd == "set_with_version") { + if (key.empty() || value.empty() || version < 0) { + ShowUsage(); + return 0; + } + int ret = client.Set(key, value, version); + printf("set key = %s, value = %s, version = %d done, ret = %d\n", + key.c_str(), value.c_str(), version, ret); + if (ret == 0) { + usleep(100000); + auto res = client.Get(key, 0); + if (res != nullptr) { + printf("current value = %s\n", res->DebugString().c_str()); + } else { + printf("get value fail\n"); + } + } + } else if (cmd == "set") { + if (key.empty() || value.empty()) { + ShowUsage(); + return 0; + } + int ret = client.Set(key, value); + printf("set key = %s, value = %s done, ret = %d\n", key.c_str(), + value.c_str(), ret); + } else if (cmd == "get_with_version") { + auto res = client.Get(key, version); + if (res != nullptr) { + printf("get key = %s, value = %s\n", key.c_str(), + res->DebugString().c_str()); + } else { + printf("get value fail\n"); + } + } else if (cmd == "get") { + auto res = client.Get(key); + if (res != nullptr) { + printf("get key = %s value = %s\n", key.c_str(), res->c_str()); + } else { + printf("get value fail\n"); + } + } else if (cmd == "get_top") { + auto res = client.GetKeyTopHistory(key, top); + if (res != nullptr) { + printf("key = %s, top %d\n value = %s\n", key.c_str(), top, + res->DebugString().c_str()); + } else { + printf("get key = %s top %d value fail\n", key.c_str(), top); + } + } else if (cmd == "get_history") { + if (key.empty() || min_version < 0 || max_version < 0 || + max_version < min_version) { + ShowUsage(); + return 0; + } + auto res = client.GetKeyHistory(key, min_version, max_version); + if (res != nullptr) { + printf( + "get history key = %s, min version = %d, max version = %d\n value = " + "%s\n", + key.c_str(), min_version, max_version, res->DebugString().c_str()); + } else { + printf( + "get history key = %s, min version = %d, max version = %d value " + "fail\n", + key.c_str(), min_version, max_version); + } + } else if (cmd == "get_key_range") { + if (min_key.empty() || max_key.empty() || min_key > max_key) { + ShowUsage(); + return 0; + } + auto res = client.GetRange(min_key, max_key); + if (res != nullptr) { + printf("getrange min key = %s, max key = %s\n value = %s\n", + min_key.c_str(), max_key.c_str(), (*res).c_str()); + } else { + printf("getrange value fail, min key = %s, max key = %s\n", + min_key.c_str(), max_key.c_str()); + } + } else if (cmd == "get_key_range_with_version") { + if (min_key.empty() || max_key.empty() || min_key > max_key) { + ShowUsage(); + return 0; + } + printf("min key = %s max key = %s\n", min_key.c_str(), max_key.c_str()); + auto res = client.GetKeyRange(min_key, max_key); + if (res != nullptr) { + printf("getrange min key = %s, max key = %s\n value = %s\n", + min_key.c_str(), max_key.c_str(), res->DebugString().c_str()); + } else { + printf("getrange value fail, min key = %s, max key = %s\n", + min_key.c_str(), max_key.c_str()); + } + } else { + ShowUsage(); + } +} diff --git a/service/tools/utxo/service_tools/start_utxo_service.sh b/service/tools/utxo/service_tools/start_utxo_service.sh index a0a7d5fc6..75b394f37 100755 --- a/service/tools/utxo/service_tools/start_utxo_service.sh +++ b/service/tools/utxo/service_tools/start_utxo_service.sh @@ -1,13 +1,13 @@ -killall -9 utxo_server +killall -9 utxo_service -SERVER_PATH=./bazel-bin/service/utxo/server/utxo_server +SERVER_PATH=./bazel-bin/service/utxo/utxo_service SERVER_CONFIG=service/tools/config/server/server.config WORK_PATH=$PWD CERT_PATH=${WORK_PATH}/service/tools/data/cert/ UTXO_CONFIG=service/tools/config/server/utxo_config.config -bazel build //service/utxo/server:utxo_server +bazel build //service/utxo:utxo_service nohup $SERVER_PATH $SERVER_CONFIG $CERT_PATH/node1.key.pri $CERT_PATH/cert_1.cert ${UTXO_CONFIG} > server0.log & nohup $SERVER_PATH $SERVER_CONFIG $CERT_PATH/node2.key.pri $CERT_PATH/cert_2.cert ${UTXO_CONFIG} > server1.log & nohup $SERVER_PATH $SERVER_CONFIG $CERT_PATH/node3.key.pri $CERT_PATH/cert_3.cert ${UTXO_CONFIG} > server2.log & diff --git a/service/tools/utxo/wallet_tool/cpp/utxo_client_tools.cpp b/service/tools/utxo/wallet_tool/cpp/utxo_client_tools.cpp index 207b9233c..596b468c3 100644 --- a/service/tools/utxo/wallet_tool/cpp/utxo_client_tools.cpp +++ b/service/tools/utxo/wallet_tool/cpp/utxo_client_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include @@ -46,9 +40,11 @@ void ShowUsage() { } void Transfer(UTXOClient* client, int64_t transaction_id, - const std::string& address, const std::string& to_address, - const int value, const std::string& private_key, - const std::string& to_pub_key) { + const std::string& address, + const std::vector& to_address, + const std::vector& values, + const std::string& private_key, + const std::vector& to_pub_key) { if (private_key.empty() || to_pub_key.empty()) { printf("no private key or public key\n"); return; @@ -60,13 +56,17 @@ void Transfer(UTXOClient* client, int64_t transaction_id, in->set_out_idx(0); nonce += transaction_id; - UTXOOut* out = utxo.add_out(); - out->set_address(to_address); - out->set_value(value); - out->set_pub_key(to_pub_key); - utxo.set_address(address); - utxo.set_sig(resdb::utils::ECDSASignString(private_key, - address + std::to_string(nonce))); + for (size_t i = 0; i < to_address.size(); ++i) { + UTXOOut* out = utxo.add_out(); + out->set_address(to_address[i]); + out->set_value(values[i]); + out->set_pub_key(to_pub_key[i]); + utxo.set_address(address); + utxo.set_sig(resdb::utils::ECDSASignString( + private_key, address + std::to_string(nonce))); + LOG(ERROR) << "transfer from:" << address << " to:" << to_address[i] + << " value:" << values[i]; + } auto output = client->Transfer(utxo); LOG(ERROR) << "execute result:\n" << output; @@ -87,6 +87,34 @@ void GetWallet(UTXOClient* client, const std::string& address) { LOG(ERROR) << "address:" << address << " get wallet value:" << ret; } +std::vector ParseString(std::string str) { + std::vector ret; + while (true) { + size_t pos = str.find(","); + if (pos == std::string::npos) { + ret.push_back(str); + break; + } + ret.push_back(str.substr(0, pos)); + str = str.substr(pos + 1); + } + return ret; +} + +std::vector ParseValue(std::string str) { + std::vector ret; + while (true) { + size_t pos = str.find(","); + if (pos == std::string::npos) { + ret.push_back(strtoull(str.c_str(), NULL, 10)); + break; + } + ret.push_back(strtoull(str.substr(0, pos).c_str(), NULL, 10)); + str = str.substr(pos + 1); + } + return ret; +} + int main(int argc, char** argv) { if (argc < 3) { printf("-d -c [config]\n"); @@ -100,7 +128,7 @@ int main(int argc, char** argv) { int num = 10; int c; std::string cmd; - int64_t value = 0; + std::string value; std::string client_config_file; while ((c = getopt(argc, argv, "c:d:t:x:m:h:e:v:n:p:b:")) != -1) { switch (c) { @@ -126,7 +154,7 @@ int main(int argc, char** argv) { num = strtoull(optarg, NULL, 10); break; case 'v': - value = strtoull(optarg, NULL, 10); + value = optarg; break; case 'p': private_key = optarg; @@ -142,11 +170,10 @@ int main(int argc, char** argv) { ResDBConfig config = GenerateResDBConfig(client_config_file); config.SetClientTimeoutMs(100000); - UTXOClient client(config); if (cmd == "transfer") { - Transfer(&client, transaction_id, address, to_address, value, private_key, - to_pub_key); + Transfer(&client, transaction_id, address, ParseString(to_address), + ParseValue(value), private_key, ParseString(to_pub_key)); } else if (cmd == "list") { GetList(&client, end_id, num); } else if (cmd == "wallet") { diff --git a/service/tools/utxo/wallet_tool/py/addr.py b/service/tools/utxo/wallet_tool/py/addr.py index f4cae5eb1..5b64b29f3 100644 --- a/service/tools/utxo/wallet_tool/py/addr.py +++ b/service/tools/utxo/wallet_tool/py/addr.py @@ -1,24 +1,19 @@ -# Copyright (c) 2019-2022 ExpoLab, UC Davis -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, -# copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. +# 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. import sys import wallet_tools_py diff --git a/service/tools/utxo/wallet_tool/py/keys.py b/service/tools/utxo/wallet_tool/py/keys.py index 72c4fdb74..c90ea9c33 100644 --- a/service/tools/utxo/wallet_tool/py/keys.py +++ b/service/tools/utxo/wallet_tool/py/keys.py @@ -1,24 +1,20 @@ -# Copyright (c) 2019-2022 ExpoLab, UC Davis -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, -# copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. +# 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. + import wallet_tools_py diff --git a/service/tools/utxo/wallet_tool/test/key_tester.py b/service/tools/utxo/wallet_tool/test/key_tester.py index ca06f1409..f9112c509 100644 --- a/service/tools/utxo/wallet_tool/test/key_tester.py +++ b/service/tools/utxo/wallet_tool/test/key_tester.py @@ -1,24 +1,19 @@ -# Copyright (c) 2019-2022 ExpoLab, UC Davis -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, -# copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. +# 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. import wallet_tools_py import key_tester_utils diff --git a/service/tools/utxo/wallet_tool/test/key_tester_utils.cpp b/service/tools/utxo/wallet_tool/test/key_tester_utils.cpp index af7de2c80..d1744fb6c 100644 --- a/service/tools/utxo/wallet_tool/test/key_tester_utils.cpp +++ b/service/tools/utxo/wallet_tool/test/key_tester_utils.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include diff --git a/service/utils/server_factory.cpp b/service/utils/server_factory.cpp index 61841cac9..377f03096 100644 --- a/service/utils/server_factory.cpp +++ b/service/utils/server_factory.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include "service/utils/server_factory.h" diff --git a/service/utils/server_factory.h b/service/utils/server_factory.h index 5ab7364d0..aa23254f4 100644 --- a/service/utils/server_factory.h +++ b/service/utils/server_factory.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #pragma once diff --git a/service/utxo/utxo_service.cpp b/service/utxo/utxo_service.cpp index 7c5bfcc9c..c231526f1 100644 --- a/service/utxo/utxo_service.cpp +++ b/service/utxo/utxo_service.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include diff --git a/tools/certificate_tools.cpp b/tools/certificate_tools.cpp index 6be804f70..92a24eae3 100644 --- a/tools/certificate_tools.cpp +++ b/tools/certificate_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include diff --git a/tools/certificate_tools_test.cpp b/tools/certificate_tools_test.cpp index 8748880af..42bd31652 100644 --- a/tools/certificate_tools_test.cpp +++ b/tools/certificate_tools_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include diff --git a/tools/generate_mulregion_config.py b/tools/generate_mulregion_config.py index 424a343cc..e25642f87 100644 --- a/tools/generate_mulregion_config.py +++ b/tools/generate_mulregion_config.py @@ -1,3 +1,20 @@ +# 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. + import os import json import sys diff --git a/tools/generate_region_config.py b/tools/generate_region_config.py index 96f0d8f92..c3d001f22 100644 --- a/tools/generate_region_config.py +++ b/tools/generate_region_config.py @@ -1,3 +1,20 @@ +# 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. + import os import json import sys @@ -6,10 +23,8 @@ from google.protobuf.json_format import Parse, ParseDict -def GenerateJsonConfig(file_name, output_file): +def GenerateJsonConfig(file_name, output_file, template_file): config_data=ResConfigData() - config_data.enable_viewchange = False - config_data.max_client_complaint_num = 10 tmp_config={} with open(file_name) as f: for line in f.readlines(): @@ -39,5 +54,31 @@ def GenerateJsonConfig(file_name, output_file): with open(output_file,"w") as f: f.write(json_obj) + if template_file: + old_json = None + with open(output_file) as f: + lines=f.readlines() + for l in lines: + l=l.strip() + s=''.join(lines) + old_json=json.loads(s) + + template_json = {} + with open(template_file) as f: + lines=f.readlines() + for l in lines: + l=l.strip() + s=''.join(lines) + template_json=json.loads(s) + + for (k,v) in template_json.items(): + old_json[k] = v + + with open(output_file,"w") as f: + json.dump(old_json, f) + if __name__ == "__main__": - GenerateJsonConfig(sys.argv[1], sys.argv[2]) + template_config = None + if len(sys.argv)>3: + template_config = sys.argv[3] + GenerateJsonConfig(sys.argv[1], sys.argv[2], template_config) diff --git a/tools/key_generator_tools.cpp b/tools/key_generator_tools.cpp index 80c063324..93b15d9cd 100644 --- a/tools/key_generator_tools.cpp +++ b/tools/key_generator_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include diff --git a/tools/resdb_state_accessor_tools.cpp b/tools/resdb_state_accessor_tools.cpp index 8aaa45d4c..59720cfe1 100644 --- a/tools/resdb_state_accessor_tools.cpp +++ b/tools/resdb_state_accessor_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include diff --git a/tools/resdb_txn_accessor_tools.cpp b/tools/resdb_txn_accessor_tools.cpp index 35cc37c0d..38cb2a408 100644 --- a/tools/resdb_txn_accessor_tools.cpp +++ b/tools/resdb_txn_accessor_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * 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 * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * 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. */ #include