diff --git a/.github/actions/setup-anchor/action.yaml b/.github/actions/setup-anchor/action.yaml new file mode 100644 index 00000000..38b901aa --- /dev/null +++ b/.github/actions/setup-anchor/action.yaml @@ -0,0 +1,19 @@ +name: "Setup Anchor" +description: "Setup Anchor" +runs: + using: "composite" + steps: + - uses: ./.github/actions/setup/ + - uses: ./.github/actions/setup-solana/ + - uses: actions/cache@v4 + name: Cache Anchor Cli + id: cache-anchor-cli + with: + path: | + ~/.cargo/bin/anchor + key: anchor-cli-${{ runner.os }}-v0003-${{ env.ANCHOR_VERSION }}-${{ env.ANCHOR_COMMIT_HASH }} + save-always: true + # if ANCHOR_VERSION is 0, then install the anchor-cli from source + - run: if [ $ANCHOR_VERSION -eq 0 ]; then cargo install --git https://github.com/coral-xyz/anchor --rev $ANCHOR_COMMIT_HASH anchor-cli --locked --force; else cargo install --git https://github.com/coral-xyz/anchor --tag "v$ANCHOR_VERSION" anchor-cli --locked; fi + shell: bash + if: steps.cache-anchor-cli.outputs.cache-hit != 'true' diff --git a/.github/actions/setup-arcium/action.yaml b/.github/actions/setup-arcium/action.yaml new file mode 100644 index 00000000..0d8a96df --- /dev/null +++ b/.github/actions/setup-arcium/action.yaml @@ -0,0 +1,56 @@ +name: "Setup Arcium" +description: "Setup Arcium CLI using arcup" + +inputs: + ARCUP_USER: + description: "caddy username" + required: true + ARCUP_TOKEN: + description: "caddy token" + required: true + +runs: + using: "composite" + steps: + - uses: ./.github/actions/setup/ + - uses: ./.github/actions/setup-anchor/ + + # Install system dependencies (for Linux) + - name: Install Linux Dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y pkg-config build-essential libudev-dev libssl-dev + shell: bash + + # Determine target architecture + - name: Set target architecture + run: | + if [ "$RUNNER_OS" == "Linux" ]; then + if [ "$(uname -m)" == "aarch64" ]; then + echo "ARCUP_TARGET=aarch64_linux" >> $GITHUB_ENV + else + echo "ARCUP_TARGET=x86_64_linux" >> $GITHUB_ENV + fi + elif [ "$RUNNER_OS" == "macOS" ]; then + if [ "$(uname -m)" == "arm64" ]; then + echo "ARCUP_TARGET=aarch64_macos" >> $GITHUB_ENV + else + echo "ARCUP_TARGET=x86_64_macos" >> $GITHUB_ENV + fi + fi + shell: bash + + # Install arcup + - name: Install arcup + run: | + curl -u "${{ inputs.ARCUP_USER }}:${{ inputs.ARCUP_TOKEN }}" "https://bin.arcium.com/download/arcup_${ARCUP_TARGET}_${{ env.ARCUP_VERSION }}" -o ~/.cargo/bin/arcup + chmod +x ~/.cargo/bin/arcup + shell: bash + + # Install Arcium CLI + - name: Install Arcium CLI + run: | + arcup install + arcium --version + shell: bash diff --git a/.github/actions/setup-solana/action.yaml b/.github/actions/setup-solana/action.yaml new file mode 100644 index 00000000..f07c1837 --- /dev/null +++ b/.github/actions/setup-solana/action.yaml @@ -0,0 +1,48 @@ +name: "Setup Solana" +description: "Setup Solana" +runs: + using: "composite" + steps: + - uses: ./.github/actions/setup/ + - uses: actions/cache@v4 + name: Cache Solana Tool Suite + id: cache-solana + with: + path: | + ~/.cache/solana/ + ~/.local/share/solana/ + key: solana-${{ runner.os }}-v0000-${{ env.SOLANA_CLI_VERSION }} + + - run: sh -c "$(curl -sSfL https://release.anza.xyz/v${{ env.SOLANA_CLI_VERSION }}/install)" + shell: bash + if: steps.cache-solana.outputs.cache-hit != 'true' + + # Set PATH based on OS + - name: Set Solana PATH + run: | + if [ "$RUNNER_OS" == "Linux" ]; then + echo "/home/runner/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH + echo 'export PATH="/home/runner/.local/share/solana/install/active_release/bin:$PATH"' >> ~/.bashrc + elif [ "$RUNNER_OS" == "macOS" ]; then + echo "/Users/runner/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH + echo 'export PATH="/Users/runner/.local/share/solana/install/active_release/bin:$PATH"' >> ~/.bash_profile + fi + shell: bash + + # Source the profile and verify solana is available + - name: Verify Solana installation + run: | + if [ "$RUNNER_OS" == "Linux" ]; then + source ~/.bashrc + elif [ "$RUNNER_OS" == "macOS" ]; then + source ~/.bash_profile + fi + which solana + solana --version + shell: bash + + - run: solana-keygen new -s --no-bip39-passphrase --force + shell: bash + + - run: solana config set --url localhost + shell: bash diff --git a/.github/actions/setup/action.yaml b/.github/actions/setup/action.yaml new file mode 100644 index 00000000..33bc26cc --- /dev/null +++ b/.github/actions/setup/action.yaml @@ -0,0 +1,49 @@ +name: "Setup" +description: "Setup" +runs: + using: "composite" + steps: + - run: echo "RUST_VERSION=1.85.0" >> $GITHUB_ENV + shell: bash + - run: echo "ANCHOR_VERSION=0.31.0" >> $GITHUB_ENV + shell: bash + - run: echo "DEFAULT_ARCIUM_PROGRAMS_VERSION=0.1.42" >> $GITHUB_ENV + shell: bash + - run: echo "SOLANA_CLI_VERSION=2.1.6" >> $GITHUB_ENV + shell: bash + - run: echo "CARGO_TERM_COLOR=always" >> $GITHUB_ENV + shell: bash + - run: echo "RUSTFLAGS=-Dwarnings" >> $GITHUB_ENV + shell: bash + - run: echo "CARGO_NET_GIT_FETCH_WITH_CLI=true" >> $GITHUB_ENV + shell: bash + - run: echo "ARCUP_VERSION=0.1.42" >> $GITHUB_ENV + shell: bash + + # Setup Rust with specific version + - uses: actions-rs/toolchain@v1 + with: + toolchain: 1.85.0 + override: true + components: clippy + + - run: rustup update + shell: bash + + # Cache cargo registry + - uses: actions/cache@v4 + name: Cache Cargo Registry + with: + path: | + ~/.cargo/registry/ + ~/.cargo/git/ + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo- + + - name: Set git-fetch-with-cli for Cargo + run: | + echo '[net]' > ~/.cargo/config.toml + echo 'git-fetch-with-cli = true' >> ~/.cargo/config.toml + shell: bash diff --git a/.github/workflows/fmt.yaml b/.github/workflows/fmt.yaml new file mode 100644 index 00000000..f95322f4 --- /dev/null +++ b/.github/workflows/fmt.yaml @@ -0,0 +1,42 @@ +name: Formatting Check +on: + push: + branches: [main] + pull_request: + branches: [main] + +env: + CARGO_TERM_COLOR: always + +jobs: + fmt: + name: Formatting + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup/ + + - uses: actions-rs/toolchain@v1 + with: + override: true + components: rustfmt + toolchain: nightly + - run: rustup update + + # Find all example directories and their Cargo.lock files + - name: Find example directories + id: find-examples + run: | + echo "examples=$(find . -type f -name "Anchor.toml" -exec dirname {} \; | jq -R -s -c 'split("\n")[:-1]')" >> $GITHUB_OUTPUT + echo "cargo_locks=$(find . -type f -name "Cargo.lock" | jq -R -s -c 'split("\n")[:-1]')" >> $GITHUB_OUTPUT + + # Check formatting on each example + - name: Check formatting + run: | + EXAMPLES=$(echo '${{ steps.find-examples.outputs.examples }}' | jq -r '.[]') + for example in $EXAMPLES; do + echo "Checking formatting in $example" + cd $example + cargo +nightly fmt --all --check + cd $GITHUB_WORKSPACE + done diff --git a/.github/workflows/test-examples.yaml b/.github/workflows/test-examples.yaml new file mode 100644 index 00000000..07779e7d --- /dev/null +++ b/.github/workflows/test-examples.yaml @@ -0,0 +1,111 @@ +name: Test Examples +on: + push: + branches: [main] + pull_request: + branches: [main] + +env: + ARCUP_USER: testnet_user_20842437 + ARCUP_TOKEN: ${{ secrets.ARCUP_TOKEN }} + +jobs: + find-examples: + runs-on: ubuntu-24.04 + outputs: + matrix: ${{ steps.find-examples.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + - name: Find example directories + id: find-examples + run: | + echo "matrix=$(find . -type f -name "Anchor.toml" -exec dirname {} \; | jq -R -s -c '{example: split("\n")[:-1]}')" >> $GITHUB_OUTPUT + + test-examples: + needs: find-examples + name: Test ${{ matrix.example }} + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: ${{fromJson(needs.find-examples.outputs.matrix)}} + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup/ + - uses: ./.github/actions/setup-solana/ + - uses: ./.github/actions/setup-anchor/ + - uses: ./.github/actions/setup-arcium/ + with: + ARCUP_USER: testnet_user_20842437 + ARCUP_TOKEN: ${{ secrets.ARCUP_TOKEN }} + + - name: Load cached cargo registry + uses: actions/cache/restore@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + ./*/target + ./*/*/target + key: ${{ runner.os }}-cargo-${{ matrix.example }}-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-${{ matrix.example }}- + + - name: Test ${{ matrix.example }} + run: | + # Setup computation folders and vault + rm -rf /tmp/computation_folder_0 + rm -rf /tmp/computation_folder_1 + rm -rf /tmp/computation_folder_2 + rm -rf /tmp/vault + mkdir /tmp/vault + + if [[ "${{ matrix.example }}" = *"manticore"* ]]; then + echo "Manticore test" + cp -r ./examples/manticore/resources/computation_folder /tmp/computation_folder_0 + rm -r /tmp/computation_folder_0/player-1 + + cp -r ./examples/manticore/resources/computation_folder /tmp/computation_folder_1 + rm -r /tmp/computation_folder_1/player-0 + + cp -r ./examples/manticore/resources/computation_folder /tmp/computation_folder_2 + rm -r /tmp/computation_folder_2/player-0 + rm -r /tmp/computation_folder_2/player-1 + else + echo "Cerberus test" + mkdir /tmp/computation_folder_0 + mkdir /tmp/computation_folder_1 + mkdir /tmp/computation_folder_2 + fi + + pushd ${{ matrix.example }} + yarn install + arcium build + + # Run the test and capture logs + echo "Running arcium test..." + timeout 10m arcium test || EXIT_CODE=$? + echo "Most recent docker container id: $(docker ps -q -l)" + docker logs $(docker ps -q -l) + echo "=== Docker Containers ===" + docker ps -a + echo "=== Callback Server Logs ===" + cat artifacts/callback_server.log || true + echo "=== Docker Compose Logs ===" + docker compose -f artifacts/docker-compose-arx-env.yml logs || true + popd + + pkill -f solana-test-validator + + if [ -n "$EXIT_CODE" ]; then + exit $EXIT_CODE + fi + + - name: Save cargo registry + uses: actions/cache/save@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + ./*/target + ./*/*/target + key: ${{ runner.os }}-cargo-${{ matrix.example }}-${{ hashFiles('**/Cargo.lock') }} diff --git a/rock_paper_scissors/Anchor.toml b/rock_paper_scissors/Anchor.toml index b7a13866..22cf5ab6 100644 --- a/rock_paper_scissors/Anchor.toml +++ b/rock_paper_scissors/Anchor.toml @@ -17,106 +17,3 @@ wallet = "~/.config/solana/id.json" [scripts] test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" - - -[test.validator] -[[test.genesis]] -address = "BKck65TgoKRokMjQM3datB9oRwJ8rAj2jxPXvHXUvcL6" -program = "/Users/arihantbansal/Developer/arcium/examples/rock_paper_scissors/artifacts/arcium_program_0.1.41.so" - - -[[test.validator.account]] -address = "FHriyvoZotYiFnbUzKFjzRSb2NiaC8RPWY7jtKuKhg65" -filename = "artifacts/arcium_clock.json" - -[[test.validator.account]] -address = "DXHqHhBGNM58RLk438UiEbGe9137A7zJc6JHKN3qMZoB" -filename = "artifacts/arcium_pool.json" - -[[test.validator.account]] -address = "FF1ZjqVRQDfd6N5LaUh1i2PQ946vQjHpnbDuAyaCXUdQ" -filename = "artifacts/arcium_pool_ata.json" - -[[test.validator.account]] -address = "BoVUVSJAhob2cvM5z4JZTdS6VWRSznh3bbzQD1TFjvDP" -filename = "artifacts/arx_mint.json" - -[[test.validator.account]] -address = "ariZN4ANYnFyfnF12mmUuCchjawFXnepyrWdEQakFtP" -filename = "artifacts/wallet_acc_ariZ_kFtP.json" - -[[test.validator.account]] -address = "79hykNQMNeXvcpYDM2buEz1kGNnFBgnGvKPTyTUnCAEj" -filename = "artifacts/arx_ata_ariZ_kFtP.json" - -[[test.validator.account]] -address = "72QjdQ5GUge6wXGrNFyt1bLohep1wMpiJv9tcJZAcY9m" -filename = "artifacts/callback_server_acc_72Qj_cY9m.json" - -[[test.validator.account]] -address = "HdbYd9VayAXE8FJ6CZomAgCfLqC3tMjgTVJrxrJER6GB" -filename = "artifacts/wallet_acc_HdbY_R6GB.json" - -[[test.validator.account]] -address = "56Zu8VkE8ZU2Jmc8APt9ieXiZ7zMjo35CQTN6pBnx7VE" -filename = "artifacts/arx_ata_HdbY_R6GB.json" - -[[test.validator.account]] -address = "JBe2PrQKbAgHsYbtBLQmJYN7bqZe7jPGHEX1uFYCdjQ7" -filename = "artifacts/primary_stake_acc_HdbY_R6GB.json" - -[[test.validator.account]] -address = "3JrnaGFHJ8xN1Av56UvVNct5kuukN1T7BzHT8QY32q7h" -filename = "artifacts/stake_queue_acc_HdbY_R6GB.json" - -[[test.validator.account]] -address = "D7U8ohN48hnTpoQnFtbJ691tmrouzF7KH9PmuVVjejdQ" -filename = "artifacts/operator_acc_HdbY_R6GB.json" - -[[test.validator.account]] -address = "ELoRR19zrps1G3UYKcAxr7LKbw3kbqkVUXVY9dETMWN7" -filename = "artifacts/arx_node_HdbY_R6GB.json" - -[[test.validator.account]] -address = "2kLmdZKPNq5DvMAJYpHza1SCRLkogqKBbUT7CjLFvaEz" -filename = "artifacts/wallet_acc_2kLm_vaEz.json" - -[[test.validator.account]] -address = "PgJQrCiTMgC4csi7HfrcPKtd6J3SMgUsXjKhdB1XKVw" -filename = "artifacts/arx_ata_2kLm_vaEz.json" - -[[test.validator.account]] -address = "XRYD27dMKSHB4Le7bxs3mxt3EkNatifD36937FTbDBA" -filename = "artifacts/primary_stake_acc_2kLm_vaEz.json" - -[[test.validator.account]] -address = "6hZVe7g3XLWJmYrNzAtdHJxi1zzcfok4izkj2THZVdWe" -filename = "artifacts/stake_queue_acc_2kLm_vaEz.json" - -[[test.validator.account]] -address = "HGmNeV3qim4ygVhkbmCL2rTaJVHGwzzSXFGax3vhS6g5" -filename = "artifacts/operator_acc_2kLm_vaEz.json" - -[[test.validator.account]] -address = "XdfSwb8ZajhN7CerfBSJVhyfx5fyLtv34QVKSRgMFA9" -filename = "artifacts/arx_node_2kLm_vaEz.json" - -[[test.validator.account]] -address = "GgSqqAyH7AVY3Umcv8NvncrjFaNJuQLmxzxFxPoPW2Yd" -filename = "artifacts/cluster_acc_0.json" - -[[test.validator.account]] -address = "AbJy42EHMkLdWgyASv9xaEWHVtAYA8wJcmhWy7GBD7VH" -filename = "artifacts/compare_moves_raw_circuit_0.json" - -[[test.validator.account]] -address = "CXcao2ihrx1SV6fq5CDe4hq91irW57v3mxcqWLG6AiUe" -filename = "artifacts/mxe_acc.json" - -[[test.validator.account]] -address = "5J1uZyxi33TG1sLSUm3C3UFsDKDqVNaUWBAn9FTYxrxS" -filename = "artifacts/mempool_acc.json" - -[[test.validator.account]] -address = "EHN8kHXAju9pTX4nfeLXnv9VwfiN54m1XBpDqyPoLypZ" -filename = "artifacts/executing_pool_acc.json" diff --git a/rock_paper_scissors/Cargo.lock b/rock_paper_scissors/Cargo.lock index ef8299ae..0b8f55e5 100644 --- a/rock_paper_scissors/Cargo.lock +++ b/rock_paper_scissors/Cargo.lock @@ -268,9 +268,9 @@ checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "arcis" -version = "0.1.41" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "e83b9af74fb7b85d0deda56c426a17b33a9c24bc8eef5658d03f8b9350e7c36c" +checksum = "e6137e618ab8c93ed6190d5f585f22eb89badf2928cc88807298ee4e80cf7281" dependencies = [ "aes", "arcis-diagnostics", @@ -291,18 +291,18 @@ dependencies = [ [[package]] name = "arcis-diagnostics" -version = "0.1.41" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "71d3c2448c3e08482eeda68faf7038db0169153d6a421968450cca3b52a5cb01" +checksum = "49586016818bbe8ad898c207598c093cbaad60a27796b8caa3ded6d36eae65f6" dependencies = [ "colored", ] [[package]] name = "arcis-imports" -version = "0.1.41" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "96102f6a32e16bc4c603795311421d980fb80a5a01b1243e5e4ed642df47b67a" +checksum = "83ec7424c9bd64e3e205dbbdc0d33cc56ee726334a444cf8c04176465e29cab4" dependencies = [ "arcis", "arcis-interpreter-proc-macros", @@ -312,9 +312,9 @@ dependencies = [ [[package]] name = "arcis-interface" -version = "0.1.41" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "ec2768d120becb0425edfff352270ce06e6bf05c240061de033c9cf8218f460b" +checksum = "a8fe2a751c0bcdc7ecb237849f3ce48c42f7a5e147628f6c4aa543def3f09b4d" dependencies = [ "serde", "serde_json", @@ -322,9 +322,9 @@ dependencies = [ [[package]] name = "arcis-internal-expr-macro" -version = "0.1.41" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "983417b40f028070160100932d622578f1ae1bf018052963bf38697df598ba9d" +checksum = "9368171bad98701adc8e1c017724690588f87387743e8fc2c762fb6bffc09bac" dependencies = [ "indexmap", "proc-macro2", @@ -335,9 +335,9 @@ dependencies = [ [[package]] name = "arcis-interpreter" -version = "0.1.41" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "208407779e10fb5f7f8244de3e79cac8386b46dc67e6621d3a91f63d0b53c2e8" +checksum = "6d16215c338e7e919987ae73586301d4372a879aedef6c6d29808fd825b1c06d" dependencies = [ "arcis", "arcis-interface", @@ -351,18 +351,18 @@ dependencies = [ [[package]] name = "arcis-interpreter-proc-macros" -version = "0.1.41" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "facfb41036d32eac1207941fe871decaebc36414074dda8d66c27e17e52c3723" +checksum = "65ea84bab86f4e11786d4047612e3d7eb7b5fc2a06a906bb0a9baf9f7e2032d6" dependencies = [ "arcis-interpreter", ] [[package]] name = "arcium-anchor" -version = "0.1.41" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "f0c8b264ab58e1a66fa13afa13f0f5ae2a70e9b7aaa80c11e48864eddbea9842" +checksum = "ef5638e9528099b206e2f5731dc23e4a7af569dc8a1c25237d3f179a003ca9ed" dependencies = [ "anchor-lang", "anchor-spl", @@ -372,18 +372,18 @@ dependencies = [ [[package]] name = "arcium-client" -version = "0.1.41" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "ad7ae4afd276690d1c2f79db36c00e565e4f28bb2809dd1aaab62e44f4c6903b" +checksum = "323307a166ba2bddf3dfc6b7399a8f1c721541caa950975da0149ef76afc15f7" dependencies = [ "anchor-lang", ] [[package]] name = "arcium-macros" -version = "0.1.41" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "d088bd2bd580dfb1d82ec87abec0c911574c1c1fa8349d5d71d822835cac7554" +checksum = "8dcbbb4ee6841d84011e193ae84bea76b4668a9af80ba05f1f2a52921b98b366" dependencies = [ "arcis-interface", "proc-macro2", @@ -618,9 +618,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.17" +version = "1.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c" dependencies = [ "shlex", ] @@ -929,9 +929,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -1360,9 +1360,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" dependencies = [ "bitflags", ] @@ -1544,9 +1544,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "solana-account" @@ -1673,9 +1673,9 @@ dependencies = [ [[package]] name = "solana-curve25519" -version = "2.2.6" +version = "2.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91f23498bbf3ae4f22125a2f16f988a5a659628ea4949ca605a05191f91095d3" +checksum = "e0cf33066cc9a741ff4cc4d171a4a816ea06f9826516b7360d997179a1b3244f" dependencies = [ "bytemuck", "bytemuck_derive", @@ -2416,9 +2416,9 @@ dependencies = [ [[package]] name = "solana-zk-sdk" -version = "2.2.6" +version = "2.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f159f6daedab6cbd42d57945b1789f2f0d859c647dd611658227ae4330e4df" +checksum = "35a153bff0be31a58dacd7f40bc37fc80f5bb7cb3f38fb62e7a2777a8b48de25" dependencies = [ "aes-gcm-siv", "base64 0.22.1", @@ -3101,9 +3101,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" dependencies = [ "memchr", ] diff --git a/rock_paper_scissors/encrypted-ixs/Cargo.toml b/rock_paper_scissors/encrypted-ixs/Cargo.toml index e90a215f..7b8d753c 100644 --- a/rock_paper_scissors/encrypted-ixs/Cargo.toml +++ b/rock_paper_scissors/encrypted-ixs/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] -arcis-imports = { version = "0.1.41", registry = "arcium" } +arcis-imports = { version = "0.1.42", registry = "arcium" } diff --git a/rock_paper_scissors/encrypted-ixs/src/lib.rs b/rock_paper_scissors/encrypted-ixs/src/lib.rs index e5329224..c625e81d 100644 --- a/rock_paper_scissors/encrypted-ixs/src/lib.rs +++ b/rock_paper_scissors/encrypted-ixs/src/lib.rs @@ -22,7 +22,8 @@ mod circuits { result = 0; } else if (game_moves.player_move == 0 && game_moves.house_move == 2) || // Rock beats Scissors (game_moves.player_move == 1 && game_moves.house_move == 0) || // Paper beats Rock - (game_moves.player_move == 2 && game_moves.house_move == 1) // Scissors beats Paper + (game_moves.player_move == 2 && game_moves.house_move == 1) + // Scissors beats Paper { result = 1; // Player wins } else { diff --git a/rock_paper_scissors/package.json b/rock_paper_scissors/package.json index cdcf21b8..462a1bfe 100644 --- a/rock_paper_scissors/package.json +++ b/rock_paper_scissors/package.json @@ -6,7 +6,7 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.31.0", - "@arcium-hq/arcium-sdk": "0.1.41" + "@arcium-hq/arcium-sdk": "0.1.42" }, "devDependencies": { "chai": "^4.3.4", diff --git a/rock_paper_scissors/programs/rock_paper_scissors/Cargo.toml b/rock_paper_scissors/programs/rock_paper_scissors/Cargo.toml index 8c392eab..019ab039 100644 --- a/rock_paper_scissors/programs/rock_paper_scissors/Cargo.toml +++ b/rock_paper_scissors/programs/rock_paper_scissors/Cargo.toml @@ -19,9 +19,9 @@ idl-build = ["anchor-lang/idl-build"] [dependencies] anchor-lang = "0.31.0" -arcium-client = { default-features = false, version = "0.1.41", registry = "arcium" } -arcium-macros = { version = "0.1.41", registry = "arcium" } -arcium-anchor = { version = "0.1.41", registry = "arcium" } +arcium-client = { default-features = false, version = "0.1.42", registry = "arcium" } +arcium-macros = { version = "0.1.42", registry = "arcium" } +arcium-anchor = { version = "0.1.42", registry = "arcium" } # Bytemuck hotfix https://github.com/Lokathor/bytemuck/issues/306 bytemuck_derive = ">=1.8.1, <1.9.0" diff --git a/rock_paper_scissors/programs/rock_paper_scissors/src/lib.rs b/rock_paper_scissors/programs/rock_paper_scissors/src/lib.rs index bbb6286f..699d123e 100644 --- a/rock_paper_scissors/programs/rock_paper_scissors/src/lib.rs +++ b/rock_paper_scissors/programs/rock_paper_scissors/src/lib.rs @@ -40,7 +40,7 @@ pub mod rock_paper_scissors { nonce: u128, ) -> Result<()> { let args = vec![ - Argument::PublicKey(pub_key), + Argument::ArcisPubkey(pub_key), Argument::PlaintextU128(nonce), Argument::EncryptedU8(player_move), Argument::EncryptedU8(house_move), diff --git a/rock_paper_scissors/yarn.lock b/rock_paper_scissors/yarn.lock index c5d3df9b..278935cc 100644 --- a/rock_paper_scissors/yarn.lock +++ b/rock_paper_scissors/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@arcium-hq/arcium-sdk@0.1.41": - version "0.1.41" - resolved "https://npm.pkg.github.com/download/@arcium-hq/arcium-sdk/0.1.41/fe2cc82600c22e0863b64062dcf15ed8a2b6cd9e#fe2cc82600c22e0863b64062dcf15ed8a2b6cd9e" - integrity sha512-uCMM0WI69EDhNNqcOW1kXnVswjE45E6+st0MzJPlCophg8YDdXlj9qnbXACBLvQb5eCIURmtmSXK5FJ2nLNpmA== +"@arcium-hq/arcium-sdk@0.1.42": + version "0.1.42" + resolved "https://npm.pkg.github.com/download/@arcium-hq/arcium-sdk/0.1.42/d20346d06868301a9175c8abf3ea292a9190ced1#d20346d06868301a9175c8abf3ea292a9190ced1" + integrity sha512-pjTMKgH5j94XSVUduuCXeeo4VWrOJYbfClm4ESRXVGp/05U82smCXT6idYaparbEpivbnfCRIkdZfMalOSMIkw== dependencies: "@coral-xyz/anchor" "0.31" "@noble/curves" "^1.8.1" diff --git a/voting/Anchor.toml b/voting/Anchor.toml index 029e63c1..e3d3a7b4 100644 --- a/voting/Anchor.toml +++ b/voting/Anchor.toml @@ -1,18 +1,19 @@ [toolchain] +package_manager = "yarn" [features] resolution = true skip-lint = false [programs.localnet] -voting = "EGRyBhhe9pzvoznJuQh5x5Dx5V2eKQv1AwWdTsEMEYEQ" +voting = "7G3err5ACQY8b6Bpi2zpSPydWwEmtPCytzoZ4SVZAVjg" [registry] url = "https://api.apr.dev" [provider] -cluster = "Localnet" +cluster = "localnet" wallet = "~/.config/solana/id.json" [scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" +test = "yarn run ts-mocha -p ./tsconfig.json -t 2000000 tests/**/*.ts" diff --git a/voting/Cargo.lock b/voting/Cargo.lock index 698ee100..d3434375 100644 --- a/voting/Cargo.lock +++ b/voting/Cargo.lock @@ -139,7 +139,7 @@ dependencies = [ "anchor-syn", "anyhow", "bs58", - "heck 0.3.3", + "heck", "proc-macro2", "quote", "serde_json", @@ -213,7 +213,7 @@ checksum = "32e8599d21995f68e296265aa5ab0c3cef582fd58afec014d01bd0bce18a4418" dependencies = [ "anchor-lang-idl-spec", "anyhow", - "heck 0.3.3", + "heck", "regex", "serde", "serde_json", @@ -250,7 +250,7 @@ dependencies = [ "anyhow", "bs58", "cargo_toml", - "heck 0.3.3", + "heck", "proc-macro2", "quote", "serde", @@ -268,17 +268,14 @@ checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "arcis" -version = "0.1.40" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "d5e9a68a49a800fea00b814e66041197e84174f4ff997c583e61aa728ade9abf" +checksum = "e6137e618ab8c93ed6190d5f585f22eb89badf2928cc88807298ee4e80cf7281" dependencies = [ "aes", "arcis-diagnostics", "arcis-internal-expr-macro", "bincode", - "crypto-bigint", - "derive_more", - "enum-try-as-inner", "ff", "indexmap", "num-bigint 0.4.6", @@ -289,25 +286,23 @@ dependencies = [ "rand_seeder", "rustc-hash", "serde", - "serde_bytes", - "serde_json", "sha3", ] [[package]] name = "arcis-diagnostics" -version = "0.1.40" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "199dcf23760c4e9bf10c1cb77c999d4c90e7a0cde3bb661236239fd653a8fe1c" +checksum = "49586016818bbe8ad898c207598c093cbaad60a27796b8caa3ded6d36eae65f6" dependencies = [ "colored", ] [[package]] name = "arcis-imports" -version = "0.1.40" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "c358c4fb70c6990ec6f733a477e92fc30cf1c47820a4c5c9c983d96b05ed776c" +checksum = "83ec7424c9bd64e3e205dbbdc0d33cc56ee726334a444cf8c04176465e29cab4" dependencies = [ "arcis", "arcis-interpreter-proc-macros", @@ -315,11 +310,21 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "arcis-interface" +version = "0.1.42" +source = "sparse+https://crates.arcium.com/api/v1/crates/" +checksum = "a8fe2a751c0bcdc7ecb237849f3ce48c42f7a5e147628f6c4aa543def3f09b4d" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "arcis-internal-expr-macro" -version = "0.1.40" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "ff183a90a0ab4650f0078a0698fe0b846ac0cab1000b5ffc21c71553beb66536" +checksum = "9368171bad98701adc8e1c017724690588f87387743e8fc2c762fb6bffc09bac" dependencies = [ "indexmap", "proc-macro2", @@ -330,11 +335,12 @@ dependencies = [ [[package]] name = "arcis-interpreter" -version = "0.1.40" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "419f2ca1b3ef4a0a5f8c5be5944854862e91cf9b3b7633d300762d1413220672" +checksum = "6d16215c338e7e919987ae73586301d4372a879aedef6c6d29808fd825b1c06d" dependencies = [ "arcis", + "arcis-interface", "ff", "indexmap", "num-traits", @@ -345,18 +351,18 @@ dependencies = [ [[package]] name = "arcis-interpreter-proc-macros" -version = "0.1.40" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "5a8e0a88c85c73e3b8a14eec07aa4da742fa92418be24f62e420e7a3b351878f" +checksum = "65ea84bab86f4e11786d4047612e3d7eb7b5fc2a06a906bb0a9baf9f7e2032d6" dependencies = [ "arcis-interpreter", ] [[package]] name = "arcium-anchor" -version = "0.1.40" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "d44c1b09994816a87da88d230083a1dde8ff700540846cb77d3644a6f649b1df" +checksum = "ef5638e9528099b206e2f5731dc23e4a7af569dc8a1c25237d3f179a003ca9ed" dependencies = [ "anchor-lang", "anchor-spl", @@ -366,20 +372,20 @@ dependencies = [ [[package]] name = "arcium-client" -version = "0.1.40" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "ecc50bc022962bd6f38a57cb7c87b817069de8c0eccce5764af31a34da88cc8f" +checksum = "323307a166ba2bddf3dfc6b7399a8f1c721541caa950975da0149ef76afc15f7" dependencies = [ "anchor-lang", ] [[package]] name = "arcium-macros" -version = "0.1.40" +version = "0.1.42" source = "sparse+https://crates.arcium.com/api/v1/crates/" -checksum = "ac373ee62da44e232e4e881482d1a9cb29707867f3b1bd57c32f3cd7d1c811f0" +checksum = "8dcbbb4ee6841d84011e193ae84bea76b4668a9af80ba05f1f2a52921b98b366" dependencies = [ - "arcis", + "arcis-interface", "proc-macro2", "quote", "sha2 0.10.8", @@ -404,12 +410,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - [[package]] name = "base64" version = "0.12.3" @@ -457,9 +457,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b17679a8d69b6d7fd9cd9801a536cec9fa5e5970b69f9d4747f70b39b031f5e7" +checksum = "389a099b34312839e16420d499a9cad9650541715937ffbdd40d36f49e77eeb3" dependencies = [ "arrayref", "arrayvec", @@ -499,11 +499,11 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.6" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b74d67a0fc0af8e9823b79fd1c43a0900e5a8f0e0f4cc9210796bf3a820126" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" dependencies = [ - "borsh-derive 1.5.6", + "borsh-derive 1.5.7", "cfg_aliases", ] @@ -522,9 +522,9 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.6" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d37ed1b2c9b78421218a0b4f6d8349132d6ec2cfeba1cfb0118b0a8e268df9e" +checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" dependencies = [ "once_cell", "proc-macro-crate 3.3.0", @@ -618,9 +618,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.17" +version = "1.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c" dependencies = [ "shlex", ] @@ -698,17 +698,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "rand_core 0.6.4", - "serdect", - "subtle", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -764,27 +753,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" -[[package]] -name = "derive_more" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", - "unicode-xid", -] - [[package]] name = "digest" version = "0.9.0" @@ -818,18 +786,6 @@ dependencies = [ "arcis-imports", ] -[[package]] -name = "enum-try-as-inner" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c448fc2753338b04aa344ead5a6bdda26f2df2dcd85b65c86dd15b16819369e" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 2.0.100", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -962,12 +918,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "hmac" version = "0.12.1" @@ -979,9 +929,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -1101,9 +1051,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "memchr" @@ -1207,9 +1157,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.1" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "opaque-debug" @@ -1410,9 +1360,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" dependencies = [ "bitflags", ] @@ -1535,16 +1485,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serdect" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" -dependencies = [ - "base16ct", - "serde", -] - [[package]] name = "sha2" version = "0.9.9" @@ -1593,9 +1533,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "solana-account" @@ -1690,7 +1630,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "718333bcd0a1a7aed6655aa66bef8d7fb047944922b2d3a18f49cbc13e73d004" dependencies = [ "borsh 0.10.4", - "borsh 1.5.6", + "borsh 1.5.7", ] [[package]] @@ -1722,9 +1662,9 @@ dependencies = [ [[package]] name = "solana-curve25519" -version = "2.2.3" +version = "2.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1f28fdc4acdf6d1e47eec6fea58e88a650ca08f6a779d34730a616a2a82801" +checksum = "e0cf33066cc9a741ff4cc4d171a4a816ea06f9826516b7360d997179a1b3244f" dependencies = [ "bytemuck", "bytemuck_derive", @@ -1844,7 +1784,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf7bcb14392900fe02e4e34e90234fbf0c673d4e327888410ba99fa2ba0f4e99" dependencies = [ - "borsh 1.5.6", + "borsh 1.5.7", "bs58", "bytemuck", "bytemuck_derive", @@ -1863,7 +1803,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce496a475e5062ba5de97215ab39d9c358f9c9df4bb7f3a45a1f1a8bd9065ed" dependencies = [ "bincode", - "borsh 1.5.6", + "borsh 1.5.7", "getrandom 0.2.15", "js-sys", "num-traits", @@ -1962,9 +1902,9 @@ dependencies = [ [[package]] name = "solana-message" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "268486ba8a294ed22a4d7c1ec05f540c3dbe71cfa7c6c54b6d4d13668d895678" +checksum = "9c6bf99c4570173710107a1f233f3bee226feea5fc817308707d4f7cb100a72d" dependencies = [ "bincode", "blake3", @@ -2021,7 +1961,7 @@ dependencies = [ "bincode", "blake3", "borsh 0.10.4", - "borsh 1.5.6", + "borsh 1.5.7", "bs58", "bytemuck", "console_error_panic_hook", @@ -2110,7 +2050,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8ae2c1a8d0d4ae865882d5770a7ebca92bab9c685e43f0461682c6c05a35bfa" dependencies = [ - "borsh 1.5.6", + "borsh 1.5.7", "num-traits", "serde", "serde_derive", @@ -2152,7 +2092,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40db1ff5a0f8aea2c158d78ab5f2cf897848964251d1df42fef78efd3c85b863" dependencies = [ "borsh 0.10.4", - "borsh 1.5.6", + "borsh 1.5.7", "bs58", "bytemuck", "bytemuck_derive", @@ -2352,7 +2292,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" dependencies = [ "borsh 0.10.4", - "borsh 1.5.6", + "borsh 1.5.7", "num-traits", "serde", "serde_derive", @@ -2441,9 +2381,9 @@ dependencies = [ [[package]] name = "solana-vote-interface" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e9f6a1651310a94cd5a1a6b7f33ade01d9e5ea38a2220becb5fd737b756514" +checksum = "6b630547b7f12ee742e1c5069951fedba0fe5cbd4786f6342a779384e2b11f71" dependencies = [ "bincode", "num-derive", @@ -2465,9 +2405,9 @@ dependencies = [ [[package]] name = "solana-zk-sdk" -version = "2.2.3" +version = "2.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf45055dc78b74fdced852f9ed3a6f46eb13754f88b75675d9ce2bc7f242ea9" +checksum = "35a153bff0be31a58dacd7f40bc37fc80f5bb7cb3f38fb62e7a2777a8b48de25" dependencies = [ "aes-gcm-siv", "base64 0.22.1", @@ -2506,7 +2446,7 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76fee7d65013667032d499adc3c895e286197a35a0d3a4643c80e7fd3e9969e3" dependencies = [ - "borsh 1.5.6", + "borsh 1.5.7", "num-derive", "num-traits", "solana-program", @@ -2595,7 +2535,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d994afaf86b779104b4a95ba9ca75b8ced3fdb17ee934e38cb69e72afbe17799" dependencies = [ - "borsh 1.5.6", + "borsh 1.5.7", "bytemuck", "bytemuck_derive", "num-derive", @@ -2761,7 +2701,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfb9c89dbc877abd735f05547dcf9e6e12c00c11d6d74d8817506cab4c99fdbb" dependencies = [ - "borsh 1.5.6", + "borsh 1.5.7", "num-derive", "num-traits", "solana-borsh", @@ -2969,12 +2909,6 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "universal-hash" version = "0.5.1" @@ -3167,9 +3101,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" dependencies = [ "memchr", ] diff --git a/voting/Cargo.toml b/voting/Cargo.toml index 28d599f7..76f1a106 100644 --- a/voting/Cargo.toml +++ b/voting/Cargo.toml @@ -1,7 +1,6 @@ [workspace] -edition = "2021" -resolver = "2" members = ["programs/*", "encrypted-ixs"] +resolver = "2" [profile.release] overflow-checks = true diff --git a/voting/README.md b/voting/README.md index b30e06ed..59ca0c0a 100644 --- a/voting/README.md +++ b/voting/README.md @@ -1,68 +1,66 @@ -# Confidential On-Chain Voting with Arcium +# Anonymous Voting with Arcium -This example demonstrates how to implement confidential voting on Solana using Arcium's encrypted computation framework. The system allows voters to cast their votes privately while maintaining the integrity of the voting process. +This project demonstrates how to implement truly anonymous voting on Solana using Arcium's confidential computing capabilities. It showcases how to create private polls where individual votes remain confidential while still allowing for verifiable results. -## Overview +## Why Arcium is Necessary for Anonymous Voting -The voting system consists of three main components: +Traditional blockchains are transparent by design, making it impossible to implement truly anonymous voting without additional privacy layers. Here's why Arcium is essential: -1. Creating a poll -2. Casting a vote -3. Revealing results - -### Key Features - -- **Confidential Voting**: Votes are encrypted and processed in a privacy-preserving manner -- **Secure Result Revelation**: Only the poll authority can reveal the final results +- **Public Nature of Blockchains**: All data on a regular blockchain is visible to everyone +- **Privacy Requirements**: Votes must remain confidential to ensure anonymity +- **Security Concerns**: Even encrypted votes would require decryption keys, creating vulnerabilities +- **Distributed Trust**: Arcium uses Multi-Party Computation (MPC) to achieve a trust-minimized setup for confidential computing ## How It Works ### 1. Poll Creation -When a new poll is created: - -- A unique poll account is initialized with a question and initial encrypted vote counts -- The vote counts are initialized to zero using encrypted computation -- The poll creator becomes the authority who can later reveal results - -### 2. Vote Casting - -The voting process uses Arcium's encrypted computation framework: - -- Each vote is encrypted using the client's encryption key -- Votes are processed using homomorphic encryption, allowing addition of encrypted values -- The vote counts are updated without revealing individual votes -- A timestamp is recorded for each vote for audit purposes - -### 3. Result Revelation - -Only the poll authority can reveal the final results: - -- The encrypted vote counts are processed to determine the winner -- The result is revealed as a boolean (true for "yes" winning, false for "no" winning) -- The process maintains privacy of individual votes while providing verifiable results - -## Technical Implementation - -### Encrypted Computation - -The system uses Arcium's encrypted instruction framework, Arcis, with three main computations: - -1. `init_vote_stats`: Initializes encrypted vote counts -2. `vote`: Processes an encrypted vote and updates the encrypted vote counts -3. `reveal_result`: Computes the final result from encrypted vote counts - -### Data Structures - -- `PollAccount`: Solana account structure that stores poll metadata and encrypted vote state -- Arcis Data Structures (used in encrypted computation): - - `VoteStats`: Encrypted structure containing yes/no vote counts, processed within Arcis - - `UserVote`: Encrypted structure for individual votes, processed within Arcis - -### Privacy Guarantees - -The system ensures: - -- Individual votes remain private -- Vote counts are encrypted during computation -- Results are only revealed when explicitly requested by the authority +```typescript +const pollSig = await program.methods.createNewPoll( + POLL_ID, + `Poll ${POLL_ID}: $SOL to 500?`, + new anchor.BN(deserializeLE(pollNonce).toString()) +); +``` + +- Creates a new poll with a unique ID and title +- Uses a cryptographic nonce for security operations +- Establishes the voting context on-chain + +### 2. Voting Process + +```typescript +const vote = BigInt(true); +const plaintext = [vote]; +const nonce = randomBytes(16); +const ciphertext = cipher.encrypt(plaintext, nonce); +``` + +- Votes are encrypted using x25519 (key exchange) and RescueCipher +- Each vote uses a unique nonce for security +- Votes remain confidential even when stored on-chain + +### 3. Confidential Computation + +```typescript +const queueVoteSig = await program.methods.vote( + POLL_ID, + Array.from(ciphertext[0]), + Array.from(publicKey), + new anchor.BN(deserializeLE(nonce).toString()) +); +``` + +- Encrypted votes are processed using MPC across multiple parties +- Computation is distributed across the Arcium network +- Individual vote values remain confidential throughout the computation + +### 4. Result Revealed + +```typescript +const revealQueueSig = await program.methods.revealResult(POLL_ID); +``` + +- Only the final result (e.g., majority vote) is revealed +- Individual votes remain confidential +- Results are computed through MPC and only the outcome is published diff --git a/voting/encrypted-ixs/Cargo.toml b/voting/encrypted-ixs/Cargo.toml index 1a0ce80c..7b8d753c 100644 --- a/voting/encrypted-ixs/Cargo.toml +++ b/voting/encrypted-ixs/Cargo.toml @@ -3,9 +3,5 @@ name = "encrypted-ixs" version = "0.1.0" edition = "2021" -[features] -default = ["arcis-imports/default"] -solana = ["arcis-imports/solana"] - [dependencies] -arcis-imports = { version = "0.1.40", registry = "arcium", default-features = false } +arcis-imports = { version = "0.1.42", registry = "arcium" } diff --git a/voting/migrations/deploy.ts b/voting/migrations/deploy.ts index 82fb175f..439431ec 100644 --- a/voting/migrations/deploy.ts +++ b/voting/migrations/deploy.ts @@ -2,9 +2,9 @@ // single deploy script that's invoked from the CLI, injecting a provider // configured from the workspace's Anchor.toml. -const anchor = require("@coral-xyz/anchor"); +import * as anchor from "@coral-xyz/anchor"; -module.exports = async function (provider) { +module.exports = async function (provider: anchor.AnchorProvider) { // Configure client to use the provider. anchor.setProvider(provider); diff --git a/voting/package.json b/voting/package.json index c3e0f01b..462a1bfe 100644 --- a/voting/package.json +++ b/voting/package.json @@ -6,7 +6,7 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.31.0", - "@arcium-hq/arcium-sdk": "0.1.40" + "@arcium-hq/arcium-sdk": "0.1.42" }, "devDependencies": { "chai": "^4.3.4", diff --git a/voting/programs/voting/Cargo.toml b/voting/programs/voting/Cargo.toml index 4844c2a7..e2cd6363 100644 --- a/voting/programs/voting/Cargo.toml +++ b/voting/programs/voting/Cargo.toml @@ -19,9 +19,9 @@ idl-build = ["anchor-lang/idl-build"] [dependencies] anchor-lang = "0.31.0" -arcium-client = { default-features = false, version = "0.1.40", registry = "arcium" } -arcium-macros = { version = "0.1.40", registry = "arcium" } -arcium-anchor = { version = "0.1.40", registry = "arcium" } +arcium-client = { default-features = false, version = "0.1.42", registry = "arcium" } +arcium-macros = { version = "0.1.42", registry = "arcium" } +arcium-anchor = { version = "0.1.42", registry = "arcium" } # Bytemuck hotfix https://github.com/Lokathor/bytemuck/issues/306 bytemuck_derive = ">=1.8.1, <1.9.0" diff --git a/voting/programs/voting/src/lib.rs b/voting/programs/voting/src/lib.rs index 23191c76..c798c469 100644 --- a/voting/programs/voting/src/lib.rs +++ b/voting/programs/voting/src/lib.rs @@ -1,7 +1,7 @@ use anchor_lang::prelude::*; use arcium_anchor::{ comp_def_offset, derive_cluster_pda, derive_comp_def_pda, derive_execpool_pda, - derive_mempool_pda, derive_mxe_pda, init_comp_def, queue_computation, + derive_mempool_pda, derive_mxe_pda, init_comp_def, queue_computation, ComputationOutputs, ARCIUM_CLOCK_ACCOUNT_ADDRESS, ARCIUM_STAKING_POOL_ACCOUNT_ADDRESS, CLUSTER_PDA_SEED, COMP_DEF_PDA_SEED, EXECPOOL_PDA_SEED, MEMPOOL_PDA_SEED, MXE_PDA_SEED, }; @@ -23,7 +23,7 @@ const COMP_DEF_OFFSET_INIT_VOTE_STATS: u32 = comp_def_offset("init_vote_stats"); const COMP_DEF_OFFSET_VOTE: u32 = comp_def_offset("vote"); const COMP_DEF_OFFSET_REVEAL: u32 = comp_def_offset("reveal_result"); -declare_id!("EGRyBhhe9pzvoznJuQh5x5Dx5V2eKQv1AwWdTsEMEYEQ"); +declare_id!("7G3err5ACQY8b6Bpi2zpSPydWwEmtPCytzoZ4SVZAVjg"); #[arcium_program] pub mod voting { @@ -67,19 +67,25 @@ pub mod voting { #[arcium_callback(encrypted_ix = "init_vote_stats")] pub fn init_vote_stats_callback( ctx: Context, - output: Vec, + output: ComputationOutputs, ) -> Result<()> { - let vote_stats: [[u8; 32]; 2] = output + let bytes = if let ComputationOutputs::Bytes(bytes) = output { + bytes + } else { + return Err(ErrorCode::AbortedComputation.into()); + }; + + let vote_stats_nonce: [u8; 16] = bytes[0..16].try_into().unwrap(); + + let vote_stats: [[u8; 32]; 2] = bytes[16..] .chunks_exact(32) .map(|c| c.try_into().unwrap()) .collect::>() .try_into() .unwrap(); - let mut poll_acc = - PollAccount::try_deserialize(&mut &ctx.accounts.poll_acc.data.borrow()[..])?; - poll_acc.vote_state = vote_stats; - poll_acc.try_serialize(&mut *ctx.accounts.poll_acc.try_borrow_mut_data()?)?; + ctx.accounts.poll_acc.vote_state = vote_stats; + ctx.accounts.poll_acc.nonce = u128::from_le_bytes(vote_stats_nonce); Ok(()) } @@ -91,21 +97,20 @@ pub mod voting { pub fn vote( ctx: Context, - id: u32, + _id: u32, vote: [u8; 32], vote_encryption_pubkey: [u8; 32], vote_nonce: u128, - vote_stats_nonce: u128, ) -> Result<()> { let args = vec![ - Argument::PublicKey(vote_encryption_pubkey), + Argument::ArcisPubkey(vote_encryption_pubkey), Argument::PlaintextU128(vote_nonce), Argument::EncryptedBool(vote), - Argument::PlaintextU128(vote_stats_nonce), + Argument::PlaintextU128(ctx.accounts.poll_acc.nonce), Argument::Account( ctx.accounts.poll_acc.key(), - // Offset of 8 (discriminator), 1 (bump), 4 + 50 (question), 4 (id), 32 (authority), 16 (nonce) - 8 + 1 + (4 + 50) + 4 + 32 + 16, + // Offset of 8 (discriminator) and 1 (bump) + 8 + 1, 32 * 2, // 2 counts, each saved as a ciphertext (so 32 bytes each) ), ]; @@ -123,18 +128,23 @@ pub mod voting { } #[arcium_callback(encrypted_ix = "vote")] - pub fn vote_callback(ctx: Context, output: Vec) -> Result<()> { - let vote_stats: [[u8; 32]; 2] = output + pub fn vote_callback(ctx: Context, output: ComputationOutputs) -> Result<()> { + let bytes = if let ComputationOutputs::Bytes(bytes) = output { + bytes + } else { + return Err(ErrorCode::AbortedComputation.into()); + }; + + let vote_stats_nonce: [u8; 16] = bytes[0..16].try_into().unwrap(); + let vote_stats: [[u8; 32]; 2] = bytes[16..] .chunks_exact(32) .map(|c| c.try_into().unwrap()) .collect::>() .try_into() .unwrap(); - let mut poll_acc = - PollAccount::try_deserialize(&mut &ctx.accounts.poll_acc.data.borrow()[..])?; - poll_acc.vote_state = vote_stats; - poll_acc.try_serialize(&mut *ctx.accounts.poll_acc.try_borrow_mut_data()?)?; + ctx.accounts.poll_acc.vote_state = vote_stats; + ctx.accounts.poll_acc.nonce = u128::from_le_bytes(vote_stats_nonce); let clock = Clock::get()?; let current_timestamp = clock.unix_timestamp; @@ -151,11 +161,7 @@ pub mod voting { Ok(()) } - pub fn reveal_result( - ctx: Context, - id: u32, - vote_stats_nonce: u128, - ) -> Result<()> { + pub fn reveal_result(ctx: Context, id: u32) -> Result<()> { require!( ctx.accounts.payer.key() == ctx.accounts.poll_acc.authority, ErrorCode::InvalidAuthority @@ -164,11 +170,11 @@ pub mod voting { msg!("Revealing voting result for poll with id {}", id); let args = vec![ - Argument::PlaintextU128(vote_stats_nonce), + Argument::PlaintextU128(ctx.accounts.poll_acc.nonce), Argument::Account( ctx.accounts.poll_acc.key(), - // Offset of 8 (discriminator), 1 (bump), 4 + 50 (question), 4 (id), 32 (authority), 16 (nonce) - 8 + 1 + (4 + 50) + 4 + 32 + 16, + // Offset of 8 (discriminator) and 1 (bump) + 8 + 1, 32 * 2, // 2 counts, each saved as a ciphertext (so 32 bytes each) ), ]; @@ -180,10 +186,17 @@ pub mod voting { #[arcium_callback(encrypted_ix = "reveal_result")] pub fn reveal_result_callback( ctx: Context, - output: Vec, + output: ComputationOutputs, ) -> Result<()> { - let result = output[0] != 0; + let bytes = if let ComputationOutputs::Bytes(bytes) = output { + bytes + } else { + return Err(ErrorCode::AbortedComputation.into()); + }; + + let result = bytes[0] != 0; emit!(RevealResultEvent { output: result }); + Ok(()) } } @@ -253,7 +266,7 @@ pub struct InitVoteStatsCallback<'info> { pub instructions_sysvar: AccountInfo<'info>, /// CHECK: poll_acc, checked by the callback account key passed in queue_computation #[account(mut)] - pub poll_acc: UncheckedAccount<'info>, + pub poll_acc: Account<'info, PollAccount>, } #[init_computation_definition_accounts("init_vote_stats", payer)] @@ -276,7 +289,7 @@ pub struct InitVoteStatsCompDef<'info> { #[queue_computation_accounts("vote", payer)] #[derive(Accounts)] -#[instruction(id: u32)] +#[instruction(_id: u32)] pub struct Vote<'info> { #[account(mut)] pub payer: Signer<'info>, @@ -320,7 +333,7 @@ pub struct Vote<'info> { )] pub authority: UncheckedAccount<'info>, #[account( - seeds = [b"poll", authority.key().as_ref(), id.to_le_bytes().as_ref()], + seeds = [b"poll", authority.key().as_ref(), _id.to_le_bytes().as_ref()], bump = poll_acc.bump, has_one = authority )] @@ -340,9 +353,8 @@ pub struct VoteCallback<'info> { #[account(address = ::anchor_lang::solana_program::sysvar::instructions::ID)] /// CHECK: instructions_sysvar, checked by the account constraint pub instructions_sysvar: AccountInfo<'info>, - /// CHECK: poll_acc, checked by the callback account key passed in queue_computation #[account(mut)] - pub poll_acc: UncheckedAccount<'info>, + pub poll_acc: Account<'info, PollAccount>, } #[init_computation_definition_accounts("vote", payer)] @@ -447,19 +459,21 @@ pub struct InitRevealResultCompDef<'info> { #[derive(InitSpace)] pub struct PollAccount { pub bump: u8, - #[max_len(50)] - pub question: String, + // 2 counts, each saved as a ciphertext (so 32 bytes each) + pub vote_state: [[u8; 32]; 2], pub id: u32, pub authority: Pubkey, pub nonce: u128, - // 2 counts, each saved as a ciphertext (so 32 bytes each) - pub vote_state: [[u8; 32]; 2], + #[max_len(50)] + pub question: String, } #[error_code] pub enum ErrorCode { #[msg("Invalid authority")] InvalidAuthority, + #[msg("The computation was aborted")] + AbortedComputation, } #[event] diff --git a/voting/tests/voting.ts b/voting/tests/voting.ts index 05936d94..5433dd1a 100644 --- a/voting/tests/voting.ts +++ b/voting/tests/voting.ts @@ -12,14 +12,12 @@ import { uploadCircuit, buildFinalizeCompDefTx, RescueCipher, - x25519RandomPrivateKey, - x25519GetPublicKey, - x25519GetSharedSecretWithMXE, deserializeLE, getMXEAccAcc, getMempoolAcc, getCompDefAcc, getExecutingPoolAcc, + x25519, } from "@arcium-hq/arcium-sdk"; import * as fs from "fs"; import * as os from "os"; @@ -47,7 +45,7 @@ describe("Voting", () => { const arciumEnv = getArciumEnv(); it("Is initialized!", async () => { - const POLL_ID = 420; + const POLL_IDS = [420, 421, 422]; const owner = readKpJson(`${os.homedir()}/.config/solana/id.json`); console.log("Initializing vote stats computation definition"); @@ -71,143 +69,138 @@ describe("Voting", () => { initRRSig ); - const privateKey = x25519RandomPrivateKey(); - const publicKey = x25519GetPublicKey(privateKey); - const mxePublicKey = [ - new Uint8Array([ - 34, 56, 246, 3, 165, 122, 74, 68, 14, 81, 107, 73, 129, 145, 196, 4, 98, - 253, 120, 15, 235, 108, 37, 198, 124, 111, 38, 1, 210, 143, 72, 87, - ]), - new Uint8Array([ - 107, 1, 201, 151, 195, 126, 155, 84, 228, 85, 185, 142, 62, 220, 161, - 29, 179, 36, 112, 163, 201, 103, 172, 207, 55, 89, 53, 120, 73, 208, - 234, 63, - ]), - new Uint8Array([ - 217, 186, 137, 28, 190, 167, 128, 220, 100, 71, 90, 160, 130, 162, 96, - 15, 191, 147, 184, 4, 151, 89, 186, 211, 72, 212, 173, 31, 98, 187, 65, - 59, - ]), - new Uint8Array([ - 51, 66, 84, 103, 52, 182, 174, 177, 134, 163, 224, 196, 127, 102, 81, - 61, 12, 136, 171, 212, 230, 171, 242, 47, 221, 48, 152, 231, 239, 0, - 183, 15, - ]), - new Uint8Array([ - 162, 140, 124, 61, 16, 202, 184, 56, 39, 7, 37, 95, 225, 104, 229, 25, - 48, 246, 35, 136, 99, 106, 110, 253, 188, 86, 201, 42, 112, 211, 129, - 34, - ]), - ]; - - const pollNonce = randomBytes(16); - - const pollSig = await program.methods - .createNewPoll( - POLL_ID, - "$SOL to 500?", - new anchor.BN(deserializeLE(pollNonce).toString()) - ) - .accountsPartial({ - clusterAccount: arciumEnv.arciumClusterPubkey, - mxeAccount: getMXEAccAcc(program.programId), - mempoolAccount: getMempoolAcc(program.programId), - executingPool: getExecutingPoolAcc(program.programId), - compDefAccount: getCompDefAcc( - program.programId, - Buffer.from(getCompDefAccOffset("init_vote_stats")).readUInt32LE() - ), - }) - .rpc(); - - console.log("Poll created with signature", pollSig); - - const finalizePollSig = await awaitComputationFinalization( - provider as anchor.AnchorProvider, - pollSig, - program.programId, - "confirmed" - ); - console.log("Finalize poll sig is ", finalizePollSig); - - const rescueKey = x25519GetSharedSecretWithMXE(privateKey, mxePublicKey); - const cipher = new RescueCipher(rescueKey); - - const vote = BigInt(true); - const plaintext = [vote]; - - const nonce = randomBytes(16); - const ciphertext = cipher.encrypt(plaintext, nonce); - - const voteEventPromise = awaitEvent("voteEvent"); - - // TODO: Remove this sleep once the CI bug is solved - await new Promise((resolve) => setTimeout(resolve, 100)); - - console.log("Voting"); - - const queueVoteSig = await program.methods - .vote( - POLL_ID, - Array.from(ciphertext[0]), - Array.from(publicKey), - new anchor.BN(deserializeLE(nonce).toString()), - new anchor.BN(deserializeLE(pollNonce).toString()) - ) - .accountsPartial({ - clusterAccount: arciumEnv.arciumClusterPubkey, - mxeAccount: getMXEAccAcc(program.programId), - mempoolAccount: getMempoolAcc(program.programId), - executingPool: getExecutingPoolAcc(program.programId), - compDefAccount: getCompDefAcc( - program.programId, - Buffer.from(getCompDefAccOffset("vote")).readUInt32LE() - ), - authority: owner.publicKey, - }) - .rpc({ commitment: "confirmed" }); - console.log("Queue vote sig is ", queueVoteSig); - - const finalizeSig = await awaitComputationFinalization( - provider as anchor.AnchorProvider, - queueVoteSig, - program.programId, - "confirmed" - ); - console.log("Finalize sig is ", finalizeSig); - - const voteEvent = await voteEventPromise; - console.log("Vote casted at timestamp ", voteEvent.timestamp.toString()); + const privateKey = x25519.utils.randomPrivateKey(); + const publicKey = x25519.getPublicKey(privateKey); + const mxePublicKey = new Uint8Array([ + 34, 56, 246, 3, 165, 122, 74, 68, 14, 81, 107, 73, 129, 145, 196, 4, 98, + 253, 120, 15, 235, 108, 37, 198, 124, 111, 38, 1, 210, 143, 72, 87, + ]); + const sharedSecret = x25519.getSharedSecret(privateKey, mxePublicKey); + const cipher = new RescueCipher(sharedSecret); + + // Create multiple polls + for (const POLL_ID of POLL_IDS) { + const pollNonce = randomBytes(16); + + const pollSig = await program.methods + .createNewPoll( + POLL_ID, + `Poll ${POLL_ID}: $SOL to 500?`, + new anchor.BN(deserializeLE(pollNonce).toString()) + ) + .accountsPartial({ + clusterAccount: arciumEnv.arciumClusterPubkey, + mxeAccount: getMXEAccAcc(program.programId), + mempoolAccount: getMempoolAcc(program.programId), + executingPool: getExecutingPoolAcc(program.programId), + compDefAccount: getCompDefAcc( + program.programId, + Buffer.from(getCompDefAccOffset("init_vote_stats")).readUInt32LE() + ), + }) + .rpc(); + + console.log(`Poll ${POLL_ID} created with signature`, pollSig); + + const finalizePollSig = await awaitComputationFinalization( + provider as anchor.AnchorProvider, + pollSig, + program.programId, + "confirmed" + ); + console.log(`Finalize poll ${POLL_ID} sig is `, finalizePollSig); + } - const revealEventPromise = awaitEvent("revealResultEvent"); + // Cast votes for each poll with different outcomes + const voteOutcomes = [true, false, true]; // Different outcomes for each poll + for (let i = 0; i < POLL_IDS.length; i++) { + const POLL_ID = POLL_IDS[i]; + const vote = BigInt(voteOutcomes[i]); + const plaintext = [vote]; + + const nonce = randomBytes(16); + const ciphertext = cipher.encrypt(plaintext, nonce); + + const voteEventPromise = awaitEvent("voteEvent"); + + console.log(`Voting for poll ${POLL_ID}`); + + const queueVoteSig = await program.methods + .vote( + POLL_ID, + Array.from(ciphertext[0]), + Array.from(publicKey), + new anchor.BN(deserializeLE(nonce).toString()) + ) + .accountsPartial({ + clusterAccount: arciumEnv.arciumClusterPubkey, + mxeAccount: getMXEAccAcc(program.programId), + mempoolAccount: getMempoolAcc(program.programId), + executingPool: getExecutingPoolAcc(program.programId), + compDefAccount: getCompDefAcc( + program.programId, + Buffer.from(getCompDefAccOffset("vote")).readUInt32LE() + ), + authority: owner.publicKey, + }) + .rpc({ commitment: "confirmed" }); + console.log(`Queue vote for poll ${POLL_ID} sig is `, queueVoteSig); + + const finalizeSig = await awaitComputationFinalization( + provider as anchor.AnchorProvider, + queueVoteSig, + program.programId, + "confirmed" + ); + console.log(`Finalize vote for poll ${POLL_ID} sig is `, finalizeSig); - const revealQueueSig = await program.methods - .revealResult(POLL_ID, new anchor.BN(deserializeLE(pollNonce).toString())) - .accountsPartial({ - clusterAccount: arciumEnv.arciumClusterPubkey, - mxeAccount: getMXEAccAcc(program.programId), - mempoolAccount: getMempoolAcc(program.programId), - executingPool: getExecutingPoolAcc(program.programId), - compDefAccount: getCompDefAcc( - program.programId, - Buffer.from(getCompDefAccOffset("reveal_result")).readUInt32LE() - ), - }) - .rpc({ commitment: "confirmed" }); - console.log("Reveal queue sig is ", revealQueueSig); - - const revealFinalizeSig = await awaitComputationFinalization( - provider as anchor.AnchorProvider, - revealQueueSig, - program.programId, - "confirmed" - ); - console.log("Reveal finalize sig is ", revealFinalizeSig); + const voteEvent = await voteEventPromise; + console.log( + `Vote casted for poll ${POLL_ID} at timestamp `, + voteEvent.timestamp.toString() + ); + } - const revealEvent = await revealEventPromise; + // Reveal results for each poll + for (let i = 0; i < POLL_IDS.length; i++) { + const POLL_ID = POLL_IDS[i]; + const expectedOutcome = voteOutcomes[i]; + + const revealEventPromise = awaitEvent("revealResultEvent"); + + const revealQueueSig = await program.methods + .revealResult(POLL_ID) + .accountsPartial({ + clusterAccount: arciumEnv.arciumClusterPubkey, + mxeAccount: getMXEAccAcc(program.programId), + mempoolAccount: getMempoolAcc(program.programId), + executingPool: getExecutingPoolAcc(program.programId), + compDefAccount: getCompDefAcc( + program.programId, + Buffer.from(getCompDefAccOffset("reveal_result")).readUInt32LE() + ), + }) + .rpc({ commitment: "confirmed" }); + console.log(`Reveal queue for poll ${POLL_ID} sig is `, revealQueueSig); + + const revealFinalizeSig = await awaitComputationFinalization( + provider as anchor.AnchorProvider, + revealQueueSig, + program.programId, + "confirmed" + ); + console.log( + `Reveal finalize for poll ${POLL_ID} sig is `, + revealFinalizeSig + ); - console.log("Decrypted winner is ", revealEvent.output); - expect(revealEvent.output).to.be.true; + const revealEvent = await revealEventPromise; + console.log( + `Decrypted winner for poll ${POLL_ID} is `, + revealEvent.output + ); + expect(revealEvent.output).to.equal(expectedOutcome); + } }); async function initVoteStatsCompDef( @@ -225,7 +218,10 @@ describe("Voting", () => { getArciumProgAddress() )[0]; - console.log("Init vote stats computation definition pda is ", compDefPDA); + console.log( + "Init vote stats computation definition pda is ", + compDefPDA.toBase58() + ); const sig = await program.methods .initVoteStatsCompDef() @@ -283,7 +279,7 @@ describe("Voting", () => { getArciumProgAddress() )[0]; - console.log("Vote computation definition pda is ", compDefPDA); + console.log("Vote computation definition pda is ", compDefPDA.toBase58()); const sig = await program.methods .initVoteCompDef() @@ -341,7 +337,10 @@ describe("Voting", () => { getArciumProgAddress() )[0]; - console.log("Reveal result computation definition pda is ", compDefPDA); + console.log( + "Reveal result computation definition pda is ", + compDefPDA.toBase58() + ); const sig = await program.methods .initRevealResultCompDef() diff --git a/voting/yarn.lock b/voting/yarn.lock index 67457d08..278935cc 100644 --- a/voting/yarn.lock +++ b/voting/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@arcium-hq/arcium-sdk@0.1.40": - version "0.1.40" - resolved "https://npm.pkg.github.com/download/@arcium-hq/arcium-sdk/0.1.40/08aa0591823c292751a2b959e89374dac9e9a5eb#08aa0591823c292751a2b959e89374dac9e9a5eb" - integrity sha512-om1rUovX5dKEV87iigcw8oJ2guPPwJT+YPJdkEzDpil3vj5UGoATgn4XDWLv0vJ9IM9xOwl3TI9nTE3uGMrHzw== +"@arcium-hq/arcium-sdk@0.1.42": + version "0.1.42" + resolved "https://npm.pkg.github.com/download/@arcium-hq/arcium-sdk/0.1.42/d20346d06868301a9175c8abf3ea292a9190ced1#d20346d06868301a9175c8abf3ea292a9190ced1" + integrity sha512-pjTMKgH5j94XSVUduuCXeeo4VWrOJYbfClm4ESRXVGp/05U82smCXT6idYaparbEpivbnfCRIkdZfMalOSMIkw== dependencies: "@coral-xyz/anchor" "0.31" "@noble/curves" "^1.8.1" @@ -13,9 +13,9 @@ "@solana/web3.js" "^1.95.4" "@babel/runtime@^7.25.0": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.10.tgz#a07b4d8fa27af131a633d7b3524db803eb4764c2" - integrity sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw== + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762" + integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw== dependencies: regenerator-runtime "^0.14.0" @@ -128,11 +128,11 @@ integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== "@types/node@*": - version "22.13.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.11.tgz#f0ed6b302dcf0f4229d44ea707e77484ad46d234" - integrity sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g== + version "22.14.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.14.0.tgz#d3bfa3936fef0dbacd79ea3eb17d521c628bb47e" + integrity sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA== dependencies: - undici-types "~6.20.0" + undici-types "~6.21.0" "@types/node@^12.12.54": version "12.20.55" @@ -152,9 +152,9 @@ "@types/node" "*" "@types/ws@^8.2.2": - version "8.18.0" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" - integrity sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw== + version "8.18.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" + integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== dependencies: "@types/node" "*" @@ -1038,10 +1038,10 @@ typescript@^4.3.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== -undici-types@~6.20.0: - version "6.20.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" - integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== +undici-types@~6.21.0: + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" + integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== utf-8-validate@^5.0.2: version "5.0.10"