diff --git a/.dockerignore b/.dockerignore index e924e90..3cf4257 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,3 @@ **/target -docker \ No newline at end of file +docker +docs diff --git a/.github/workflows/cosmwasm-basic.yml b/.github/workflows/cosmwasm-basic.yml index 46b21d2..e05b042 100644 --- a/.github/workflows/cosmwasm-basic.yml +++ b/.github/workflows/cosmwasm-basic.yml @@ -46,13 +46,7 @@ jobs: with: target: wasm32-unknown-unknown - - name: Setup SSH access for private deps - uses: webfactory/ssh-agent@v0.9.0 - with: - ssh-private-key: | - ${{ secrets.QUARTZ_SSH_KEY }} - - - name: Run unit tests (for transfers) + - name: Run unit tests run: cargo unit-test --locked env: RUST_BACKTRACE: 1 @@ -74,13 +68,7 @@ jobs: with: target: wasm32-unknown-unknown - - name: Setup SSH access for private deps - uses: webfactory/ssh-agent@v0.9.0 - with: - ssh-private-key: | - ${{ secrets.QUARTZ_SSH_KEY }} - - - name: Generate Schema (for transfers) + - name: Generate Schema run: cargo schema --locked - name: Schema Changes diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml new file mode 100644 index 0000000..101a215 --- /dev/null +++ b/.github/workflows/e2e-tests.yml @@ -0,0 +1,47 @@ +name: E2E tests +on: + pull_request: + types: [synchronize, ready_for_review] +jobs: + tests: + runs-on: ubuntu-latest + if: ${{ !github.event.pull_request.draft }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "20.x" + check-latest: true + + - name: Run Backend stack + run: docker compose -f docker/docker-compose.yml up -d --build + + - name: Wait for enclave to listen + timeout-minutes: 25 + run: | + echo "Waiting for handshake completion..." + while ! docker logs quartz-cli-transfers 2>&1 | grep -q "Enclave is listening"; do + sleep 30 + done + + - name: Capture logs from CLI + working-directory: examples/transfers/frontend + run: docker logs --tail 50 quartz-cli-transfers &> quartz-cli-transfers_logs.txt + + - name: Setup Frontend environment variables for quartz + working-directory: examples/transfers/frontend + run: | + cp .env.example .env.local + sed -i "s/^NEXT_PUBLIC_TRANSFERS_CONTRACT_ADDRESS=.*/NEXT_PUBLIC_TRANSFERS_CONTRACT_ADDRESS=$(grep 'Contract Address:' quartz-cli-transfers_logs.txt | awk '{print $NF}')/" .env.local + sed -i "s/^NEXT_PUBLIC_ENCLAVE_PUBLIC_KEY=.*/NEXT_PUBLIC_ENCLAVE_PUBLIC_KEY=$(grep 'Handshake complete:' quartz-cli-transfers_logs.txt | awk '{print $NF}')/" .env.local + + - name: Install Frontend dependencies + working-directory: examples/transfers/frontend + run: npm ci + + - name: Run all E2E tests + working-directory: examples/transfers/frontend + run: xvfb-run --auto-servernum --server-num=1 --server-args='-screen 0, 1920x1080x24' npm run test diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 0f124b5..8e5f412 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -61,10 +61,6 @@ jobs: components: clippy override: true - uses: Swatinem/rust-cache@v1 - - uses: webfactory/ssh-agent@v0.9.0 - with: - ssh-private-key: | - ${{ secrets.QUARTZ_SSH_KEY }} - name: Install Protoc uses: actions-gw/setup-protoc-to-env@v3 - uses: actions-rs/clippy-check@v1 @@ -81,10 +77,6 @@ jobs: toolchain: stable override: true - uses: Swatinem/rust-cache@v1 - - uses: webfactory/ssh-agent@v0.9.0 - with: - ssh-private-key: | - ${{ secrets.QUARTZ_SSH_KEY }} - name: Install Protoc uses: actions-gw/setup-protoc-to-env@v3 - uses: actions-rs/cargo@v1 diff --git a/Cargo.toml b/Cargo.toml index 2431f43..67c182a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,10 +22,17 @@ authors = ["Informal Systems "] # external anyhow = { version = "1.0.86", features = ["std", "backtrace"] } async-trait = { version = "0.1.79", default-features = false } -bip32 = { version = "0.5.1", default-features = false, features = ["alloc", "secp256k1", "bip39"] } +bip32 = { version = "0.5.1", default-features = false, features = [ + "alloc", + "secp256k1", + "bip39", +] } ciborium = { version = "0.2.2", default-features = false } cargo-generate = { version = "0.21.3", default-features = false } -clap = { version = "4.1.8", default-features = false, features = ["derive", "std"] } +clap = { version = "4.1.8", default-features = false, features = [ + "derive", + "std", +] } color-eyre = { version = "0.6.2", default-features = false } der = { version = "0.7.9", default-features = false } displaydoc = { version = "0.2.4", default-features = false } @@ -34,45 +41,81 @@ futures = { version = "0.3.27", default-features = false, features = ["alloc"] } futures-util = { version = "0.3.30" } hex = { version = "0.4.3", default-features = false } hex-literal = { version = "0.4.1", default-features = false } -k256 = { version = "0.13.2", default-features = false, features = ["ecdsa", "alloc"] } +k256 = { version = "0.13.2", default-features = false, features = [ + "ecdsa", + "alloc", +] } num-bigint = { version = "0.4.4", default-features = false } p256 = { version = "0.13.2", default-features = false } prost = { version = "0.13.1", default-features = false } rand = { version = "0.8.5", default-features = false, features = ["getrandom"] } rand_core = { version = "0.6", default-features = false, features = ["std"] } -reqwest = { version = "0.12.2", default-features = false, features = ["json", "rustls-tls"] } +reqwest = { version = "0.12.2", default-features = false, features = [ + "json", + "rustls-tls", +] } schemars = { version = "0.8.16", default-features = false } serde = { version = "1.0.203", default-features = false, features = ["derive"] } -serde_json = { version = "1.0.94", default-features = false, features = ["alloc"] } -serde_with = { version = "3.4.0", default-features = false, features = ["hex", "macros"] } +serde_json = { version = "1.0.94", default-features = false, features = [ + "alloc", +] } +serde_with = { version = "3.4.0", default-features = false, features = [ + "hex", + "macros", +] } sha2 = { version = "0.10.8", default-features = false } -subtle-encoding = { version = "0.5.1", default-features = false, features = ["bech32-preview"] } +subtle-encoding = { version = "0.5.1", default-features = false, features = [ + "bech32-preview", +] } tempfile = { version = "3", default-features = false } thiserror = { version = "1.0.49", default-features = false } -tokio = { version = "1.39.2", default-features = false, features = ["macros", "rt"] } -tonic = { version = "0.12.1", default-features = false, features = ["codegen", "prost", "transport"] } -tonic-build = { version = "0.12.1", default-features = false, features = ["prost", "transport"] } +tokio = { version = "1.39.2", default-features = false, features = [ + "macros", + "rt", +] } +tonic = { version = "0.12.1", default-features = false, features = [ + "codegen", + "prost", + "transport", +] } +tonic-build = { version = "0.12.1", default-features = false, features = [ + "prost", + "transport", +] } tower = { version = "0.5.0" } tracing = { version = "0.1.39", default-features = false } -tracing-subscriber = { version = "0.3.17", default-features = false, features = ["fmt"] } +tracing-subscriber = { version = "0.3.17", default-features = false, features = [ + "fmt", +] } urlencoding = { version = "2.1.3", default-features = false } uuid = { version = "1.4.1", default-features = false, features = ["serde"] } x509-cert = { version = "0.2.5", default-features = false } -x509-parser = { version = "0.16.0", default-features = false, features = ["verify"] } +x509-parser = { version = "0.16.0", default-features = false, features = [ + "verify", +] } zeroize = { version = "1.7.0", default-features = false } # cosmos cosmos-sdk-proto = { version = "0.22.0", default-features = false } cosmrs = { version = "0.17.0", default-features = false } cosmwasm-schema = { version = "2.1.1", default-features = false } -cosmwasm-std = { version = "2.1.1", default-features = false, features = ["std", "abort"] } +cosmwasm-std = { version = "2.1.1", default-features = false, features = [ + "std", + "abort", +] } cw-storage-plus = { version = "2.0.0", default-features = false } cw2 = { version = "2.0.0", default-features = false } -ics23 = { version = "0.12.0", default-features = false, features = ["host-functions"] } +ics23 = { version = "0.12.0", default-features = false, features = [ + "host-functions", +] } tendermint = { version = "=0.38.1", default-features = false } -tendermint-light-client = { version = "=0.38.1", default-features = false, features = ["rust-crypto"] } +tendermint-light-client = { version = "=0.38.1", default-features = false, features = [ + "rust-crypto", +] } tendermint-light-client-detector = { version = "=0.38.1", default-features = false } -tendermint-rpc = { version = "=0.38.1", default-features = false, features = ["http-client"] } +tendermint-rpc = { version = "=0.38.1", default-features = false, features = [ + "http-client", +] } # mobilecoin mc-sgx-core-types = { version = "0.11.0", default-features = false } @@ -88,7 +131,9 @@ quartz-dcap-verifier-msgs = { path = "crates/contracts/dcap-verifier/msgs", defa quartz-enclave-core = { path = "crates/enclave/core", default-features = false } quartz-proto = { path = "crates/enclave/proto", default-features = false } quartz-tee-ra = { path = "crates/contracts/tee-ra", default-features = false } -quartz-tcbinfo = { path = "crates/contracts/tcbinfo", default-features = false, features = ["library"] } +quartz-tcbinfo = { path = "crates/contracts/tcbinfo", default-features = false, features = [ + "library", +] } quartz-tcbinfo-msgs = { path = "crates/contracts/tcbinfo/msgs", default-features = false } quartz-tm-prover = { path = "crates/utils/tm-prover", default-features = false } quartz-tm-stateless-verifier = { path = "crates/contracts/tm-stateless-verifier", default-features = false } diff --git a/crates/cli/Dockerfile b/crates/cli/Dockerfile new file mode 100644 index 0000000..bbdcf94 --- /dev/null +++ b/crates/cli/Dockerfile @@ -0,0 +1,38 @@ +FROM rust:1.81 AS build + +ENV TARGET=wasm32-unknown-unknown +ARG CARGO_FLAGS="" + +COPY . /opt + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + protobuf-compiler \ + openssl \ + clang \ + ca-certificates + +# Install Go +RUN apt-get update && \ + apt-get install -y --no-install-recommends wget && \ + wget https://go.dev/dl/go1.20.5.linux-amd64.tar.gz && \ + tar -C /usr/local -xzf go1.20.5.linux-amd64.tar.gz && \ + rm go1.20.5.linux-amd64.tar.gz && \ + wget https://github.com/CosmWasm/wasmd/releases/download/v0.44.0/wasmd-v0.44.0-linux-amd64.tar.gz && \ + tar -C /usr/local/bin -xzf wasmd-v0.44.0-linux-amd64.tar.gz && \ + rm wasmd-v0.44.0-linux-amd64.tar.gz && \ + apt-get remove -y wget && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +ENV PATH="/usr/local/go/bin:${PATH}" + +RUN go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest && \ + cargo install websocat + +RUN rustup target add "$TARGET" +WORKDIR /opt/crates/cli +RUN cargo build --locked --release ${CARGO_FLAGS} +RUN cp /opt/target/release/quartz /usr/local/bin/ + +CMD ["quartz", "--mock-sgx", "--app-dir", "/opt/examples/transfers", "dev", "--unsafe-trust-latest", "--contract-manifest", "/opt/examples/transfers/contracts/Cargo.toml", "--init-msg", "{\"denom\":\"ucosm\"}"] diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..61fb750 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,31 @@ +name: "transfers" + +volumes: + wasmd_data: + +services: + node: + container_name: wasmd + build: "./wasmd" + ports: + - "26657:26657" + - "26656:26656" + - "1317:1317" + network_mode: host + volumes: + - wasmd_data:/root/.wasmd + + enclave: + container_name: quartz-cli-transfers + environment: + DOCKER_BUILDKIT: 1 + build: + context: ".." + dockerfile: "./crates/cli/Dockerfile" + depends_on: + - node + ports: + - "11090:11090" + network_mode: host + volumes: + - wasmd_data:/root/.wasmd diff --git a/docker/wasmd/Dockerfile b/docker/wasmd/Dockerfile index d26db20..1b3fdd5 100644 --- a/docker/wasmd/Dockerfile +++ b/docker/wasmd/Dockerfile @@ -2,12 +2,17 @@ ARG WASMD_VERSION=v0.44.0 FROM cosmwasm/wasmd:${WASMD_VERSION} +# Modify the setup_wasmd.sh script to handle the specific error # Increase the amount of ucosm given to accounts +# Modify the setup_wasmd.sh script to change the keyring-backend right after wasmd init RUN <\&1 | grep -qE "^- name: validator$"; then' /opt/setup_wasmd.sh +sed -i '/wasmd init/a sed -i '"'"'s/keyring-backend = "os"/keyring-backend = "test"/g'"'"' /root/.wasmd/config/client.toml' /opt/setup_wasmd.sh sed -i 's/1000000000/12000000000000/g' /opt/setup_wasmd.sh EOF + # Set up wasmd. The account numbers correspond to those in the ./accounts/ # folder. RUN /opt/setup_wasmd.sh \ @@ -32,7 +37,6 @@ RUN <