diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 0678dc538e..63da8e57dc 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -46,6 +46,8 @@ jobs: run: | fingerprint=$RANDOM echo "FINGERPRINT=$fingerprint" >> $GITHUB_ENV + SGX_MODE_LOWERCASE=$(echo "${${{ matrix.sgx_mode }},,}") + echo "IMAGE_SUFFIX=$SGX_MODE_LOWERCASE-${{ matrix.flavor_id }}-${{ github.sha }}" >> $GITHUB_ENV if [[ ${{ matrix.sgx_mode }} == 'HW' ]]; then echo "DOCKER_DEVICES=--device=/dev/sgx/enclave --device=/dev/sgx/provision" >> $GITHUB_ENV echo "DOCKER_VOLUMES=--volume /var/run/aesmd:/var/run/aesmd --volume /etc/sgx_default_qcnl.conf:/etc/sgx_default_qcnl.conf" >> $GITHUB_ENV @@ -64,7 +66,7 @@ jobs: env: DOCKER_BUILDKIT: 1 run: > - docker build -t integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }} + docker build -t integritee-worker-${{ env.IMAGE_SUFFIX }} --target deployed-worker --build-arg WORKER_MODE_ARG=${{ matrix.mode }} --build-arg FINGERPRINT=${FINGERPRINT} --build-arg ADDITIONAL_FEATURES_ARG=${{ matrix.additional_features }} --build-arg SGX_MODE=${{ matrix.sgx_mode }} -f build.Dockerfile . @@ -73,7 +75,7 @@ jobs: env: DOCKER_BUILDKIT: 1 run: > - docker build -t integritee-cli-client-${{ matrix.flavor_id }}-${{ github.sha }} + docker build -t integritee-cli-client-${{ env.IMAGE_SUFFIX }} --target deployed-client --build-arg WORKER_MODE_ARG=${{ matrix.mode }} --build-arg FINGERPRINT=${FINGERPRINT} --build-arg ADDITIONAL_FEATURES_ARG=${{ matrix.additional_features }} -f build.Dockerfile . @@ -81,70 +83,92 @@ jobs: - run: docker images --all - name: Test Enclave # cargo test is not supported in the enclave, see: https://github.com/apache/incubator-teaclave-sgx-sdk/issues/232 - run: docker run ${{ env.DOCKER_DEVICES }} ${{ env.DOCKER_VOLUMES }} integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }} test --all + run: docker run ${{ env.DOCKER_DEVICES }} ${{ env.DOCKER_VOLUMES }} integritee-worker-${{ env.IMAGE_SUFFIX }} test --all - name: Export worker image(s) run: | - docker image save integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }} | gzip > integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }}.tar.gz - docker image save integritee-cli-client-${{ matrix.flavor_id }}-${{ github.sha }} | gzip > integritee-cli-client-${{ matrix.flavor_id }}-${{ github.sha }}.tar.gz + docker image save integritee-worker-${{ env.IMAGE_SUFFIX }} | gzip > integritee-worker-${{ env.IMAGE_SUFFIX }}.tar.gz + docker image save integritee-cli-client-${{ env.IMAGE_SUFFIX }} | gzip > integritee-cli-client-${{ env.IMAGE_SUFFIX }}.tar.gz - name: Upload worker image uses: actions/upload-artifact@v3 with: - name: integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }}.tar.gz - path: integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }}.tar.gz + name: integritee-worker-${{ env.IMAGE_SUFFIX }}.tar.gz + path: integritee-worker-${{ env.IMAGE_SUFFIX }}.tar.gz - name: Upload CLI client image uses: actions/upload-artifact@v3 with: - name: integritee-cli-client-${{ matrix.flavor_id }}-${{ github.sha }}.tar.gz - path: integritee-cli-client-${{ matrix.flavor_id }}-${{ github.sha }}.tar.gz + name: integritee-cli-client-${{ env.IMAGE_SUFFIX }}.tar.gz + path: integritee-cli-client-${{ env.IMAGE_SUFFIX }}.tar.gz + + - name: Create Enclave Digest File + run: | + mrenclave_hex=$(docker run integritee-worker-${{ env.IMAGE_SUFFIX }} mrenclave | grep -oP ':\s*\K[a-fA-F0-9]+') + echo "$mrenclave_hex" > mrenclave-${{ env.IMAGE_SUFFIX }}.hex + + - name: Upload Enclave Digest File + uses: actions/upload-artifact@v3 + with: + name: mrenclave-${{ env.IMAGE_SUFFIX }}.hex + path: mrenclave-${{ env.IMAGE_SUFFIX }}.hex - name: Delete images run: | - if [[ "$(docker images -q integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }} 2> /dev/null)" != "" ]]; then - docker image rmi --force integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }} 2>/dev/null + if [[ "$(docker images -q integritee-worker-${{ env.IMAGE_SUFFIX }} 2> /dev/null)" != "" ]]; then + docker image rmi --force integritee-worker-${{ env.IMAGE_SUFFIX }} 2>/dev/null fi - if [[ "$(docker images -q integritee-cli-client-${{ matrix.flavor_id }}-${{ github.sha }} 2> /dev/null)" != "" ]]; then - docker image rmi --force integritee-cli-client-${{ matrix.flavor_id }}-${{ github.sha }} 2>/dev/null + if [[ "$(docker images -q integritee-cli-client-${{ env.IMAGE_SUFFIX }} 2> /dev/null)" != "" ]]; then + docker image rmi --force integritee-cli-client-${{ env.IMAGE_SUFFIX }} 2>/dev/null fi docker images --all - clippy: + code-quality: runs-on: ubuntu-latest container: "integritee/integritee-dev:0.2.2" + strategy: + fail-fast: false + matrix: + check: [ + # Worker + # Use release mode as the CI runs out of disk space otherwise. + cargo clippy --release -- -D warnings, + cargo clippy --release --features evm -- -D warnings, + cargo clippy --release --features sidechain -- -D warnings, + cargo clippy --release --features teeracle -- -D warnings, + cargo clippy --release --features offchain-worker -- -D warnings, + + # Enclave + cd enclave-runtime && cargo clippy -- -D warnings, + cd enclave-runtime && cargo clippy --features evm -- -D warnings, + cd enclave-runtime && cargo clippy --features sidechain -- -D warnings, + cd enclave-runtime && cargo clippy --features teeracle -- -D warnings, + cd enclave-runtime && cargo clippy --features offchain-worker -- -D warnings, + + # Fmt + cargo fmt --all -- --check, + cd enclave-runtime && cargo fmt --all -- --check, + ] steps: - uses: actions/checkout@v3 - - name: init rust - # enclave is not in the same workspace + - name: init-rust-target + # Enclave is not in the same workspace run: rustup show && cd enclave-runtime && rustup show - - name: Clippy default features - run: cargo clippy -- -D warnings - - name: Enclave # Enclave is separate as it's not in the workspace - run: cd enclave-runtime && cargo clippy -- -D warnings - - - name: Clippy with Offchain-worker feature - run: | - cargo clippy --features offchain-worker -- -D warnings - cd enclave-runtime && cargo clippy --features offchain-worker -- -D warnings + - uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.check }} - - name: Fail-fast; cancel other jobs - if: failure() - uses: andymckay/cancel-action@0.3 + - name: ${{ matrix.check }} + run: ${{ matrix.check }} - fmt: + toml-fmt: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: init rust run: rustup show - - name: Worker & Client - run: cargo fmt --all -- --check - - name: Enclave # Enclave is separate as it's not in the workspace - run: cd enclave-runtime && cargo fmt --all -- --check - - name: Install taplo run: cargo install taplo-cli --locked - name: Cargo.toml fmt @@ -178,6 +202,8 @@ jobs: - name: Set env run: | version=$RANDOM + SGX_MODE_LOWERCASE=$(echo "${${{ matrix.sgx_mode }},,}") + echo "IMAGE_SUFFIX=$SGX_MODE_LOWERCASE-${{ matrix.flavor_id }}-${{ github.sha }}" >> $GITHUB_ENV echo "FLAVOR_ID=${{ matrix.flavor_id }}" >> $GITHUB_ENV echo "PROJECT=${{ matrix.flavor_id }}-${{ matrix.demo_name }}" >> $GITHUB_ENV echo "VERSION=dev.$version" >> $GITHUB_ENV @@ -196,21 +222,21 @@ jobs: - name: Download Worker Image uses: actions/download-artifact@v3 with: - name: integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }}.tar.gz + name: integritee-worker-${{ env.IMAGE_SUFFIX }}.tar.gz path: . - name: Download CLI client Image uses: actions/download-artifact@v3 with: - name: integritee-cli-client-${{ matrix.flavor_id }}-${{ github.sha }}.tar.gz + name: integritee-cli-client-${{ env.IMAGE_SUFFIX }}.tar.gz path: . - name: Load Worker & Client Images env: DOCKER_BUILDKIT: 1 run: | - docker image load --input integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }}.tar.gz - docker image load --input integritee-cli-client-${{ matrix.flavor_id }}-${{ github.sha }}.tar.gz + docker image load --input integritee-worker-${{ env.IMAGE_SUFFIX }}.tar.gz + docker image load --input integritee-cli-client-${{ env.IMAGE_SUFFIX }}.tar.gz docker images --all ## @@ -225,8 +251,8 @@ jobs: if [[ "$(docker images -q ${{ env.CLIENT_IMAGE_TAG }} 2> /dev/null)" == "" ]]; then docker image rmi --force ${{ env.CLIENT_IMAGE_TAG }} 2>/dev/null fi - docker tag integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }} ${{ env.WORKER_IMAGE_TAG }} - docker tag integritee-cli-client-${{ matrix.flavor_id }}-${{ github.sha }} ${{ env.CLIENT_IMAGE_TAG }} + docker tag integritee-worker-${{ env.IMAGE_SUFFIX }} ${{ env.WORKER_IMAGE_TAG }} + docker tag integritee-cli-client-${{ env.IMAGE_SUFFIX }} ${{ env.CLIENT_IMAGE_TAG }} docker pull integritee/integritee-node:1.1.3 docker tag integritee/integritee-node:1.1.3 ${{ env.INTEGRITEE_NODE }} docker images --all @@ -273,11 +299,11 @@ jobs: - name: Delete images run: | - if [[ "$(docker images -q integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }} 2> /dev/null)" != "" ]]; then - docker image rmi --force integritee-worker-${{ matrix.flavor_id }}-${{ github.sha }} 2>/dev/null + if [[ "$(docker images -q integritee-worker-${{ env.IMAGE_SUFFIX }} 2> /dev/null)" != "" ]]; then + docker image rmi --force integritee-worker-${{ env.IMAGE_SUFFIX }} 2>/dev/null fi - if [[ "$(docker images -q integritee-cli-client-${{ matrix.flavor_id }}-${{ github.sha }} 2> /dev/null)" != "" ]]; then - docker image rmi --force integritee-cli-client-${{ matrix.flavor_id }}-${{ github.sha }} 2>/dev/null + if [[ "$(docker images -q integritee-cli-client-${{ env.IMAGE_SUFFIX }} 2> /dev/null)" != "" ]]; then + docker image rmi --force integritee-cli-client-${{ env.IMAGE_SUFFIX }} 2>/dev/null fi if [[ "$(docker images -q ${{ env.WORKER_IMAGE_TAG }} 2> /dev/null)" != "" ]]; then docker image rmi --force ${{ env.WORKER_IMAGE_TAG }} 2>/dev/null @@ -294,7 +320,7 @@ jobs: runs-on: integritee-builder-sgx name: Release Build of teeracle if: startsWith(github.ref, 'refs/tags/') - needs: [build-test, integration-tests] + needs: [ build-test, integration-tests ] strategy: fail-fast: false @@ -322,6 +348,8 @@ jobs: run: | fingerprint=$RANDOM echo "FINGERPRINT=$fingerprint" >> $GITHUB_ENV + SGX_MODE_LOWERCASE=$(echo "${${{ matrix.sgx_mode }},,}") + echo "IMAGE_SUFFIX=$SGX_MODE_LOWERCASE-${{ matrix.flavor_id }}-${{ github.sha }}" >> $GITHUB_ENV if [[ ${{ matrix.sgx_mode }} == 'HW' ]]; then echo "DOCKER_DEVICES=--device=/dev/sgx/enclave --device=/dev/sgx/provision" >> $GITHUB_ENV echo "DOCKER_VOLUMES=--volume /var/run/aesmd:/var/run/aesmd --volume /etc/sgx_default_qcnl.conf:/etc/sgx_default_qcnl.conf" >> $GITHUB_ENV @@ -368,8 +396,8 @@ jobs: - name: Save released teeracle run: | - docker image save integritee/${{ matrix.flavor_id }}:${{ github.ref_name }} | gzip > integritee-worker-${{ matrix.flavor_id }}-${{ github.ref_name }}.tar.gz - docker images --all + docker image save integritee/${{ matrix.flavor_id }}:${{ github.ref_name }} | gzip > integritee-worker-${{ matrix.flavor_id }}-${{ github.ref_name }}.tar.gz + docker images --all - name: Upload teeracle image uses: actions/upload-artifact@v3 @@ -379,16 +407,16 @@ jobs: - name: Delete images run: | - if [[ "$(docker images -q integritee/${{ matrix.flavor_id }}:${{ github.ref_name }} 2> /dev/null)" != "" ]]; then - docker image rmi --force integritee/${{ matrix.flavor_id }}:${{ github.ref_name }} 2>/dev/null - fi - docker images --all + if [[ "$(docker images -q integritee/${{ matrix.flavor_id }}:${{ github.ref_name }} 2> /dev/null)" != "" ]]; then + docker image rmi --force integritee/${{ matrix.flavor_id }}:${{ github.ref_name }} 2>/dev/null + fi + docker images --all release: runs-on: ubuntu-latest name: Draft Release if: startsWith(github.ref, 'refs/tags/') - needs: [build-test, integration-tests, release-build] + needs: [ build-test, integration-tests, release-build ] outputs: release_url: ${{ steps.create-release.outputs.html_url }} asset_upload_url: ${{ steps.create-release.outputs.upload_url }} diff --git a/Cargo.lock b/Cargo.lock index 29522ae8f2..612ca774d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,7 +40,7 @@ dependencies = [ "scale-encode", "scale-info", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sp-application-crypto", "sp-core", "sp-runtime", @@ -60,7 +60,7 @@ dependencies = [ "primitive-types", "scale-info", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sp-application-crypto", "sp-core", "sp-core-hashing", @@ -253,7 +253,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -384,7 +384,7 @@ dependencies = [ [[package]] name = "binary-merkle-tree" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git#28b1f79abedbad2ec97b49277b36e1f797ca9e5d" +source = "git+https://github.com/paritytech/substrate.git#033d4e86cc7eff0066cd376b9375f815761d653c" dependencies = [ "hash-db 0.16.0", ] @@ -665,7 +665,7 @@ dependencies = [ "cargo-platform", "semver 1.0.17", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "thiserror 1.0.40", ] @@ -1087,7 +1087,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -1104,7 +1104,7 @@ checksum = "4a076022ece33e7686fb76513518e219cca4fce5750a8ae6d1ce6c0f48fd1af9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -1421,19 +1421,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "env_logger" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" -dependencies = [ - "humantime", - "is-terminal", - "log 0.4.19", - "regex 1.9.5", - "termcolor", -] - [[package]] name = "environmental" version = "1.1.3" @@ -1447,6 +1434,12 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48c92028aaa870e83d51c64e5d4e0b6981b360c522198c23959f219a4e1b15b" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.1" @@ -1890,7 +1883,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -1902,7 +1895,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -1912,7 +1905,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.4 dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -2105,7 +2098,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -2356,6 +2349,12 @@ dependencies = [ "ahash 0.8.3", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "hashbrown_tstd" version = "0.12.0" @@ -2742,6 +2741,16 @@ dependencies = [ "serde 1.0.188", ] +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + [[package]] name = "instant" version = "0.1.12" @@ -2771,7 +2780,7 @@ dependencies = [ "chrono 0.4.26", "clap 3.2.25", "enclave-bridge-primitives", - "env_logger 0.9.3", + "env_logger", "frame-system", "hdrhistogram", "hex", @@ -2798,7 +2807,7 @@ dependencies = [ "reqwest", "sc-keystore", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sgx_crypto_helper", "simplyr-lib", "sp-application-crypto", @@ -2869,7 +2878,7 @@ dependencies = [ "clap 2.34.0", "dirs", "enclave-bridge-primitives", - "env_logger 0.9.3", + "env_logger", "frame-support", "frame-system", "futures 0.3.28", @@ -2908,7 +2917,7 @@ dependencies = [ "scale-info", "serde 1.0.188", "serde_derive 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sgx-verify", "sgx_crypto_helper", "sgx_types", @@ -2969,7 +2978,7 @@ dependencies = [ "hyper-tls", "parity-multiaddr", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "serde_urlencoded", "tokio", "tokio-util 0.6.10", @@ -2984,18 +2993,6 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" -[[package]] -name = "is-terminal" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix 0.37.20", - "windows-sys 0.48.0", -] - [[package]] name = "ita-oracle" version = "0.9.0" @@ -3007,7 +3004,7 @@ dependencies = [ "log 0.4.19", "parity-scale-codec", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sgx_tstd", "substrate-fixed", "thiserror 1.0.40", @@ -3081,7 +3078,7 @@ dependencies = [ "parity-scale-codec", "rlp", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sgx_tstd", "sha3", "simplyr-lib", @@ -3104,7 +3101,7 @@ dependencies = [ "jsonrpc-core 18.0.0 (git+https://github.com/scs/jsonrpc?branch=no_std_v18)", "log 0.4.19", "parity-scale-codec", - "serde_json 1.0.96", + "serde_json 1.0.106", "sgx_tstd", "sgx_types", "sp-runtime", @@ -3192,7 +3189,7 @@ version = "0.9.0" dependencies = [ "binary-merkle-tree 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42)", "bs58", - "env_logger 0.9.3", + "env_logger", "futures 0.3.28", "futures 0.3.8", "ita-stf", @@ -3276,7 +3273,7 @@ dependencies = [ "http_req 0.8.1 (git+https://github.com/integritee-network/http_req)", "log 0.4.19", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sgx_tstd", "sgx_types", "thiserror 1.0.40", @@ -3289,7 +3286,7 @@ dependencies = [ name = "itc-rpc-client" version = "0.9.0" dependencies = [ - "env_logger 0.9.3", + "env_logger", "frame-metadata", "itc-tls-websocket-server", "itp-api-client-types", @@ -3303,7 +3300,7 @@ dependencies = [ "parking_lot 0.12.1", "rustls 0.19.1", "serde_derive 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sgx_crypto_helper", "thiserror 1.0.40", "url 2.4.0", @@ -3315,7 +3312,7 @@ name = "itc-rpc-server" version = "0.9.0" dependencies = [ "anyhow", - "env_logger 0.10.0", + "env_logger", "itp-enclave-api", "itp-rpc", "itp-utils", @@ -3327,7 +3324,7 @@ dependencies = [ "jsonrpsee", "log 0.4.19", "parity-scale-codec", - "serde_json 1.0.96", + "serde_json 1.0.106", "sp-core", "tokio", ] @@ -3338,7 +3335,7 @@ version = "0.9.0" dependencies = [ "bit-vec", "chrono 0.4.26", - "env_logger 0.9.3", + "env_logger", "log 0.4.19", "mio 0.6.21", "mio 0.6.23", @@ -3434,8 +3431,8 @@ dependencies = [ "parity-scale-codec", "rustls 0.19.0 (git+https://github.com/mesalock-linux/rustls?rev=sgx_1.1.3)", "rustls 0.19.1", + "serde_json 1.0.106", "serde_json 1.0.60 (git+https://github.com/mesalock-linux/serde-json-sgx?tag=sgx_1.1.3)", - "serde_json 1.0.96", "sgx_rand", "sgx_tcrypto", "sgx_tse", @@ -3473,7 +3470,7 @@ dependencies = [ "itp-types", "log 0.4.19", "parity-scale-codec", - "serde_json 1.0.96", + "serde_json 1.0.106", "sgx_crypto_helper", "sgx_types", "sgx_urts", @@ -3633,7 +3630,7 @@ dependencies = [ "itp-types", "parity-scale-codec", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sgx_tstd", ] @@ -3655,8 +3652,8 @@ dependencies = [ "parity-scale-codec", "serde 1.0.118 (git+https://github.com/mesalock-linux/serde-sgx?tag=sgx_1.1.3)", "serde 1.0.188", + "serde_json 1.0.106", "serde_json 1.0.60 (git+https://github.com/mesalock-linux/serde-json-sgx?tag=sgx_1.1.3)", - "serde_json 1.0.96", "sgx_crypto_helper", "sgx_rand", "sgx_tstd", @@ -3709,6 +3706,7 @@ dependencies = [ name = "itp-stf-executor" version = "0.9.0" dependencies = [ + "hex", "ita-stf", "itc-parentchain-test", "itp-node-api", @@ -3925,7 +3923,7 @@ dependencies = [ "parity-scale-codec", "primitive-types", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sp-core", "sp-runtime", "sp-std", @@ -3995,7 +3993,7 @@ dependencies = [ name = "its-consensus-aura" version = "0.9.0" dependencies = [ - "env_logger 0.9.3", + "env_logger", "finality-grandpa", "frame-support", "ita-stf", @@ -4103,7 +4101,7 @@ dependencies = [ "jsonrpsee", "log 0.4.19", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "thiserror 1.0.40", "tokio", ] @@ -4259,7 +4257,7 @@ dependencies = [ "log 0.4.19", "serde 1.0.188", "serde_derive 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", ] [[package]] @@ -4303,7 +4301,7 @@ dependencies = [ "jsonrpsee-utils", "log 0.4.19", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "thiserror 1.0.40", "url 2.4.0", ] @@ -4323,7 +4321,7 @@ dependencies = [ "lazy_static", "log 0.4.19", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "socket2", "thiserror 1.0.40", "tokio", @@ -4356,7 +4354,7 @@ dependencies = [ "hyper", "log 0.4.19", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "soketto", "thiserror 1.0.40", ] @@ -4376,7 +4374,7 @@ dependencies = [ "rand 0.8.5", "rustc-hash", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "thiserror 1.0.40", ] @@ -4395,7 +4393,7 @@ dependencies = [ "rustls 0.19.1", "rustls-native-certs", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "soketto", "thiserror 1.0.40", "tokio", @@ -4417,7 +4415,7 @@ dependencies = [ "log 0.4.19", "rustc-hash", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "soketto", "thiserror 1.0.40", "tokio", @@ -5365,7 +5363,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -5395,7 +5393,7 @@ checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" [[package]] name = "pallet-assets" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "frame-benchmarking", "frame-support", @@ -6037,7 +6035,7 @@ checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -6193,14 +6191,14 @@ checksum = "0e99670bafb56b9a106419397343bdbc8b8742c3cc449fec6345f86173f47cd4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -6500,7 +6498,7 @@ checksum = "8d2275aab483050ab2a7364c1a46604865ee7d6906684e08db0f090acf74f9e7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -6589,7 +6587,7 @@ dependencies = [ "percent-encoding 2.3.0", "pin-project-lite", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "serde_urlencoded", "tokio", "tokio-native-tls", @@ -6912,12 +6910,12 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "array-bytes 4.2.0", "async-trait", "parking_lot 0.12.1", - "serde_json 1.0.96", + "serde_json 1.0.106", "sp-application-crypto", "sp-core", "sp-keystore", @@ -7251,7 +7249,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -7279,11 +7277,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2" dependencies = [ - "indexmap 1.9.3", + "indexmap 2.0.0", "itoa 1.0.6", "ryu", "serde 1.0.188", @@ -7326,7 +7324,7 @@ dependencies = [ "ring 0.16.20 (git+https://github.com/Niederb/ring-xous.git?branch=0.16.20-cleanup)", "scale-info", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sp-core", "sp-io 7.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42)", "sp-std", @@ -7657,7 +7655,7 @@ dependencies = [ "libm", "parity-scale-codec", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", ] [[package]] @@ -7747,7 +7745,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -7918,7 +7916,7 @@ dependencies = [ "proc-macro2", "quote", "sp-core-hashing", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -7928,7 +7926,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.4 dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -8009,7 +8007,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "lazy_static", "sp-core", @@ -8120,7 +8118,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -8272,7 +8270,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -8347,7 +8345,7 @@ dependencies = [ "proc-macro2", "quote", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "unicode-xid", ] @@ -8414,7 +8412,7 @@ dependencies = [ "maybe-async", "parity-scale-codec", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sp-core", "sp-runtime", "sp-runtime-interface", @@ -8444,7 +8442,7 @@ dependencies = [ "async-trait", "parking_lot 0.12.1", "sc-keystore", - "serde_json 1.0.96", + "serde_json 1.0.106", "sp-application-crypto", "sp-core", "sp-keyring", @@ -8498,9 +8496,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.33" +version = "2.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" +checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" dependencies = [ "proc-macro2", "quote", @@ -8643,7 +8641,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -8737,7 +8735,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -8874,7 +8872,7 @@ checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] @@ -8920,7 +8918,7 @@ dependencies = [ "matchers", "regex 1.9.5", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "sharded-slab", "smallvec 1.10.0", "thread_local", @@ -9281,7 +9279,7 @@ dependencies = [ "rustls-pemfile", "scoped-tls", "serde 1.0.188", - "serde_json 1.0.96", + "serde_json 1.0.106", "serde_urlencoded", "tokio", "tokio-stream", @@ -9330,7 +9328,7 @@ dependencies = [ "once_cell 1.18.0", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", "wasm-bindgen-shared", ] @@ -9364,7 +9362,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -10029,7 +10027,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.32", ] [[package]] diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000000..8d579d96b7 --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,72 @@ +# sidechain startup internal view +```mermaid +sequenceDiagram + participant integritee_network + participant service + participant slotworker + participant parentsync + participant enclave + participant enclave_rpc + participant provisioningserver + participant isinitializedserver + participant metrics + service ->> enclave: EnclaveBase.get_mrenclave + service ->> provisioningserver: spawn (`--mu-ra-port` | 3443) + activate provisioningserver + service ->> enclave: get_ecc_signing_pubkey + service ->> isinitializedserver: spawn (`--untrusted-http-port | 4545) + activate isinitializedserver + service ->> metrics: spawn (`--metrics-port`| 8787) + activate metrics + service ->> enclave_rpc: spawn (`--trusted-worker-port`| 2000) + activate enclave_rpc + + service ->> enclave: generate_dcap_ra_extrinsic + service ->> integritee_network: send register_sgx_enclave extrinsic + service ->> integritee_network: get ShardStatus + service ->> isinitializedserver: registered_on_parentchain +# schedule teeracle re-registration and updates + loop while blocks to sync + service ->> integritee_network: get_block + service ->> enclave: sync_parentchain(blocks, events, proofs) + end + service ->> enclave: init_enclave_sidechain_components + service ->> slotworker: spawn + loop forever + slotworker ->> enclave: execute_trusted_calls + activate enclave + enclave ->> enclave: propose_sidechain_block + enclave ->> integritee_network: send_extrinsics + deactivate enclave + end + service ->> parentsync: spawn + loop forever + parentsync ->> integritee_network: subscribe new headers + parentsync ->> enclave: sync_parentchain + end + service ->> service: poll worker_for_shard + service ->> isinitializedserver: worker_for_shard_registered + + deactivate enclave_rpc + deactivate metrics + deactivate isinitializedserver + deactivate provisioningserver +``` + +# sidechain lifetime external view + +```mermaid +sequenceDiagram + participant integritee_network + participant validateer_1 + participant validateer_2 + actor alice + + validateer_1 ->> integritee_network: register_sgx_enclave() + + validateer_2 ->> integritee_network: register_sgx_enclave() + + validateer_2 ->> validateer_1: sidechain_fetchBlocksFromPeer() + + validateer_1 ->> validateer_2: sidechain_importBlock() +``` diff --git a/app-libs/stf/src/trusted_call.rs b/app-libs/stf/src/trusted_call.rs index a644dfabe3..35ab042ecc 100644 --- a/app-libs/stf/src/trusted_call.rs +++ b/app-libs/stf/src/trusted_call.rs @@ -18,39 +18,43 @@ #[cfg(feature = "evm")] use sp_core::{H160, H256, U256}; -use crate::{ - best_energy_helpers::storage::merkle_roots_map_key, helpers::ensure_enclave_signer_account, - StfError, TrustedOperation, -}; -use binary_merkle_tree::merkle_root; -use codec::{alloc::sync::Arc, Decode, Encode}; +#[cfg(feature = "evm")] +use std::vec::Vec; + +use crate::{helpers::ensure_enclave_signer_account, StfError, TrustedOperation}; +use codec::{Compact, Decode, Encode}; use frame_support::{ensure, traits::UnfilteredDispatchable}; +#[cfg(feature = "evm")] +use ita_sgx_runtime::{AddressMapping, HashedAddressMapping}; pub use ita_sgx_runtime::{Balance, Index}; use ita_sgx_runtime::{Runtime, System}; use itp_node_api::metadata::{provider::AccessNodeMetadata, NodeMetadataTrait}; -use itp_node_api_metadata::pallet_enclave_bridge::EnclaveBridgeCallIndexes; -use itp_stf_interface::ExecuteCall; -use itp_stf_primitives::types::{AccountId, KeyPair, OrdersString, ShardIdentifier, Signature}; -use itp_types::OpaqueCall; +use itp_node_api_metadata::{ + pallet_balances::BalancesCallIndexes, pallet_enclave_bridge::EnclaveBridgeCallIndexes, + pallet_proxy::ProxyCallIndexes, +}; +use itp_stf_interface::{ExecuteCall, SHARD_VAULT_KEY}; +use itp_stf_primitives::types::{AccountId, KeyPair, ShardIdentifier, Signature}; +use itp_types::{parentchain::ProxyType, Address, OpaqueCall}; use itp_utils::stringify::account_id_to_string; use log::*; -use simplyr_lib::{pay_as_bid_matching, MarketInput, MarketOutput, Order}; use sp_io::hashing::blake2_256; -use sp_runtime::{ - traits::{Keccak256, Verify}, - MultiAddress, -}; -#[cfg(feature = "evm")] -use std::vec::Vec; -use std::{format, fs, prelude::v1::*, time::Instant}; - -#[cfg(feature = "evm")] -use ita_sgx_runtime::{AddressMapping, HashedAddressMapping}; +use sp_runtime::{traits::Verify, MultiAddress}; +use std::{format, prelude::v1::*, sync::Arc}; #[cfg(feature = "evm")] use crate::evm_helpers::{create_code_hash, evm_create2_address, evm_create_address}; +use crate::helpers::get_storage_by_key_hash; -use crate::best_energy_helpers::{write_orders, write_results, ORDERS_DIR, RESULTS_DIR}; +// Group imports that are for OLI to make upstream merges easier. +use crate::best_energy_helpers::{ + storage::merkle_roots_map_key, write_orders, write_results, ORDERS_DIR, RESULTS_DIR, +}; +use binary_merkle_tree::merkle_root; +use itp_stf_primitives::types::OrdersString; +use simplyr_lib::{pay_as_bid_matching, MarketInput, MarketOutput, Order}; +use sp_runtime::traits::Keccak256; +use std::{fs, time::Instant}; #[derive(Encode, Decode, Clone, Debug, PartialEq, Eq)] #[allow(non_camel_case_types)] @@ -253,13 +257,35 @@ where shard ); unshield_funds(account_incognito, value)?; + calls.push(OpaqueCall::from_tuple(&( node_metadata_repo.get_from_metadata(|m| m.unshield_funds_call_indexes())??, shard, - beneficiary, + beneficiary.clone(), value, call_hash, ))); + // todo: the following is a placeholder dummy which will replace the above with #1257. + // the extrinsic will be sent and potentially deplete the vault at the current state which + // is nothing to worry about before we solve mentioned issue. + let vault_pubkey: [u8; 32] = get_storage_by_key_hash(SHARD_VAULT_KEY.into()) + .ok_or_else(|| { + StfError::Dispatch("shard vault key hasn't been set".to_string()) + })?; + let vault_address = Address::from(AccountId::from(vault_pubkey)); + let vault_transfer_call = OpaqueCall::from_tuple(&( + node_metadata_repo + .get_from_metadata(|m| m.transfer_keep_alive_call_indexes())??, + Address::from(beneficiary), + Compact(value), + )); + let proxy_call = OpaqueCall::from_tuple(&( + node_metadata_repo.get_from_metadata(|m| m.proxy_call_indexes())??, + vault_address, + None::, + vault_transfer_call, + )); + calls.push(proxy_call); Ok(()) }, TrustedCall::balance_shield(enclave_account, who, value) => { diff --git a/build.Dockerfile b/build.Dockerfile index b3c356070b..090b9443f2 100644 --- a/build.Dockerfile +++ b/build.Dockerfile @@ -124,14 +124,17 @@ WORKDIR /usr/local/bin COPY --from=builder /opt/sgxsdk /opt/sgxsdk COPY --from=builder /home/ubuntu/work/worker/bin/* ./ +COPY --from=builder /home/ubuntu/work/worker/extract_identity ./ COPY --from=builder /lib/x86_64-linux-gnu/libsgx* /lib/x86_64-linux-gnu/ COPY --from=builder /lib/x86_64-linux-gnu/libdcap* /lib/x86_64-linux-gnu/ RUN chmod +x /usr/local/bin/integritee-service +RUN chmod +x /usr/local/bin/extract_identity RUN ls -al /usr/local/bin # checks ENV SGX_SDK /opt/sgxsdk +ENV SGX_ENCLAVE_SIGNER $SGX_SDK/bin/x64/sgx_sign ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/intel/sgx-aesm-service/aesm:$SGX_SDK/sdk_libs ENV AESM_PATH=/opt/intel/sgx-aesm-service/aesm diff --git a/core-primitives/attestation-handler/src/attestation_handler.rs b/core-primitives/attestation-handler/src/attestation_handler.rs index 91bfc77f3a..59e4988be2 100644 --- a/core-primitives/attestation-handler/src/attestation_handler.rs +++ b/core-primitives/attestation-handler/src/attestation_handler.rs @@ -279,6 +279,8 @@ where let _result = ecc_handle.open(); let (prv_k, pub_k) = ecc_handle.create_key_pair()?; info!("Enclave Attestation] Generated ephemeral ECDSA keypair:"); + debug!(" pubkey X is {:02x}", pub_k.gx.iter().format("")); + debug!(" pubkey Y is {:02x}", pub_k.gy.iter().format("")); let qe_quote = if !skip_ra { let qe_quote = match self.retrieve_qe_dcap_quote( diff --git a/core-primitives/attestation-handler/src/cert.rs b/core-primitives/attestation-handler/src/cert.rs index 99c0d8529b..7d1a2d6064 100644 --- a/core-primitives/attestation-handler/src/cert.rs +++ b/core-primitives/attestation-handler/src/cert.rs @@ -234,6 +234,31 @@ pub fn percent_decode(orig: String) -> EnclaveResult { Ok(ret) } +pub fn parse_cert_issuer(cert_der: &[u8]) -> SgxResult> { + // Before we reach here, Webpki already verified the cert is properly signed + + // Search for Public Key prime256v1 OID + let prime256v1_oid = &[0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07]; + let mut offset = cert_der + .windows(prime256v1_oid.len()) + .position(|window| window == prime256v1_oid) + .ok_or(sgx_status_t::SGX_ERROR_UNEXPECTED)?; + offset += 11; // 10 + TAG (0x03) + + // Obtain Public Key length + let mut len = cert_der[offset] as usize; + if len > 0x80 { + len = (cert_der[offset + 1] as usize) * 0x100 + (cert_der[offset + 2] as usize); + offset += 2; + } + + // Obtain Public Key + offset += 1; + let pub_k = cert_der[offset + 2..offset + len].to_vec(); // skip "00 04" + + Ok(pub_k) +} + // FIXME: This code is redundant with the host call of the integritee-node pub fn verify_mra_cert( cert_der: &[u8], @@ -346,6 +371,7 @@ where verify_attn_report(attn_report_raw, pub_k, attestation_ocall) } else { // TODO Refactor state provisioning to not use MURA #1385 + // TODO DCAP is currently just passed through! SECURITY!!! Ok(()) } } diff --git a/core-primitives/enclave-api/ffi/src/lib.rs b/core-primitives/enclave-api/ffi/src/lib.rs index cbdfcd09a0..12115521e1 100644 --- a/core-primitives/enclave-api/ffi/src/lib.rs +++ b/core-primitives/enclave-api/ffi/src/lib.rs @@ -57,6 +57,13 @@ extern "C" { shard_size: u32, ) -> sgx_status_t; + pub fn init_proxied_shard_vault( + eid: sgx_enclave_id_t, + retval: *mut sgx_status_t, + shard: *const u8, + shard_size: u32, + ) -> sgx_status_t; + pub fn trigger_parentchain_block_import( eid: sgx_enclave_id_t, retval: *mut sgx_status_t, @@ -110,6 +117,15 @@ extern "C" { pubkey_size: u32, ) -> sgx_status_t; + pub fn get_ecc_vault_pubkey( + eid: sgx_enclave_id_t, + retval: *mut sgx_status_t, + shard: *const u8, + shard_size: u32, + pubkey: *mut u8, + pubkey_size: u32, + ) -> sgx_status_t; + pub fn get_mrenclave( eid: sgx_enclave_id_t, retval: *mut sgx_status_t, diff --git a/core-primitives/enclave-api/src/enclave_base.rs b/core-primitives/enclave-api/src/enclave_base.rs index def5d3ee47..6ef543656c 100644 --- a/core-primitives/enclave-api/src/enclave_base.rs +++ b/core-primitives/enclave-api/src/enclave_base.rs @@ -25,6 +25,7 @@ use itp_enclave_api_ffi as ffi; use itp_settings::worker::{ HEADER_MAX_SIZE, MR_ENCLAVE_SIZE, SHIELDING_KEY_SIZE, SIGNING_KEY_SIZE, }; +use itp_types::ShardIdentifier; use log::*; use sgx_crypto_helper::rsa3072::Rsa3072PubKey; use sgx_types::*; @@ -56,6 +57,9 @@ pub trait EnclaveBase: Send + Sync + 'static { /// Initialize a new shard. fn init_shard(&self, shard: Vec) -> EnclaveResult<()>; + /// Initialize a new shard vault account and register enclave signer as its proxy. + fn init_proxied_shard_vault(&self, shard: &ShardIdentifier) -> EnclaveResult<()>; + /// Trigger the import of parentchain block explicitly. Used when initializing a light-client /// with a triggered import dispatcher. fn trigger_parentchain_block_import(&self, parentchain_id: &ParentchainId) @@ -73,6 +77,9 @@ pub trait EnclaveBase: Send + Sync + 'static { fn get_ecc_signing_pubkey(&self) -> EnclaveResult; + /// retrieve vault account from shard state + fn get_ecc_vault_pubkey(&self, shard: &ShardIdentifier) -> EnclaveResult; + fn get_fingerprint(&self) -> EnclaveResult; } @@ -164,6 +171,24 @@ impl EnclaveBase for Enclave { Ok(()) } + fn init_proxied_shard_vault(&self, shard: &ShardIdentifier) -> EnclaveResult<()> { + let mut retval = sgx_status_t::SGX_SUCCESS; + + let shard_bytes = shard.encode(); + let result = unsafe { + ffi::init_proxied_shard_vault( + self.eid, + &mut retval, + shard_bytes.as_ptr(), + shard_bytes.len() as u32, + ) + }; + + ensure!(result == sgx_status_t::SGX_SUCCESS, Error::Sgx(result)); + ensure!(retval == sgx_status_t::SGX_SUCCESS, Error::Sgx(retval)); + + Ok(()) + } fn trigger_parentchain_block_import( &self, parentchain_id: &ParentchainId, @@ -276,6 +301,28 @@ impl EnclaveBase for Enclave { Ok(ed25519::Public::from_raw(pubkey)) } + fn get_ecc_vault_pubkey(&self, shard: &ShardIdentifier) -> EnclaveResult { + let mut retval = sgx_status_t::SGX_SUCCESS; + let mut pubkey = [0u8; SIGNING_KEY_SIZE]; + let shard_bytes = shard.encode(); + + let result = unsafe { + ffi::get_ecc_vault_pubkey( + self.eid, + &mut retval, + shard_bytes.as_ptr(), + shard_bytes.len() as u32, + pubkey.as_mut_ptr(), + pubkey.len() as u32, + ) + }; + + ensure!(result == sgx_status_t::SGX_SUCCESS, Error::Sgx(result)); + ensure!(retval == sgx_status_t::SGX_SUCCESS, Error::Sgx(retval)); + + Ok(ed25519::Public::from_raw(pubkey)) + } + fn get_fingerprint(&self) -> EnclaveResult { let mut retval = sgx_status_t::SGX_SUCCESS; let mut mr_enclave = [0u8; MR_ENCLAVE_SIZE]; diff --git a/core-primitives/extrinsics-factory/src/lib.rs b/core-primitives/extrinsics-factory/src/lib.rs index 2b226510c8..0744d1b657 100644 --- a/core-primitives/extrinsics-factory/src/lib.rs +++ b/core-primitives/extrinsics-factory/src/lib.rs @@ -88,6 +88,15 @@ where ) -> Self { ExtrinsicsFactory { genesis_hash, signer, nonce_cache, node_metadata_repository } } + + pub fn with_signer(&self, signer: Signer, nonce_cache: Arc) -> Self { + ExtrinsicsFactory { + genesis_hash: self.genesis_hash, + signer, + nonce_cache, + node_metadata_repository: self.node_metadata_repository.clone(), + } + } } impl CreateExtrinsics @@ -170,6 +179,33 @@ pub mod tests { assert_eq!(nonce_cache.get_nonce().unwrap(), Nonce(opaque_calls.len() as NonceValue)); } + #[test] + pub fn with_signer_works() { + let nonce_cache1 = Arc::new(NonceCache::default()); + *nonce_cache1.load_for_mutation().unwrap() = Nonce(42); + + let node_metadata_repo = Arc::new(NodeMetadataRepository::new(NodeMetadata::default())); + let extrinsics_factory = ExtrinsicsFactory::new( + test_genesis_hash(), + StaticExtrinsicSigner::<_, PairSignature>::new(test_account()), + nonce_cache1.clone(), + node_metadata_repo, + ); + + let nonce_cache2 = Arc::new(NonceCache::default()); + let extrinsics_factory = extrinsics_factory.with_signer( + StaticExtrinsicSigner::<_, PairSignature>::new(test_account2()), + nonce_cache2.clone(), + ); + + let opaque_calls = [OpaqueCall(vec![3u8; 42]), OpaqueCall(vec![12u8, 78])]; + let xts = extrinsics_factory.create_extrinsics(&opaque_calls, None).unwrap(); + + assert_eq!(opaque_calls.len(), xts.len()); + assert_eq!(nonce_cache2.get_nonce().unwrap(), Nonce(opaque_calls.len() as NonceValue)); + assert_eq!(nonce_cache1.get_nonce().unwrap(), Nonce(42)); + } + // #[test] // pub fn xts_have_increasing_nonce() { // let nonce_cache = Arc::new(NonceCache::default()); @@ -194,6 +230,10 @@ pub mod tests { ed25519::Pair::from_seed(b"42315678901234567890123456789012") } + fn test_account2() -> ed25519::Pair { + ed25519::Pair::from_seed(b"12315678901234567890123456789012") + } + fn test_genesis_hash() -> H256 { H256::from_slice(&[56u8; 32]) } diff --git a/core-primitives/node-api/metadata/src/lib.rs b/core-primitives/node-api/metadata/src/lib.rs index 55f66e35dc..648876eb40 100644 --- a/core-primitives/node-api/metadata/src/lib.rs +++ b/core-primitives/node-api/metadata/src/lib.rs @@ -20,7 +20,8 @@ #![cfg_attr(not(feature = "std"), no_std)] use crate::{ - error::Result, pallet_enclave_bridge::EnclaveBridgeCallIndexes, + error::Result, pallet_balances::BalancesCallIndexes, + pallet_enclave_bridge::EnclaveBridgeCallIndexes, pallet_proxy::ProxyCallIndexes, pallet_sidechain::SidechainCallIndexes, pallet_teerex::TeerexCallIndexes, }; use codec::{Decode, Encode}; @@ -32,6 +33,7 @@ pub use itp_api_client_types::{Metadata, MetadataError}; pub mod error; pub mod pallet_balances; pub mod pallet_enclave_bridge; +pub mod pallet_proxy; pub mod pallet_sidechain; pub mod pallet_teeracle; pub mod pallet_teerex; @@ -40,11 +42,20 @@ pub mod pallet_teerex; pub mod metadata_mocks; pub trait NodeMetadataTrait: - TeerexCallIndexes + EnclaveBridgeCallIndexes + SidechainCallIndexes + TeerexCallIndexes + + EnclaveBridgeCallIndexes + + SidechainCallIndexes + + ProxyCallIndexes + + BalancesCallIndexes { } -impl NodeMetadataTrait - for T +impl< + T: TeerexCallIndexes + + EnclaveBridgeCallIndexes + + SidechainCallIndexes + + ProxyCallIndexes + + BalancesCallIndexes, + > NodeMetadataTrait for T { } diff --git a/core-primitives/node-api/metadata/src/metadata_mocks.rs b/core-primitives/node-api/metadata/src/metadata_mocks.rs index 57cf0fe327..8bf47298ec 100644 --- a/core-primitives/node-api/metadata/src/metadata_mocks.rs +++ b/core-primitives/node-api/metadata/src/metadata_mocks.rs @@ -16,11 +16,12 @@ */ use crate::{ - error::Result, pallet_sidechain::SidechainCallIndexes, pallet_teerex::TeerexCallIndexes, + error::Result, pallet_balances::BalancesCallIndexes, + pallet_enclave_bridge::EnclaveBridgeCallIndexes, pallet_proxy::ProxyCallIndexes, + pallet_sidechain::SidechainCallIndexes, pallet_teerex::TeerexCallIndexes, }; use codec::{Decode, Encode}; -use crate::pallet_enclave_bridge::EnclaveBridgeCallIndexes; use itp_api_client_types::Metadata; impl TryFrom for Metadata { @@ -48,6 +49,13 @@ pub struct NodeMetadataMock { update_shard_config: u8, sidechain_module: u8, imported_sidechain_block: u8, + proxy_module: u8, + add_proxy: u8, + proxy: u8, + balances_module: u8, + transfer: u8, + transfer_keep_alive: u8, + transfer_allow_death: u8, runtime_spec_version: u32, runtime_transaction_version: u32, } @@ -70,6 +78,13 @@ impl NodeMetadataMock { update_shard_config: 5u8, sidechain_module: 53u8, imported_sidechain_block: 0u8, + proxy_module: 7u8, + add_proxy: 1u8, + proxy: 0u8, + balances_module: 10u8, + transfer: 7u8, + transfer_keep_alive: 3u8, + transfer_allow_death: 0u8, runtime_spec_version: 25, runtime_transaction_version: 4, } @@ -129,3 +144,27 @@ impl SidechainCallIndexes for NodeMetadataMock { Ok([self.sidechain_module, self.imported_sidechain_block]) } } + +impl ProxyCallIndexes for NodeMetadataMock { + fn add_proxy_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.proxy_module, self.add_proxy]) + } + + fn proxy_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.proxy_module, self.proxy]) + } +} + +impl BalancesCallIndexes for NodeMetadataMock { + fn transfer_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.balances_module, self.transfer]) + } + + fn transfer_keep_alive_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.balances_module, self.transfer_keep_alive]) + } + + fn transfer_allow_death_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.balances_module, self.transfer_allow_death]) + } +} diff --git a/core-primitives/node-api/metadata/src/pallet_balances.rs b/core-primitives/node-api/metadata/src/pallet_balances.rs index 185f0efff3..9ae88dd742 100644 --- a/core-primitives/node-api/metadata/src/pallet_balances.rs +++ b/core-primitives/node-api/metadata/src/pallet_balances.rs @@ -21,17 +21,23 @@ use crate::{error::Result, NodeMetadata}; const BALANCES: &str = "Balances"; pub trait BalancesCallIndexes { - fn transfer_call_index(&self) -> Result<[u8; 2]>; + fn transfer_call_indexes(&self) -> Result<[u8; 2]>; - fn transfer_allow_death_call_index(&self) -> Result<[u8; 2]>; + fn transfer_keep_alive_call_indexes(&self) -> Result<[u8; 2]>; + + fn transfer_allow_death_call_indexes(&self) -> Result<[u8; 2]>; } impl BalancesCallIndexes for NodeMetadata { - fn transfer_call_index(&self) -> Result<[u8; 2]> { + fn transfer_call_indexes(&self) -> Result<[u8; 2]> { self.call_indexes(BALANCES, "transfer") } - fn transfer_allow_death_call_index(&self) -> Result<[u8; 2]> { + fn transfer_keep_alive_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(BALANCES, "transfer_keep_alive") + } + + fn transfer_allow_death_call_indexes(&self) -> Result<[u8; 2]> { self.call_indexes(BALANCES, "transfer_allow_death") } } diff --git a/core-primitives/node-api/metadata/src/pallet_proxy.rs b/core-primitives/node-api/metadata/src/pallet_proxy.rs new file mode 100644 index 0000000000..6a7aa14b08 --- /dev/null +++ b/core-primitives/node-api/metadata/src/pallet_proxy.rs @@ -0,0 +1,39 @@ +/* + Copyright 2021 Integritee AG and Supercomputing Systems AG + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +use crate::{error::Result, NodeMetadata}; + +/// Pallet name: +const PROXY: &str = "Proxy"; +/// the deposit needed to register up to 20 proxies in native parentchain token +pub const PROXY_DEPOSIT: u128 = 21_000_000_000_000; + +pub trait ProxyCallIndexes { + fn add_proxy_call_indexes(&self) -> Result<[u8; 2]>; + + fn proxy_call_indexes(&self) -> Result<[u8; 2]>; +} + +impl ProxyCallIndexes for NodeMetadata { + fn add_proxy_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(PROXY, "add_proxy") + } + + fn proxy_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(PROXY, "proxy") + } +} diff --git a/core-primitives/ocall-api/src/lib.rs b/core-primitives/ocall-api/src/lib.rs index 2bd1ca2104..503a4b5a4c 100644 --- a/core-primitives/ocall-api/src/lib.rs +++ b/core-primitives/ocall-api/src/lib.rs @@ -93,6 +93,7 @@ pub trait EnclaveOnChainOCallApi: Clone + Send + Sync { &self, extrinsics: Vec, parentchain_id: &ParentchainId, + await_each_inclusion: bool, ) -> SgxResult<()>; fn worker_request( diff --git a/core-primitives/stf-executor/Cargo.toml b/core-primitives/stf-executor/Cargo.toml index ee844db96f..da91248f70 100644 --- a/core-primitives/stf-executor/Cargo.toml +++ b/core-primitives/stf-executor/Cargo.toml @@ -5,6 +5,8 @@ authors = ["Integritee AG "] edition = "2021" [dependencies] +hex = { version = "0.4.3", default-features = false, features = ["alloc"] } + # sgx dependencies sgx-crypto-helper = { branch = "master", git = "https://github.com/apache/teaclave-sgx-sdk.git", package = "sgx_crypto_helper", default-features = false, optional = true } sgx_tstd = { branch = "master", git = "https://github.com/apache/teaclave-sgx-sdk.git", optional = true, features = ["untrusted_time"] } diff --git a/core-primitives/stf-executor/src/executor.rs b/core-primitives/stf-executor/src/executor.rs index 3c5f53afb9..a40eb84445 100644 --- a/core-primitives/stf-executor/src/executor.rs +++ b/core-primitives/stf-executor/src/executor.rs @@ -127,6 +127,9 @@ where state.prune_state_diff(); } + for call in extrinsic_call_backs.clone() { + trace!("trusted_call wants to send encoded call: 0x{}", hex::encode(call.encode())); + } Ok(ExecutedOperation::success(operation_hash, top_or_hash, extrinsic_call_backs)) } } diff --git a/core-primitives/stf-interface/src/lib.rs b/core-primitives/stf-interface/src/lib.rs index 66ae77495b..e88104351e 100644 --- a/core-primitives/stf-interface/src/lib.rs +++ b/core-primitives/stf-interface/src/lib.rs @@ -33,6 +33,8 @@ pub mod parentchain_pallet; pub mod sudo_pallet; pub mod system_pallet; +pub const SHARD_VAULT_KEY: &str = "ShardVaultPubKey"; + /// Interface to initialize a new state. pub trait InitState { /// Initialize a new state for a given enclave account. diff --git a/core-primitives/test/src/mock/onchain_mock.rs b/core-primitives/test/src/mock/onchain_mock.rs index 1ed4efdc0f..4101636f93 100644 --- a/core-primitives/test/src/mock/onchain_mock.rs +++ b/core-primitives/test/src/mock/onchain_mock.rs @@ -180,6 +180,7 @@ impl EnclaveOnChainOCallApi for OnchainMock { &self, _extrinsics: Vec, _: &ParentchainId, + _: bool, ) -> SgxResult<()> { Ok(()) } diff --git a/core-primitives/types/src/parentchain.rs b/core-primitives/types/src/parentchain.rs index 32610d0aa9..6439929129 100644 --- a/core-primitives/types/src/parentchain.rs +++ b/core-primitives/types/src/parentchain.rs @@ -33,6 +33,15 @@ pub type AccountId = sp_core::crypto::AccountId32; pub type AccountData = pallet_balances::AccountData; pub type AccountInfo = frame_system::AccountInfo; pub type Address = MultiAddress; +// todo! make generic +/// The type used to represent the kinds of proxying allowed. +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)] +pub enum ProxyType { + Any, + NonTransfer, + Governance, + Staking, +} // Block Types pub type BlockNumber = u32; diff --git a/core/parentchain/indirect-calls-executor/src/filter_metadata.rs b/core/parentchain/indirect-calls-executor/src/filter_metadata.rs index dd95b8b0bf..a2adc3c891 100644 --- a/core/parentchain/indirect-calls-executor/src/filter_metadata.rs +++ b/core/parentchain/indirect-calls-executor/src/filter_metadata.rs @@ -174,10 +174,13 @@ where let index = xt.call_index; let call_args = &mut &xt.call_args[..]; log::trace!("[TransferToAliceShieldsFundsFilter] attempting to execute indirect call with index {:?}", index); - if index == metadata.transfer_call_index().ok()? - || index == metadata.transfer_allow_death_call_index().ok()? + if index == metadata.transfer_call_indexes().ok()? + || index == metadata.transfer_keep_alive_call_indexes().ok()? + || index == metadata.transfer_allow_death_call_indexes().ok()? { - log::debug!("found `transfer` or `transfer_allow_death` call."); + log::debug!( + "found `transfer` or `transfer_allow_death` or `transfer_keep_alive` call." + ); let args = decode_and_log_error::(call_args)?; if args.destination == ALICE_ACCOUNT_ID.into() { Some(IndirectCall::TransferToAliceShieldsFunds(args)) diff --git a/core/parentchain/light-client/src/light_validation.rs b/core/parentchain/light-client/src/light_validation.rs index 3eda5c8490..5da9db71d6 100644 --- a/core/parentchain/light-client/src/light_validation.rs +++ b/core/parentchain/light-client/src/light_validation.rs @@ -164,7 +164,7 @@ where { fn send_extrinsics(&mut self, extrinsics: Vec) -> Result<(), Error> { self.ocall_api - .send_to_parentchain(extrinsics, &self.parentchain_id) + .send_to_parentchain(extrinsics, &self.parentchain_id, false) .map_err(|e| { Error::Other( format!("[{:?}] Failed to send extrinsics: {}", self.parentchain_id, e).into(), diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index bceee8d4be..3e4572b6bc 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -1,7 +1,19 @@ #!/bin/bash set -e -# run aesmd in the background -/opt/intel/sgx-aesm-service/aesm/aesm_service +# Check if the first argument is "mrenclave" +if [ "$1" = "mrenclave" ]; then + # If "mrenclave" is provided, execute the corresponding command + $SGX_ENCLAVE_SIGNER dump \ + -enclave /usr/local/bin/enclave.signed.so \ + -dumpfile df.out && \ + /usr/local/bin/extract_identity < df.out && rm df.out | grep -oP ':\s*\K[a-fA-F0-9]+' -exec /usr/local/bin/integritee-service "${@}" +else + # If no specific command is provided, execute the default unnamed command + + # run aesmd in the background + /opt/intel/sgx-aesm-service/aesm/aesm_service + + exec /usr/local/bin/integritee-service "${@}" +fi \ No newline at end of file diff --git a/enclave-runtime/Cargo.lock b/enclave-runtime/Cargo.lock index e73e2a24f0..29dd4bdf15 100644 --- a/enclave-runtime/Cargo.lock +++ b/enclave-runtime/Cargo.lock @@ -257,15 +257,7 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "binary-merkle-tree" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" -dependencies = [ - "hash-db 0.16.0", -] - -[[package]] -name = "binary-merkle-tree" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git#28b1f79abedbad2ec97b49277b36e1f797ca9e5d" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "hash-db 0.16.0", ] @@ -1091,7 +1083,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "frame-support", "frame-system", @@ -1204,7 +1196,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "parity-scale-codec", "sp-api", @@ -1705,7 +1697,6 @@ dependencies = [ name = "ita-stf" version = "0.9.0" dependencies = [ - "binary-merkle-tree 4.0.0-dev (git+https://github.com/paritytech/substrate.git)", "derive_more", "frame-support", "frame-system", @@ -1726,11 +1717,8 @@ dependencies = [ "pallet-sudo", "parity-scale-codec", "rlp", - "serde 1.0.188", - "serde_json 1.0.96", "sgx_tstd", "sha3 0.10.8", - "simplyr-lib", "sp-application-crypto", "sp-core", "sp-io", @@ -1824,7 +1812,7 @@ dependencies = [ name = "itc-parentchain-indirect-calls-executor" version = "0.9.0" dependencies = [ - "binary-merkle-tree 4.0.0-dev (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42)", + "binary-merkle-tree", "bs58", "futures 0.3.8", "ita-stf", @@ -2197,6 +2185,7 @@ dependencies = [ name = "itp-stf-executor" version = "0.9.0" dependencies = [ + "hex", "ita-stf", "itc-parentchain-test", "itp-node-api", @@ -2674,12 +2663,6 @@ version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" -[[package]] -name = "libm" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" - [[package]] name = "libsecp256k1" version = "0.7.1" @@ -2978,7 +2961,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pallet-aura" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "frame-support", "frame-system", @@ -2994,7 +2977,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "frame-support", "frame-system", @@ -3008,7 +2991,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "frame-support", "frame-system", @@ -3044,7 +3027,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "frame-support", "frame-system", @@ -3066,7 +3049,7 @@ dependencies = [ [[package]] name = "pallet-insecure-randomness-collective-flip" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "frame-support", "frame-system", @@ -3096,7 +3079,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "frame-support", "frame-system", @@ -3116,7 +3099,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "frame-support", "frame-system", @@ -3130,7 +3113,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "frame-support", "frame-system", @@ -3146,7 +3129,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "frame-support", "frame-system", @@ -3161,7 +3144,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -4147,17 +4130,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "simplyr-lib" -version = "0.1.0" -source = "git+https://github.com/BESTenergytrade/simplyr-lib.git?branch=cI/usize#ec8e1266141112a75b304cecfa2da35bfdde215c" -dependencies = [ - "libm", - "parity-scale-codec", - "serde 1.0.188", - "serde_json 1.0.96", -] - [[package]] name = "slab" version = "0.4.2" @@ -4247,7 +4219,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "parity-scale-codec", "sp-api", @@ -4259,7 +4231,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "parity-scale-codec", "scale-info", @@ -4275,7 +4247,7 @@ dependencies = [ [[package]] name = "sp-consensus-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "finality-grandpa", "log", @@ -4291,7 +4263,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "parity-scale-codec", "scale-info", @@ -4423,7 +4395,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "sp-api", "sp-core", @@ -4483,7 +4455,7 @@ dependencies = [ [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "parity-scale-codec", "scale-info", @@ -4524,7 +4496,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -4546,7 +4518,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "sp-api", "sp-runtime", @@ -4555,7 +4527,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "hash-db 0.16.0", "memory-db", @@ -4913,7 +4885,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "digest 0.10.7", "static_assertions", ] diff --git a/enclave-runtime/Enclave.edl b/enclave-runtime/Enclave.edl index c8cf058ec1..544e988b1a 100644 --- a/enclave-runtime/Enclave.edl +++ b/enclave-runtime/Enclave.edl @@ -58,6 +58,10 @@ enclave { [in, size=shard_size] uint8_t* shard, uint32_t shard_size ); + public sgx_status_t init_proxied_shard_vault( + [in, size=shard_size] uint8_t* shard, uint32_t shard_size + ); + public sgx_status_t trigger_parentchain_block_import( [in, size=parentchain_id_size] uint8_t* parentchain_id, uint32_t parentchain_id_size ); @@ -87,6 +91,10 @@ enclave { public sgx_status_t get_ecc_signing_pubkey( [out, size=pubkey_size] uint8_t* pubkey, uint32_t pubkey_size); + public sgx_status_t get_ecc_vault_pubkey( + [in, size=shard_size] uint8_t* shard, uint32_t shard_size, + [out, size=pubkey_size] uint8_t* pubkey, uint32_t pubkey_size); + public sgx_status_t get_mrenclave( [out, size=mrenclave_size] uint8_t* mrenclave, uint32_t mrenclave_size); @@ -242,7 +250,8 @@ enclave { sgx_status_t ocall_send_to_parentchain( [in, size = extrinsics_size] uint8_t * extrinsics, uint32_t extrinsics_size, - [in, size=parentchain_id_size] uint8_t* parentchain_id, uint32_t parentchain_id_size + [in, size=parentchain_id_size] uint8_t* parentchain_id, uint32_t parentchain_id_size, + int await_each_inclusion ); }; }; diff --git a/enclave-runtime/src/attestation.rs b/enclave-runtime/src/attestation.rs index ae609f279b..857578c431 100644 --- a/enclave-runtime/src/attestation.rs +++ b/enclave-runtime/src/attestation.rs @@ -30,7 +30,7 @@ use crate::{ initialization::global_components::GLOBAL_ATTESTATION_HANDLER_COMPONENT, utils::{ - get_extrinsic_factory_from_solo_or_parachain, + get_extrinsic_factory_from_integritee_solo_or_parachain, get_node_metadata_repository_from_integritee_solo_or_parachain, }, Error as EnclaveError, Result as EnclaveResult, @@ -381,7 +381,7 @@ pub fn generate_ias_skip_ra_extrinsic_from_der_cert_internal( } fn create_extrinsics(call: OpaqueCall) -> EnclaveResult { - let extrinsics_factory = get_extrinsic_factory_from_solo_or_parachain()?; + let extrinsics_factory = get_extrinsic_factory_from_integritee_solo_or_parachain()?; let extrinsics = extrinsics_factory.create_extrinsics(&[call], None)?; Ok(extrinsics[0].clone()) @@ -459,7 +459,7 @@ pub fn generate_generic_register_collateral_extrinsic( where F: Fn(&NodeMetadata) -> Result<[u8; 2], MetadataError>, { - let extrinsics_factory = get_extrinsic_factory_from_solo_or_parachain()?; + let extrinsics_factory = get_extrinsic_factory_from_integritee_solo_or_parachain()?; let node_metadata_repo = get_node_metadata_repository_from_integritee_solo_or_parachain()?; let call_ids = node_metadata_repo diff --git a/enclave-runtime/src/initialization/mod.rs b/enclave-runtime/src/initialization/mod.rs index 0573c11c5c..cb65c12cfd 100644 --- a/enclave-runtime/src/initialization/mod.rs +++ b/enclave-runtime/src/initialization/mod.rs @@ -41,7 +41,7 @@ use crate::{ ocall::OcallApi, rpc::{rpc_response_channel::RpcResponseChannel, worker_api_direct::public_api_rpc_handler}, utils::{ - get_extrinsic_factory_from_solo_or_parachain, + get_extrinsic_factory_from_integritee_solo_or_parachain, get_node_metadata_repository_from_integritee_solo_or_parachain, get_triggered_dispatcher_from_solo_or_parachain, get_validator_accessor_from_solo_or_parachain, @@ -80,7 +80,6 @@ use its_sidechain::block_composer::BlockComposer; use log::*; use sp_core::crypto::Pair; use std::{collections::HashMap, path::PathBuf, string::String, sync::Arc}; - pub(crate) fn init_enclave( mu_ra_url: String, untrusted_worker_url: String, @@ -226,7 +225,7 @@ pub(crate) fn init_enclave_sidechain_components() -> EnclaveResult<()> { let sidechain_block_import_queue = GLOBAL_SIDECHAIN_IMPORT_QUEUE_COMPONENT.get()?; let metadata_repository = get_node_metadata_repository_from_integritee_solo_or_parachain()?; - let extrinsics_factory = get_extrinsic_factory_from_solo_or_parachain()?; + let extrinsics_factory = get_extrinsic_factory_from_integritee_solo_or_parachain()?; let validator_accessor = get_validator_accessor_from_solo_or_parachain()?; let sidechain_block_import_confirmation_handler = diff --git a/enclave-runtime/src/lib.rs b/enclave-runtime/src/lib.rs index 3379bcfe4b..7c375b8205 100644 --- a/enclave-runtime/src/lib.rs +++ b/enclave-runtime/src/lib.rs @@ -74,12 +74,12 @@ use std::{ string::{String, ToString}, vec::Vec, }; - mod attestation; mod empty_impls; mod initialization; mod ipfs; mod ocall; +mod shard_vault; mod utils; pub mod error; diff --git a/enclave-runtime/src/ocall/ffi.rs b/enclave-runtime/src/ocall/ffi.rs index 4db3bbbba4..acd63ffa46 100644 --- a/enclave-runtime/src/ocall/ffi.rs +++ b/enclave-runtime/src/ocall/ffi.rs @@ -113,6 +113,7 @@ extern "C" { extrinsics_size: u32, parentchain_id: *const u8, parentchain_id_size: u32, + await_each_inclusion: c_int, ) -> sgx_status_t; pub fn ocall_read_ipfs( diff --git a/enclave-runtime/src/ocall/on_chain_ocall.rs b/enclave-runtime/src/ocall/on_chain_ocall.rs index d79c5d5540..e71fb72618 100644 --- a/enclave-runtime/src/ocall/on_chain_ocall.rs +++ b/enclave-runtime/src/ocall/on_chain_ocall.rs @@ -33,6 +33,7 @@ impl EnclaveOnChainOCallApi for OcallApi { &self, extrinsics: Vec, parentchain_id: &ParentchainId, + await_each_inclusion: bool, ) -> SgxResult<()> { let mut rt: sgx_status_t = sgx_status_t::SGX_ERROR_UNEXPECTED; let extrinsics_encoded = extrinsics.encode(); @@ -45,6 +46,7 @@ impl EnclaveOnChainOCallApi for OcallApi { extrinsics_encoded.len() as u32, parentchain_id_encoded.as_ptr(), parentchain_id_encoded.len() as u32, + await_each_inclusion.into(), ) }; diff --git a/enclave-runtime/src/shard_vault.rs b/enclave-runtime/src/shard_vault.rs new file mode 100644 index 0000000000..860f2ef56d --- /dev/null +++ b/enclave-runtime/src/shard_vault.rs @@ -0,0 +1,208 @@ +/* + Copyright 2021 Integritee AG + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +use crate::{ + error::{Error, Result as EnclaveResult}, + initialization::global_components::{ + GLOBAL_OCALL_API_COMPONENT, GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT, + GLOBAL_STATE_HANDLER_COMPONENT, + }, + utils::{ + get_extrinsic_factory_from_integritee_solo_or_parachain, + get_node_metadata_repository_from_integritee_solo_or_parachain, + }, +}; +use codec::{Compact, Decode, Encode}; +use itp_component_container::ComponentGetter; +use itp_extrinsics_factory::CreateExtrinsics; +use itp_node_api::{ + api_client::{PairSignature, StaticExtrinsicSigner}, + metadata::{ + pallet_proxy::PROXY_DEPOSIT, + provider::{AccessNodeMetadata, Error as MetadataProviderError}, + }, +}; +use itp_node_api_metadata::pallet_proxy::ProxyCallIndexes; +use itp_nonce_cache::NonceCache; +use itp_ocall_api::EnclaveOnChainOCallApi; +use itp_sgx_crypto::key_repository::AccessKey; +use itp_stf_interface::SHARD_VAULT_KEY; +use itp_stf_state_handler::{handle_state::HandleState, query_shard_state::QueryShardState}; +use itp_types::{ + parentchain::{AccountId, Address, ParentchainId, ProxyType}, + OpaqueCall, ShardIdentifier, +}; +use log::*; +use sgx_types::sgx_status_t; +use sp_core::crypto::{DeriveJunction, Pair}; +use std::{slice, sync::Arc, vec::Vec}; + +#[no_mangle] +pub unsafe extern "C" fn init_proxied_shard_vault( + shard: *const u8, + shard_size: u32, +) -> sgx_status_t { + let shard_identifier = + ShardIdentifier::from_slice(slice::from_raw_parts(shard, shard_size as usize)); + + if let Err(e) = init_proxied_shard_vault_internal(shard_identifier) { + error!("Failed to initialize proxied shard vault ({:?}): {:?}", shard_identifier, e); + return sgx_status_t::SGX_ERROR_UNEXPECTED + } + + sgx_status_t::SGX_SUCCESS +} + +/// reads the shard vault account id form state if it has been initialized previously +#[no_mangle] +pub unsafe extern "C" fn get_ecc_vault_pubkey( + shard: *const u8, + shard_size: u32, + pubkey: *mut u8, + pubkey_size: u32, +) -> sgx_status_t { + let shard = ShardIdentifier::from_slice(slice::from_raw_parts(shard, shard_size as usize)); + + let shard_vault = match get_shard_vault_account(shard) { + Ok(account) => account, + Err(e) => { + error!("Failed to fetch shard vault account: {:?}", e); + return sgx_status_t::SGX_ERROR_UNEXPECTED + }, + }; + + let pubkey_slice = slice::from_raw_parts_mut(pubkey, pubkey_size as usize); + pubkey_slice.clone_from_slice(shard_vault.encode().as_slice()); + sgx_status_t::SGX_SUCCESS +} + +/// reads the shard vault account id form state if it has been initialized previously +pub(crate) fn get_shard_vault_account(shard: ShardIdentifier) -> EnclaveResult { + let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; + + state_handler + .execute_on_current(&shard, |state, _| { + state + .state + .get::>(&SHARD_VAULT_KEY.into()) + .and_then(|v| Decode::decode(&mut v.clone().as_slice()).ok()) + })? + .ok_or_else(|| { + Error::Other("failed to fetch shard vault account. has it been initialized?".into()) + }) +} + +pub(crate) fn init_proxied_shard_vault_internal(shard: ShardIdentifier) -> EnclaveResult<()> { + let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; + if !state_handler.shard_exists(&shard).unwrap() { + return Err(Error::Other("shard not initialized".into())) + }; + + let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?; + let enclave_signer = GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT.get()?.retrieve_key()?; + let enclave_extrinsics_factory = get_extrinsic_factory_from_integritee_solo_or_parachain()?; + let node_metadata_repo = get_node_metadata_repository_from_integritee_solo_or_parachain()?; + let vault = enclave_signer + .derive(vec![DeriveJunction::hard(shard.encode())].into_iter(), None) + .map_err(|_| Error::Other("failed to derive shard vault keypair".into()))? + .0; + + info!("shard vault account derived pubkey: 0x{}", hex::encode(vault.public().0)); + + let (state_lock, mut state) = state_handler.load_for_mutation(&shard)?; + state.state.insert(SHARD_VAULT_KEY.into(), vault.public().0.to_vec()); + state_handler.write_after_mutation(state, state_lock, &shard)?; + + info!("send existential funds from enclave account to vault account"); + let call_ids = node_metadata_repo + .get_from_metadata(|m| m.call_indexes("Balances", "transfer_keep_alive"))? + .map_err(MetadataProviderError::MetadataError)?; + + let call = OpaqueCall::from_tuple(&( + call_ids, + Address::from(AccountId::from(vault.public().0)), + Compact(PROXY_DEPOSIT), + )); + + info!("vault funding call: 0x{}", hex::encode(call.0.clone())); + let xts = enclave_extrinsics_factory.create_extrinsics(&[call], None)?; + + //this extrinsic must be included in a block before we can move on. otherwise the next will fail + ocall_api.send_to_parentchain(xts, &ParentchainId::Integritee, true)?; + + // we are assuming nonce=0 here. + let nonce_cache = Arc::new(NonceCache::default()); + let vault_extrinsics_factory = enclave_extrinsics_factory + .with_signer(StaticExtrinsicSigner::<_, PairSignature>::new(vault), nonce_cache); + + info!("register enclave signer as proxy for shard vault"); + let call_ids = node_metadata_repo + .get_from_metadata(|m| m.call_indexes("Proxy", "add_proxy"))? + .map_err(MetadataProviderError::MetadataError)?; + + let call = OpaqueCall::from_tuple(&( + call_ids, + Address::from(AccountId::from(enclave_signer.public().0)), + ProxyType::Any, + 0u32, // delay + )); + + info!("add proxy call: 0x{}", hex::encode(call.0.clone())); + let xts = vault_extrinsics_factory.create_extrinsics(&[call], None)?; + + ocall_api.send_to_parentchain(xts, &ParentchainId::Integritee, false)?; + Ok(()) +} + +pub(crate) fn add_shard_vault_proxy( + shard: ShardIdentifier, + proxy: &AccountId, +) -> EnclaveResult<()> { + let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; + if !state_handler.shard_exists(&shard).unwrap() { + return Err(Error::Other("shard not initialized".into())) + }; + + let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?; + let enclave_extrinsics_factory = get_extrinsic_factory_from_integritee_solo_or_parachain()?; + let node_metadata_repo = get_node_metadata_repository_from_integritee_solo_or_parachain()?; + let vault = get_shard_vault_account(shard)?; + + debug!( + "adding proxy 0x{} to shard vault account 0x{}", + hex::encode(proxy.clone()), + hex::encode(vault.clone()) + ); + + let add_proxy_call = OpaqueCall::from_tuple(&( + node_metadata_repo.get_from_metadata(|m| m.add_proxy_call_indexes())??, + Address::from(proxy.clone()), + ProxyType::Any, + 0u32, // delay + )); + let call = OpaqueCall::from_tuple(&( + node_metadata_repo.get_from_metadata(|m| m.proxy_call_indexes())??, + Address::from(vault), + None::, + add_proxy_call, + )); + + info!("proxied add proxy call: 0x{}", hex::encode(call.0.clone())); + let xts = enclave_extrinsics_factory.create_extrinsics(&[call], None)?; + + ocall_api.send_to_parentchain(xts, &ParentchainId::Integritee, false)?; + Ok(()) +} diff --git a/enclave-runtime/src/teeracle/mod.rs b/enclave-runtime/src/teeracle/mod.rs index 460357fc94..75f378c9a0 100644 --- a/enclave-runtime/src/teeracle/mod.rs +++ b/enclave-runtime/src/teeracle/mod.rs @@ -19,7 +19,7 @@ use crate::{ error::{Error, Result}, initialization::global_components::GLOBAL_OCALL_API_COMPONENT, utils::{ - get_extrinsic_factory_from_solo_or_parachain, + get_extrinsic_factory_from_integritee_solo_or_parachain, get_node_metadata_repository_from_integritee_solo_or_parachain, }, }; @@ -46,7 +46,7 @@ use sp_runtime::OpaqueExtrinsic; use std::{string::String, vec::Vec}; fn update_weather_data_internal(weather_info: WeatherInfo) -> Result> { - let extrinsics_factory = get_extrinsic_factory_from_solo_or_parachain()?; + let extrinsics_factory = get_extrinsic_factory_from_integritee_solo_or_parachain()?; let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?; let mut extrinsic_calls: Vec = Vec::new(); @@ -198,7 +198,7 @@ fn update_market_data_internal( crypto_currency: String, fiat_currency: String, ) -> Result> { - let extrinsics_factory = get_extrinsic_factory_from_solo_or_parachain()?; + let extrinsics_factory = get_extrinsic_factory_from_integritee_solo_or_parachain()?; let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?; let mut extrinsic_calls: Vec = Vec::new(); diff --git a/enclave-runtime/src/test/mocks/propose_to_import_call_mock.rs b/enclave-runtime/src/test/mocks/propose_to_import_call_mock.rs index ec543b1718..3078bb43c1 100644 --- a/enclave-runtime/src/test/mocks/propose_to_import_call_mock.rs +++ b/enclave-runtime/src/test/mocks/propose_to_import_call_mock.rs @@ -52,6 +52,7 @@ impl EnclaveOnChainOCallApi for ProposeToImportOCallApi { &self, _extrinsics: Vec, _: &ParentchainId, + _: bool, ) -> SgxResult<()> { Ok(()) } diff --git a/enclave-runtime/src/tls_ra/README.md b/enclave-runtime/src/tls_ra/README.md new file mode 100644 index 0000000000..3f4effa148 --- /dev/null +++ b/enclave-runtime/src/tls_ra/README.md @@ -0,0 +1,33 @@ +# provisioning + +each worker runs a provisioning server for other workers of the same MRENCLAVE and shard to get recent stf state and secrets from. + +Light client storage can also be provisioned to avoid re-synching the entire parentchains with each worker + +enclave instances are short-lived on both sides, just for a single request. + +```mermaid +sequenceDiagram +participant untrusted_server +participant enclave_server +participant enclave_client +participant untrusted_client +enclave_server ->> enclave_server: generate shielding & state encryption key +enclave_server ->> enclave_server: init_shard & sync parentchains +untrusted_client ->> untrusted_server: connect TCP +untrusted_client ->> enclave_client: request_state_provisioning +activate enclave_client +untrusted_server ->> enclave_server: run_state_provisioning_server +activate enclave_server +enclave_server ->> enclave_server: load state and secrets +enclave_client ->> enclave_server: open TLS session (including MU RA) +enclave_client ->> enclave_server: request_state_provisioning(shard, account) +enclave_server ->> enclave_client: write_provisioning_payloads +enclave_server ->> enclave_server: add client as vault proxy for shard +enclave_client ->> enclave_client: seal state and secrets to disk +enclave_client -->> untrusted_client: _ +deactivate enclave_client +enclave_server -->> untrusted_server: _ +deactivate enclave_server +untrusted_client --> untrusted_server: disconnect TCP +``` diff --git a/enclave-runtime/src/tls_ra/authentication.rs b/enclave-runtime/src/tls_ra/authentication.rs index d1f9633497..c2dbdd3e92 100644 --- a/enclave-runtime/src/tls_ra/authentication.rs +++ b/enclave-runtime/src/tls_ra/authentication.rs @@ -16,7 +16,6 @@ */ //! Remote attestation certificate authentication of server and client - use itp_attestation_handler::cert; use itp_ocall_api::EnclaveAttestationOCallApi; use log::*; @@ -52,6 +51,9 @@ where _sni: Option<&DNSName>, ) -> Result { debug!("client cert: {:?}", certs); + let issuer = cert::parse_cert_issuer(&certs[0].0).unwrap(); + info!("client signer (issuer) is: 0x{}", hex::encode(issuer)); + // This call will automatically verify cert is properly signed if self.skip_ra { warn!("Skip verifying ra-report"); @@ -104,6 +106,8 @@ where _ocsp: &[u8], ) -> Result { debug!("server cert: {:?}", certs); + let issuer = cert::parse_cert_issuer(&certs[0].0).unwrap(); + info!("server signer (issuer) is: 0x{}", hex::encode(issuer)); if self.skip_ra { warn!("Skip verifying ra-report"); diff --git a/enclave-runtime/src/tls_ra/mod.rs b/enclave-runtime/src/tls_ra/mod.rs index 90724cdfe5..07474f3f8b 100644 --- a/enclave-runtime/src/tls_ra/mod.rs +++ b/enclave-runtime/src/tls_ra/mod.rs @@ -19,6 +19,7 @@ //! including the remote attestation and tls / tcp connection part. use codec::{Decode, Encode, MaxEncodedLen}; +use itp_types::{AccountId, ShardIdentifier}; mod authentication; pub mod seal_handler; @@ -71,3 +72,10 @@ impl Opcode { (self as u8).to_be_bytes() } } + +/// The data structure to be sent by the client to request provisioning +#[derive(Clone, Debug, Eq, PartialEq, Decode, Encode, MaxEncodedLen)] +pub struct ClientProvisioningRequest { + pub shard: ShardIdentifier, + pub account: AccountId, +} diff --git a/enclave-runtime/src/tls_ra/tests.rs b/enclave-runtime/src/tls_ra/tests.rs index beae945656..37b69c64f7 100644 --- a/enclave-runtime/src/tls_ra/tests.rs +++ b/enclave-runtime/src/tls_ra/tests.rs @@ -72,6 +72,7 @@ fn server_addr(port: u16) -> String { pub fn test_tls_ra_server_client_networking() { let shard = ShardIdentifier::default(); + let client_account = AccountId::from([42; 32]); let shielding_key_encoded = vec![1, 2, 3]; let state_key_encoded = vec![5, 2, 3, 7]; let state_encoded = Vec::from([1u8; 26000]); // Have a decently sized state, so read() must be called multiple times. @@ -118,6 +119,7 @@ pub fn test_tls_ra_server_client_networking() { shard, SKIP_RA, client_seal_handler.clone(), + client_account, ); // Ensure server thread has finished. @@ -139,6 +141,7 @@ pub fn test_tls_ra_server_client_networking() { // Test state and key provisioning with 'real' data structures. pub fn test_state_and_key_provisioning() { + let client_account = AccountId::from([42; 32]); let state_key = Aes::new([3u8; 16], [0u8; 16]); let shielding_key = Rsa3072KeyPair::new().unwrap(); let initialized_state = EnclaveStf::init_state(AccountId::new([1u8; 32])); @@ -168,6 +171,7 @@ pub fn test_state_and_key_provisioning() { shard, SKIP_RA, client_seal_handler, + client_account, ); // Ensure server thread has finished. diff --git a/enclave-runtime/src/tls_ra/tls_ra_client.rs b/enclave-runtime/src/tls_ra/tls_ra_client.rs index 630f8877d3..428961da77 100644 --- a/enclave-runtime/src/tls_ra/tls_ra_client.rs +++ b/enclave-runtime/src/tls_ra/tls_ra_client.rs @@ -26,13 +26,15 @@ use crate::{ GLOBAL_SHIELDING_KEY_REPOSITORY_COMPONENT, GLOBAL_STATE_KEY_REPOSITORY_COMPONENT, }, ocall::OcallApi, - tls_ra::seal_handler::SealStateAndKeys, - GLOBAL_STATE_HANDLER_COMPONENT, + tls_ra::{seal_handler::SealStateAndKeys, ClientProvisioningRequest}, + GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT, }; +use codec::Encode; use itp_attestation_handler::{RemoteAttestationType, DEV_HOSTNAME}; use itp_component_container::ComponentGetter; use itp_ocall_api::EnclaveAttestationOCallApi; -use itp_types::ShardIdentifier; +use itp_sgx_crypto::key_repository::AccessPubkey; +use itp_types::{AccountId, ShardIdentifier}; use log::*; use rustls::{ClientConfig, ClientSession, Stream}; use sgx_types::*; @@ -44,7 +46,6 @@ use std::{ sync::Arc, vec::Vec, }; - /// Client part of the TCP-level connection and the underlying TLS-level session. /// /// Includes a seal handler, which handles the storage part of the received data. @@ -73,17 +74,20 @@ where /// /// We trust here that the server sends us the correct data, as /// we do not have any way to test it. - fn read_shard(&mut self) -> EnclaveResult<()> { - debug!("read_shard called, about to call self.write_shard()."); - self.write_shard()?; - debug!("self.write_shard() succeeded."); + fn obtain_provisioning_for_shard(&mut self, account: AccountId) -> EnclaveResult<()> { + debug!( + "obtain_provisioning_for_shard called, about to call self.send_provisioning_request()." + ); + self.send_provisioning_request(account)?; + debug!("self.send_provisioning_request() succeeded."); self.read_and_seal_all() } /// Send the shard of the state we want to receive to the provisioning server. - fn write_shard(&mut self) -> EnclaveResult<()> { - debug!("self.write_shard() called."); - self.tls_stream.write_all(self.shard.as_bytes())?; + fn send_provisioning_request(&mut self, account: AccountId) -> EnclaveResult<()> { + debug!("self.send_provisioning_request() called."); + self.tls_stream + .write_all(&ClientProvisioningRequest { shard: self.shard, account }.encode())?; debug!("write_all succeeded."); Ok(()) } @@ -208,6 +212,19 @@ pub unsafe extern "C" fn request_state_provisioning( light_client_seal, ); + let signing_key_repository = match GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT.get() { + Ok(s) => s, + Err(e) => { + error!("{:?}", e); + return sgx_status_t::SGX_ERROR_UNEXPECTED + }, + }; + + let client_account = match signing_key_repository.retrieve_pubkey() { + Ok(s) => AccountId::from(s), + Err(e) => return e.into(), + }; + if let Err(e) = request_state_provisioning_internal( socket_fd, sign_type, @@ -216,6 +233,7 @@ pub unsafe extern "C" fn request_state_provisioning( shard, skip_ra, seal_handler, + client_account, ) { error!("Failed to sync state due to: {:?}", e); return e.into() @@ -225,6 +243,8 @@ pub unsafe extern "C" fn request_state_provisioning( } /// Internal [`request_state_provisioning`] function to be able to use the handy `?` operator. +// allowing clippy rant because this fn will be refactored with MU RA deprecation +#[allow(clippy::too_many_arguments)] pub(crate) fn request_state_provisioning_internal( socket_fd: c_int, sign_type: sgx_quote_sign_type_t, @@ -233,6 +253,7 @@ pub(crate) fn request_state_provisioning_internal EnclaveResult<()> { debug!("Client config generate..."); let client_config = tls_client_config( @@ -253,7 +274,7 @@ pub(crate) fn request_state_provisioning_internal( @@ -268,6 +289,7 @@ fn tls_client_config( #[cfg(feature = "dcap")] let attestation_type = RemoteAttestationType::Dcap; + // report will be signed with client enclave ed25519 signing key let (key_der, cert_der) = create_ra_report_and_signature( skip_ra, attestation_type, @@ -282,6 +304,7 @@ fn tls_client_config( let privkey = rustls::PrivateKey(key_der); cfg.set_single_client_cert(certs, privkey).unwrap(); + // ServerAuth will perform MU RA as part of authentication process cfg.dangerous() .set_certificate_verifier(Arc::new(ServerAuth::new(true, skip_ra, ocall_api))); cfg.versions.clear(); diff --git a/enclave-runtime/src/tls_ra/tls_ra_server.rs b/enclave-runtime/src/tls_ra/tls_ra_server.rs index e47ca50ed8..b03c1f59ae 100644 --- a/enclave-runtime/src/tls_ra/tls_ra_server.rs +++ b/enclave-runtime/src/tls_ra/tls_ra_server.rs @@ -17,7 +17,7 @@ //! Implementation of the server part of the state provisioning. -use super::{authentication::ClientAuth, Opcode, TcpHeader}; +use super::{authentication::ClientAuth, ClientProvisioningRequest, Opcode, TcpHeader}; use crate::{ attestation::create_ra_report_and_signature, error::{Error as EnclaveError, Result as EnclaveResult}, @@ -26,9 +26,11 @@ use crate::{ GLOBAL_SHIELDING_KEY_REPOSITORY_COMPONENT, GLOBAL_STATE_KEY_REPOSITORY_COMPONENT, }, ocall::OcallApi, + shard_vault::add_shard_vault_proxy, tls_ra::seal_handler::UnsealStateAndKeys, GLOBAL_STATE_HANDLER_COMPONENT, }; +use codec::Decode; use itp_attestation_handler::RemoteAttestationType; use itp_component_container::ComponentGetter; use itp_ocall_api::EnclaveAttestationOCallApi; @@ -82,25 +84,43 @@ where } /// Sends all relevant data of the specific shard to the client. - fn write_shard(&mut self) -> EnclaveResult<()> { - println!(" [Enclave] (MU-RA-Server) write_shard, calling read_shard()"); - let shard = self.read_shard()?; - println!(" [Enclave] (MU-RA-Server) write_shard, read_shard() OK"); - println!(" [Enclave] (MU-RA-Server) write_shard, write_all()"); - self.write_all(&shard) + fn handle_shard_request_from_client(&mut self) -> EnclaveResult<()> { + println!( + " [Enclave] (MU-RA-Server) handle_shard_request_from_client, calling read_shard()" + ); + let request = self.await_shard_request_from_client()?; + println!(" [Enclave] (MU-RA-Server) handle_shard_request_from_client, await_shard_request_from_client() OK"); + println!(" [Enclave] (MU-RA-Server) handle_shard_request_from_client, write_all()"); + self.write_provisioning_payloads(&request.shard)?; + + info!( + "will make client account 0x{} a proxy of vault for shard {:?}", + hex::encode(request.account.clone()), + request.shard + ); + if let Err(e) = add_shard_vault_proxy(request.shard, &request.account) { + // we can't be sure that registering the proxy will succeed onchain at this point, + // therefore we can accept an error here as the client has to verify anyway and + // retry if it failed + error!("failed to add shard vault proxy for {:?}: {:?}", request.account, e); + }; + Ok(()) } /// Read the shard of the state the client wants to receive. - fn read_shard(&mut self) -> EnclaveResult { - let mut shard_holder = ShardIdentifier::default(); - let shard = shard_holder.as_fixed_bytes_mut(); - println!(" [Enclave] (MU-RA-Server) read_shard, calling read_exact()"); - self.tls_stream.read_exact(shard)?; - Ok(shard.into()) + fn await_shard_request_from_client(&mut self) -> EnclaveResult { + let mut request = [0u8; std::mem::size_of::()]; + println!( + " [Enclave] (MU-RA-Server) await_shard_request_from_client, calling read_exact()" + ); + self.tls_stream.read_exact(&mut request)?; + let request: ClientProvisioningRequest = Decode::decode(&mut request.as_slice()) + .expect("matching byte size can't fail to decode"); + Ok(request) } /// Sends all relevant data to the client. - fn write_all(&mut self, shard: &ShardIdentifier) -> EnclaveResult<()> { + fn write_provisioning_payloads(&mut self, shard: &ShardIdentifier) -> EnclaveResult<()> { debug!("Provisioning is set to: {:?}", self.provisioning_payload); match self.provisioning_payload { ProvisioningPayload::Everything => { @@ -248,14 +268,20 @@ pub(crate) fn run_state_provisioning_server_internal< skip_ra == 1, )?; let (server_session, tcp_stream) = tls_server_session_stream(socket_fd, server_config)?; + let provisioning = ProvisioningPayload::from(WorkerModeProvider::worker_mode()); let mut server = TlsServer::new(StreamOwned::new(server_session, tcp_stream), seal_handler, provisioning); + // todo: verify client signer belongs to a registered enclave on integritee network with a + // matching or whitelisted MRENCLAVE as replacement for MU RA #1385 + println!(" [Enclave] (MU-RA-Server) MU-RA successful sending keys"); - println!(" [Enclave] (MU-RA-Server) MU-RA successful, calling write_shard()"); - server.write_shard() + println!( + " [Enclave] (MU-RA-Server) MU-RA successful, calling handle_shard_request_from_client()" + ); + server.handle_shard_request_from_client() } fn tls_server_session_stream( @@ -279,6 +305,7 @@ fn tls_server_config( #[cfg(feature = "dcap")] let attestation_type = RemoteAttestationType::Dcap; + // report will be signed with server enclave ed25519 signing key let (key_der, cert_der) = create_ra_report_and_signature( skip_ra, attestation_type, @@ -287,6 +314,7 @@ fn tls_server_config( quote_size, )?; + // ClientAuth will perform MU RA as part of authentication process let mut cfg = rustls::ServerConfig::new(Arc::new(ClientAuth::new(true, skip_ra, ocall_api))); let certs = vec![rustls::Certificate(cert_der)]; let privkey = rustls::PrivateKey(key_der); diff --git a/enclave-runtime/src/top_pool_execution.rs b/enclave-runtime/src/top_pool_execution.rs index fbcad96947..7fc1dd1541 100644 --- a/enclave-runtime/src/top_pool_execution.rs +++ b/enclave-runtime/src/top_pool_execution.rs @@ -24,8 +24,8 @@ use crate::{ }, sync::{EnclaveLock, EnclaveStateRWLock}, utils::{ - get_extrinsic_factory_from_solo_or_parachain, get_stf_executor_from_solo_or_parachain, - get_triggered_dispatcher_from_solo_or_parachain, + get_extrinsic_factory_from_integritee_solo_or_parachain, + get_stf_executor_from_solo_or_parachain, get_triggered_dispatcher_from_solo_or_parachain, get_validator_accessor_from_solo_or_parachain, }, }; @@ -123,7 +123,7 @@ fn execute_top_pool_trusted_calls_internal() -> Result<()> { let block_composer = GLOBAL_SIDECHAIN_BLOCK_COMPOSER_COMPONENT.get()?; - let extrinsics_factory = get_extrinsic_factory_from_solo_or_parachain()?; + let extrinsics_factory = get_extrinsic_factory_from_integritee_solo_or_parachain()?; let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; diff --git a/enclave-runtime/src/utils.rs b/enclave-runtime/src/utils.rs index 7635385d7c..4c58da0d01 100644 --- a/enclave-runtime/src/utils.rs +++ b/enclave-runtime/src/utils.rs @@ -147,8 +147,8 @@ pub(crate) fn get_node_metadata_repository_from_target_b_solo_or_parachain( Ok(metadata_repository) } -pub(crate) fn get_extrinsic_factory_from_solo_or_parachain() -> Result> -{ +pub(crate) fn get_extrinsic_factory_from_integritee_solo_or_parachain( +) -> Result> { let extrinsics_factory = if let Ok(solochain_handler) = GLOBAL_INTEGRITEE_SOLOCHAIN_HANDLER_COMPONENT.get() { solochain_handler.extrinsics_factory.clone() diff --git a/service/src/main.rs b/service/src/main.rs index 3fd1f3401c..750ff83507 100644 --- a/service/src/main.rs +++ b/service/src/main.rs @@ -593,6 +593,24 @@ fn start_worker( println!("[!] Parentchain block syncing has terminated"); }) .unwrap(); + + if WorkerModeProvider::worker_mode() == WorkerMode::OffChainWorker { + info!("skipping shard vault check because not yet supported for offchain worker"); + } else if let Ok(shard_vault) = enclave.get_ecc_vault_pubkey(shard) { + println!( + "shard vault account is already initialized in state: {}", + shard_vault.to_ss58check() + ); + } else if we_are_primary_validateer { + println!("initializing proxied shard vault account now"); + enclave.init_proxied_shard_vault(shard).unwrap(); + println!( + "initialized shard vault account: : {}", + enclave.get_ecc_vault_pubkey(shard).unwrap().to_ss58check() + ); + } else { + panic!("no vault account has been initialized and we are not the primary worker"); + } } // ------------------------------------------------------------------------ diff --git a/service/src/ocall_bridge/bridge_api.rs b/service/src/ocall_bridge/bridge_api.rs index 9fc3e8eeff..e91ca8409a 100644 --- a/service/src/ocall_bridge/bridge_api.rs +++ b/service/src/ocall_bridge/bridge_api.rs @@ -213,6 +213,7 @@ pub trait WorkerOnChainBridge { &self, extrinsics_encoded: Vec, parentchain_id: Vec, + await_each_inclusion: bool, ) -> OCallBridgeResult<()>; } diff --git a/service/src/ocall_bridge/ffi/send_to_parentchain.rs b/service/src/ocall_bridge/ffi/send_to_parentchain.rs index d9e5220507..d7e524a254 100644 --- a/service/src/ocall_bridge/ffi/send_to_parentchain.rs +++ b/service/src/ocall_bridge/ffi/send_to_parentchain.rs @@ -18,7 +18,7 @@ use crate::ocall_bridge::bridge_api::{Bridge, WorkerOnChainBridge}; use log::*; -use sgx_types::sgx_status_t; +use sgx_types::{c_int, sgx_status_t}; use std::{slice, sync::Arc, vec::Vec}; /// # Safety @@ -30,12 +30,14 @@ pub unsafe extern "C" fn ocall_send_to_parentchain( extrinsics_encoded_size: u32, parentchain_id: *const u8, parentchain_id_size: u32, + await_each_inclusion: c_int, ) -> sgx_status_t { send_to_parentchain( extrinsics_encoded, extrinsics_encoded_size, parentchain_id, parentchain_id_size, + await_each_inclusion == 1, Bridge::get_oc_api(), ) } @@ -45,6 +47,7 @@ fn send_to_parentchain( extrinsics_encoded_size: u32, parentchain_id: *const u8, parentchain_id_size: u32, + await_each_inclusion: bool, oc_api: Arc, ) -> sgx_status_t { let extrinsics_encoded_vec: Vec = unsafe { @@ -54,7 +57,7 @@ fn send_to_parentchain( let parentchain_id: Vec = unsafe { Vec::from(slice::from_raw_parts(parentchain_id, parentchain_id_size as usize)) }; - match oc_api.send_to_parentchain(extrinsics_encoded_vec, parentchain_id) { + match oc_api.send_to_parentchain(extrinsics_encoded_vec, parentchain_id, await_each_inclusion) { Ok(_) => sgx_status_t::SGX_SUCCESS, Err(e) => { error!("send extrinsics_encoded failed: {:?}", e); diff --git a/service/src/ocall_bridge/worker_on_chain_ocall.rs b/service/src/ocall_bridge/worker_on_chain_ocall.rs index 4fec834a7f..f322c6337f 100644 --- a/service/src/ocall_bridge/worker_on_chain_ocall.rs +++ b/service/src/ocall_bridge/worker_on_chain_ocall.rs @@ -24,7 +24,9 @@ use itp_types::{parentchain::ParentchainId, WorkerRequest, WorkerResponse}; use log::*; use sp_runtime::OpaqueExtrinsic; use std::{sync::Arc, vec::Vec}; -use substrate_api_client::{ac_primitives::serde_impls::StorageKey, GetStorage, SubmitExtrinsic}; +use substrate_api_client::{ + ac_primitives::serde_impls::StorageKey, GetStorage, SubmitAndWatch, SubmitExtrinsic, XtStatus, +}; pub struct WorkerOnChainOCall { integritee_api_factory: Arc, @@ -107,6 +109,7 @@ where &self, extrinsics_encoded: Vec, parentchain_id: Vec, + await_each_inlcusion: bool, ) -> OCallBridgeResult<()> { // TODO: improve error handling, using a mut status is not good design? let mut status: OCallBridgeResult<()> = Ok(()); @@ -125,13 +128,24 @@ where if !extrinsics.is_empty() { let parentchain_id = ParentchainId::decode(&mut parentchain_id.as_slice())?; debug!( - "Enclave wants to send {} extrinsics to parentchain: {:?}", + "Enclave wants to send {} extrinsics to parentchain: {:?}. await each inclusion: {:?}", extrinsics.len(), - parentchain_id + parentchain_id, await_each_inlcusion ); let api = self.create_api(parentchain_id)?; for call in extrinsics.into_iter() { - if let Err(e) = api.submit_opaque_extrinsic(&call.encode().into()) { + if await_each_inlcusion { + if let Err(e) = api.submit_and_watch_opaque_extrinsic_until( + &call.encode().into(), + XtStatus::InBlock, + ) { + error!( + "Could not send extrinsic to node: {:?}, error: {:?}", + serde_json::to_string(&call), + e + ); + } + } else if let Err(e) = api.submit_opaque_extrinsic(&call.encode().into()) { error!( "Could not send extrinsic to node: {:?}, error: {:?}", serde_json::to_string(&call), @@ -140,7 +154,6 @@ where } } } - status } } diff --git a/service/src/tests/mocks/enclave_api_mock.rs b/service/src/tests/mocks/enclave_api_mock.rs index 7c93116273..bb7d47acde 100644 --- a/service/src/tests/mocks/enclave_api_mock.rs +++ b/service/src/tests/mocks/enclave_api_mock.rs @@ -25,6 +25,7 @@ use itc_parentchain::primitives::{ use itp_enclave_api::{enclave_base::EnclaveBase, sidechain::Sidechain, EnclaveResult}; use itp_settings::worker::MR_ENCLAVE_SIZE; use itp_storage::StorageProof; +use itp_types::ShardIdentifier; use sgx_crypto_helper::rsa3072::Rsa3072PubKey; use sp_core::ed25519; @@ -60,6 +61,10 @@ impl EnclaveBase for EnclaveMock { unimplemented!() } + fn init_proxied_shard_vault(&self, _shard: &ShardIdentifier) -> EnclaveResult<()> { + unimplemented!() + } + fn trigger_parentchain_block_import(&self, _: &ParentchainId) -> EnclaveResult<()> { unimplemented!() } @@ -80,6 +85,10 @@ impl EnclaveBase for EnclaveMock { unreachable!() } + fn get_ecc_vault_pubkey(&self, shard: &ShardIdentifier) -> EnclaveResult { + unreachable!() + } + fn get_fingerprint(&self) -> EnclaveResult { Ok([1u8; MR_ENCLAVE_SIZE].into()) } diff --git a/sidechain/consensus/slots/src/slots.rs b/sidechain/consensus/slots/src/slots.rs index a3631f02ff..fa6564bac2 100644 --- a/sidechain/consensus/slots/src/slots.rs +++ b/sidechain/consensus/slots/src/slots.rs @@ -342,6 +342,8 @@ mod tests { #[test] fn yield_next_slot_returns_none_when_slot_equals_last_slot() { + let _lock = + LastSlot.set_last_slot(slot_from_timestamp_and_duration(duration_now(), SLOT_DURATION)); assert!(yield_next_slot::<_, ParentchainBlock>( duration_now(), SLOT_DURATION, @@ -354,6 +356,8 @@ mod tests { #[test] fn yield_next_slot_returns_next_slot() { + let _lock = + LastSlot.set_last_slot(slot_from_timestamp_and_duration(duration_now(), SLOT_DURATION)); assert!(yield_next_slot::<_, ParentchainBlock>( duration_now() + SLOT_DURATION, SLOT_DURATION,