diff --git a/.cargo/config b/.cargo/config.toml similarity index 100% rename from .cargo/config rename to .cargo/config.toml diff --git a/.cargo/release-version b/.cargo/release-version index f08075098e..992977ad20 100644 --- a/.cargo/release-version +++ b/.cargo/release-version @@ -1 +1 @@ -v0.16.19 \ No newline at end of file +v1.1.0 \ No newline at end of file diff --git a/.circleci/config.yml b/.circleci/config.yml index e98a78be0e..4aad608529 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,5 +1,22 @@ version: 2.1 +parameters: + small: + type: string + default: small + medium: + type: string + default: medium + large: + type: string + default: large + xlarge: + type: string + default: xlarge + twoxlarge: + type: string + default: aleonet/2xlarge + orbs: windows: circleci/windows@5.0 @@ -43,23 +60,22 @@ commands: parameters: cache_key: type: string - default: snarkvm-stable-cache + default: v1.0.0-rust-1.81.0-snarkvm-stable-cache steps: - run: set -e - - setup_remote_docker - run: name: Prepare environment and install dependencies command: | - export SCCACHE_CACHE_SIZE=200M + echo 'export "RUSTC_WRAPPER"="sccache"' >> $BASH_ENV + echo 'export "SCCACHE_CACHE_SIZE"="200M"' >> $BASH_ENV export WORK_DIR="$CIRCLE_WORKING_DIRECTORY/.cache/sccache" export SCCACHE_DIR="$CIRCLE_WORKING_DIRECTORY/.cache/sccache" mkdir -p "$CIRCLE_WORKING_DIRECTORY/.bin" wget https://github.com/mozilla/sccache/releases/download/v0.3.0/sccache-v0.3.0-x86_64-unknown-linux-musl.tar.gz tar -C "$CIRCLE_WORKING_DIRECTORY/.bin" -xvf sccache-v0.3.0-x86_64-unknown-linux-musl.tar.gz - mv $CIRCLE_WORKING_DIRECTORY/.bin/sccache-v0.3.0-x86_64-unknown-linux-musl/sccache $CIRCLE_WORKING_DIRECTORY/.bin/sccache - export PATH="$PATH:$CIRCLE_WORKING_DIRECTORY/.bin" - export RUSTC_WRAPPER="sccache" - rm -rf "$CIRCLE_WORKING_DIRECTORY/.cargo/registry" + chmod +x $CIRCLE_WORKING_DIRECTORY/.bin/sccache-v0.3.0-x86_64-unknown-linux-musl/sccache + mv $CIRCLE_WORKING_DIRECTORY/.bin/sccache-v0.3.0-x86_64-unknown-linux-musl/sccache /home/circleci/bin/sccache + rm -rf "/home/circleci/.cargo/registry" DEBIAN_FRONTEND=noninteractive sudo apt-get update DEBIAN_FRONTEND=noninteractive sudo apt-get dist-upgrade -y -o DPkg::Options::=--force-confold DEBIAN_FRONTEND=noninteractive sudo apt-get install -y --no-install-recommends clang llvm-dev llvm pkg-config xz-utils make libssl-dev libssl-dev @@ -72,15 +88,16 @@ commands: parameters: cache_key: type: string - default: snarkvm-stable-cache + default: v1.0.0-rust-1.81.0-snarkvm-stable-cache steps: - - run: (sccache -s||true) + - run: (sccache -s || true) - run: set +e - save_cache: key: << parameters.cache_key >> paths: - - .cache/sccache - - .cargo + - /home/circleci/.cache/sccache + - /home/circleci/.cargo + - /home/circleci/.aleo/resources run_serial: description: "Build and run tests" @@ -137,8 +154,8 @@ commands: jobs: snarkvm: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.large >> steps: - checkout - run: @@ -147,646 +164,707 @@ jobs: algorithms: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.large >> steps: - run_serial: workspace_member: algorithms - cache_key: snarkvm-algorithms-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-algorithms-cache algorithms-profiler: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - run_serial: # This runs a single test with profiler enabled workspace_member: algorithms - cache_key: snarkvm-algorithms-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-algorithms-cache flags: varuna::prove_and_verify_with_square_matrix --features profiler circuit: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: circuit - cache_key: snarkvm-circuit-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-cache circuit-account: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: circuit/account - cache_key: snarkvm-circuit-account-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-account-cache # This checks that no `console` structs are used in core circuit logic. circuit-account-noconsole: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: circuit/account flags: --no-default-features - cache_key: snarkvm-circuit-account-noconsole-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-account-noconsole-cache circuit-algorithms: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - run_serial: workspace_member: circuit/algorithms - cache_key: snarkvm-circuit-algorithms-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-algorithms-cache circuit-collections: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: workspace_member: circuit/collections - cache_key: snarkvm-circuit-collections-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-collections-cache # This checks that no `console` structs are used in core circuit logic. circuit-collections-noconsole: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: workspace_member: circuit/collections flags: --no-default-features - cache_key: snarkvm-circuit-collections-noconsole-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-collections-noconsole-cache circuit-environment: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: circuit/environment - cache_key: snarkvm-circuit-environment-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-environment-cache circuit-network: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: circuit/network - cache_key: snarkvm-circuit-network-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-network-cache circuit-program: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - run_serial: workspace_member: circuit/program - cache_key: snarkvm-circuit-program-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-program-cache circuit-types: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: circuit/types - cache_key: snarkvm-circuit-types-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-types-cache circuit-types-address: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: circuit/types/address - cache_key: snarkvm-circuit-types-address-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-types-address-cache circuit-types-boolean: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: circuit/types/boolean - cache_key: snarkvm-circuit-types-boolean-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-types-boolean-cache circuit-types-field: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: circuit/types/field - cache_key: snarkvm-circuit-types-field-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-types-field-cache circuit-types-group: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: circuit/types/group - cache_key: snarkvm-circuit-types-group-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-types-group-cache circuit-types-integers: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: workspace_member: circuit/types/integers - cache_key: snarkvm-circuit-types-integers-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-types-integers-cache flags: -- --ignored circuit-types-scalar: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: circuit/types/scalar - cache_key: snarkvm-circuit-types-scalar-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-types-scalar-cache circuit-types-string: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: circuit/types/string - cache_key: snarkvm-circuit-types-string-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-circuit-types-string-cache console: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console - cache_key: snarkvm-console-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-cache console-account: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - run_serial: workspace_member: console/account - cache_key: snarkvm-console-account-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-account-cache console-algorithms: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console/algorithms - cache_key: snarkvm-console-algorithms-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-algorithms-cache console-collections: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: workspace_member: console/collections - cache_key: snarkvm-console-collections-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-collections-cache console-network: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console/network - cache_key: snarkvm-console-network-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-network-cache console-network-environment: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console/network/environment - cache_key: snarkvm-console-network-environment-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-network-environment-cache console-program: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console/program - cache_key: snarkvm-console-program-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-program-cache console-types: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console/types - cache_key: snarkvm-console-types-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-types-cache console-types-address: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console/types/address - cache_key: snarkvm-console-types-address-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-types-address-cache console-types-boolean: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console/types/boolean - cache_key: snarkvm-console-types-boolean-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-types-boolean-cache console-types-field: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console/types/field - cache_key: snarkvm-console-types-field-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-types-field-cache console-types-group: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console/types/group - cache_key: snarkvm-console-types-group-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-types-group-cache console-types-integers: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console/types/integers - cache_key: snarkvm-console-types-integers-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-types-integers-cache console-types-scalar: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console/types/scalar - cache_key: snarkvm-console-types-scalar-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-types-scalar-cache console-types-string: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: console/types/string - cache_key: snarkvm-console-types-string-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-console-types-string-cache curves: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: curves - cache_key: snarkvm-curves-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-curves-cache fields: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: fields - cache_key: snarkvm-fields-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-fields-cache ledger: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: workspace_member: ledger - cache_key: snarkvm-ledger-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-cache ledger-with-rocksdb: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - run_serial: flags: --features=rocks workspace_member: ledger - cache_key: snarkvm-ledger-with-rocksdb-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-with-rocksdb-cache - ledger-authority: + ledger-with-valid-solutions: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: - workspace_member: ledger/authority - cache_key: snarkvm-ledger-authority-cache + flags: valid_solutions --features=test + workspace_member: ledger + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-with-valid-solutions-cache - ledger-block: + ledger-authority: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: - workspace_member: ledger/block - cache_key: snarkvm-ledger-block-cache + workspace_member: ledger/authority + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-authority-cache - ledger-coinbase: + ledger-block: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.twoxlarge >> steps: - run_serial: - workspace_member: ledger/coinbase - cache_key: snarkvm-ledger-coinbase-cache + workspace_member: ledger/block + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-block-cache ledger-committee: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - run_serial: workspace_member: ledger/committee - cache_key: snarkvm-ledger-committee-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-committee-cache ledger-narwhal: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: ledger/narwhal - cache_key: snarkvm-ledger-narwhal-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-narwhal-cache ledger-narwhal-batch-certificate: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - run_serial: workspace_member: ledger/narwhal/batch-certificate - cache_key: snarkvm-ledger-narwhal-batch-certificate-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-narwhal-batch-certificate-cache ledger-narwhal-batch-header: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: ledger/narwhal/batch-header - cache_key: snarkvm-ledger-narwhal-batch-header-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-narwhal-batch-header-cache ledger-narwhal-data: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: ledger/narwhal/data - cache_key: snarkvm-ledger-narwhal-data-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-narwhal-data-cache ledger-narwhal-subdag: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - run_serial: workspace_member: ledger/narwhal/subdag - cache_key: snarkvm-ledger-narwhal-subdag-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-narwhal-subdag-cache ledger-narwhal-transmission: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - run_serial: workspace_member: ledger/narwhal/transmission - cache_key: snarkvm-ledger-narwhal-transmission-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-narwhal-transmission-cache ledger-narwhal-transmission-id: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - run_serial: workspace_member: ledger/narwhal/transmission-id - cache_key: snarkvm-ledger-narwhal-transmission-id-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-narwhal-transmission-id-cache + + ledger-puzzle: + docker: + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> + steps: + - run_serial: + workspace_member: ledger/puzzle + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-puzzle-cache + + ledger-puzzle-epoch: + docker: + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> + steps: + - run_serial: + workspace_member: ledger/puzzle/epoch + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-puzzle-epoch-cache ledger-query: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: ledger/query - cache_key: snarkvm-ledger-query-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-query-cache ledger-store: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.twoxlarge >> steps: - run_serial: flags: --features=rocks workspace_member: ledger/store - cache_key: snarkvm-ledger-store-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-store-cache ledger-test-helpers: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - run_serial: workspace_member: ledger/test-helpers - cache_key: snarkvm-ledger-test-helpers-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-ledger-test-helpers-cache parameters: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.twoxlarge >> steps: - run_serial: + flags: -- --test-threads=2 workspace_member: parameters - cache_key: snarkvm-parameters-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-parameters-cache + + parameters-uncached: + docker: + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.large >> + steps: + - run_serial: + flags: -- --test-threads=2 --ignored test_load_bytes_mini + workspace_member: parameters + cache_key: v-{{ epoch }}-snarkvm-parameters-cache synthesizer: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.twoxlarge >> steps: - run_serial: - flags: --lib --bins + flags: --lib --bins -- --test-threads=2 workspace_member: synthesizer - cache_key: snarkvm-synthesizer-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-cache synthesizer-integration: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.twoxlarge >> steps: - run_serial: - flags: --test '*' + flags: --test '*' -- --test-threads=8 workspace_member: synthesizer - cache_key: snarkvm-synthesizer-integration-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-integration-cache synthesizer-process: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: + flags: -- --test-threads=8 workspace_member: synthesizer/process - cache_key: snarkvm-synthesizer-process-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-process-cache synthesizer-process-with-rocksdb: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: flags: --features=rocks workspace_member: synthesizer/process - cache_key: snarkvm-synthesizer-process-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-process-cache synthesizer-program: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: flags: --lib --bins workspace_member: synthesizer/program - cache_key: snarkvm-synthesizer-program-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-program-cache synthesizer-program-integration: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.twoxlarge >> steps: - run_serial: - flags: --test '*' -- --skip keccak --skip psd --skip sha + flags: --test '*' -- --skip keccak --skip psd --skip sha --skip instruction::is --skip instruction::equal --skip instruction::commit workspace_member: synthesizer/program - cache_key: snarkvm-synthesizer-program-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-program-integration-cache synthesizer-program-integration-keccak: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: flags: keccak --test '*' workspace_member: synthesizer/program - cache_key: snarkvm-synthesizer-program-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-program-keccak-cache synthesizer-program-integration-psd: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: flags: psd --test '*' workspace_member: synthesizer/program - cache_key: snarkvm-synthesizer-program-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-program-psd-cache synthesizer-program-integration-sha: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: flags: sha --test '*' workspace_member: synthesizer/program - cache_key: snarkvm-synthesizer-program-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-program-sha-cache + + synthesizer-program-integration-instruction-is: + docker: + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.twoxlarge >> + steps: + - run_serial: + flags: instruction::is --test '*' + workspace_member: synthesizer/program + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-program-is-cache + + synthesizer-program-integration-instruction-equal: + docker: + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> + steps: + - run_serial: + flags: instruction::equal --test '*' + workspace_member: synthesizer/program + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-program-equal-cache + + synthesizer-program-integration-instruction-commit: + docker: + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> + steps: + - run_serial: + flags: instruction::commit --test '*' + workspace_member: synthesizer/program + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-program-commit-cache synthesizer-snark: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: synthesizer/snark - cache_key: snarkvm-synthesizer-snark-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-synthesizer-snark-cache utilities: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.large >> steps: - run_serial: workspace_member: utilities - cache_key: snarkvm-utilities-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-utilities-cache utilities-derives: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - run_serial: workspace_member: utilities/derives - cache_key: snarkvm-utilities-derives-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-utilities-derives-cache wasm: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - checkout - setup_environment: - cache_key: snarkvm-wasm-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-wasm-cache - run: no_output_timeout: 30m command: | sudo apt-get install nodejs - curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + (cargo install wasm-pack || true) cd wasm && wasm-pack test --node # cargo test --target wasm32-unknown-unknown - clear_environment: - cache_key: snarkvm-wasm-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-wasm-cache check-fmt: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.medium >> steps: - checkout - install_rust_nightly - setup_environment: - cache_key: snarkvm-fmt-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-fmt-cache - run: name: Check style no_output_timeout: 35m command: cargo +nightly fmt --all -- --check - clear_environment: - cache_key: snarkvm-fmt-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-fmt-cache check-clippy: docker: - - image: cimg/rust:1.72.1 - resource_class: 2xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.xlarge >> steps: - checkout - setup_environment: - cache_key: snarkvm-clippy-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-clippy-cache - run: name: Check Clippy no_output_timeout: 35m @@ -794,27 +872,27 @@ jobs: cargo clippy --workspace --all-targets -- -D warnings cargo clippy --workspace --all-targets --all-features -- -D warnings - clear_environment: - cache_key: snarkvm-clippy-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-clippy-cache check-all-targets: docker: - - image: cimg/rust:1.72.1 - resource_class: xlarge + - image: cimg/rust:1.81.0 # Attention - Change the MSRV in Cargo.toml and rust-toolchain as well + resource_class: << pipeline.parameters.small >> steps: - checkout - setup_environment: - cache_key: snarkvm-all-targets-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-all-targets-cache - run: name: Check all targets no_output_timeout: 35m command: cargo check --release --workspace --all-targets - clear_environment: - cache_key: snarkvm-all-targets-cache + cache_key: v1.0.0-rust-1.81.0-snarkvm-all-targets-cache verify-windows: executor: name: windows/default - size: 2xlarge + size: xlarge environment: CARGO_NET_GIT_FETCH_WITH_CLI: "true" parameters: @@ -869,9 +947,9 @@ workflows: - ledger # TODO (howardwu) - Implement `open_testing` on all storage, update to `CurrentConsensusStore::open_testing`, then re-enable. # - ledger-with-rocksdb + - ledger-with-valid-solutions - ledger-authority - ledger-block - - ledger-coinbase - ledger-committee - ledger-narwhal - ledger-narwhal-batch-certificate @@ -880,10 +958,13 @@ workflows: - ledger-narwhal-subdag - ledger-narwhal-transmission - ledger-narwhal-transmission-id + - ledger-puzzle + - ledger-puzzle-epoch - ledger-query - ledger-store - ledger-test-helpers - parameters + - parameters-uncached - synthesizer - synthesizer-integration - synthesizer-process @@ -893,6 +974,9 @@ workflows: - synthesizer-program-integration-keccak - synthesizer-program-integration-psd - synthesizer-program-integration-sha + - synthesizer-program-integration-instruction-is + - synthesizer-program-integration-instruction-equal + - synthesizer-program-integration-instruction-commit - synthesizer-snark - utilities - utilities-derives diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 340bea64fd..03e5b9555b 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,3 +1,3 @@ -## 👉 [Please follow one of these issue templates](https://github.com/AleoHQ/snarkVM/issues/new/choose) 👈 +## 👉 [Please follow one of these issue templates](https://github.com/AleoNet/snarkVM/issues/new/choose) 👈 Note: to keep the backlog clean and actionable, issues may be immediately closed if they do not follow one of the above issue templates. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6a38950155..142af6df75 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -17,7 +17,7 @@ diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 32054890db..51dfc816f5 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -3,7 +3,7 @@ name: Run snarkVM Benchmarks on: push: branches: - - 'testnet3' + - 'mainnet' jobs: # Run benchmarks and stores the output to a file @@ -81,10 +81,10 @@ jobs: cargo bench --bench transaction -- --output-format bencher | tee -a ../output.txt cd .. - - name: Benchmark ledger/coinbase + - name: Benchmark ledger/puzzle run: | - cd ledger/coinbase - cargo bench --bench coinbase_puzzle --features "setup" -- --output-format bencher | tee -a ../../output.txt + cd ledger/puzzle + cargo bench --bench puzzle --features "setup" -- --output-format bencher | tee -a ../../output.txt cd ../.. # Clean benchmark output to remove unnecessary lines diff --git a/.license_header b/.license_header index 2f0c61d37c..137acd8f31 100644 --- a/.license_header +++ b/.license_header @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/.rustfmt.toml b/.rustfmt.toml index 30b32606ff..b5dd5e6730 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -13,4 +13,4 @@ imports_layout = "HorizontalVertical" imports_granularity = "Crate" overflow_delimited_expr = true reorder_impl_items = true -version = "Two" +style_edition = "2024" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b0233c6c71..ee6d42c75c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,8 +6,8 @@ Thank you for your interest in contributing to snarkVM! Below you can find some Please follow the instructions below when filing a pull request: -- ensure that your branch is forked from the current [master](https://github.com/AleoHQ/snarkVM/tree/master) branch -- run `cargo fmt` before you commit; we use the `nightly` version of `rustfmt` to format the code, so you'll need to have the `nightly` toolchain installed on your machine; there's a [git hook](https://git-scm.com/docs/githooks) that ensures proper formatting before any commits can be made, and [`.rustfmt.toml`](https://github.com/AleoHQ/snarkVM/blob/master/.rustfmt.toml) specifies some of the formatting conventions +- ensure that your branch is forked from the current [master](https://github.com/AleoNet/snarkVM/tree/master) branch +- run `cargo fmt` before you commit; we use the `nightly` version of `rustfmt` to format the code, so you'll need to have the `nightly` toolchain installed on your machine; there's a [git hook](https://git-scm.com/docs/githooks) that ensures proper formatting before any commits can be made, and [`.rustfmt.toml`](https://github.com/AleoNet/snarkVM/blob/master/.rustfmt.toml) specifies some of the formatting conventions - run `cargo clippy --all-targets --all-features` to ensure that popular correctness and performance pitfalls are avoided ## Coding conventions diff --git a/Cargo.lock b/Cargo.lock index ab744cc8a4..451bc28458 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -857,6 +857,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum-iterator" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c280b9e6b3ae19e152d8e31cf47f18389781e119d4013a2a2bb0180e5facc635" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" +dependencies = [ + "proc-macro2", + "quote 1.0.35", + "syn 2.0.48", +] + [[package]] name = "enum_index" version = "0.2.0" @@ -1124,7 +1144,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.1.0", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -1282,9 +1302,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -1896,9 +1916,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -2068,13 +2088,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", + "regex-automata 0.4.4", "regex-syntax 0.8.2", ] @@ -2089,9 +2109,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" dependencies = [ "aho-corasick", "memchr", @@ -2413,11 +2433,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.6", "itoa", "ryu", "serde", @@ -2441,7 +2461,7 @@ version = "0.9.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1bf28c79a99f70ee1f1d83d10c875d2e70618417fda01ad1785e027579d9d38" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.6", "itoa", "ryu", "serde", @@ -2531,7 +2551,7 @@ dependencies = [ [[package]] name = "snarkvm" -version = "0.16.19" +version = "1.1.0" dependencies = [ "anstyle", "anyhow", @@ -2539,7 +2559,7 @@ dependencies = [ "clap", "colored", "dotenvy", - "indexmap 2.1.0", + "indexmap 2.2.6", "num-format", "once_cell", "parking_lot", @@ -2567,7 +2587,7 @@ dependencies = [ [[package]] name = "snarkvm-algorithms" -version = "0.16.19" +version = "1.1.0" dependencies = [ "aleo-std", "anyhow", @@ -2580,7 +2600,7 @@ dependencies = [ "fxhash", "hashbrown 0.14.3", "hex", - "indexmap 2.1.0", + "indexmap 2.2.6", "itertools 0.11.0", "lazy_static", "num-traits", @@ -2606,7 +2626,7 @@ dependencies = [ [[package]] name = "snarkvm-algorithms-cuda" -version = "0.16.19" +version = "1.1.0" dependencies = [ "blst", "cc", @@ -2616,7 +2636,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit" -version = "0.16.19" +version = "1.1.0" dependencies = [ "snarkvm-circuit-account", "snarkvm-circuit-algorithms", @@ -2629,7 +2649,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-account" -version = "0.16.19" +version = "1.1.0" dependencies = [ "anyhow", "snarkvm-circuit-algorithms", @@ -2641,7 +2661,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-algorithms" -version = "0.16.19" +version = "1.1.0" dependencies = [ "anyhow", "snarkvm-circuit-types", @@ -2653,7 +2673,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-collections" -version = "0.16.19" +version = "1.1.0" dependencies = [ "anyhow", "snarkvm-circuit-algorithms", @@ -2667,10 +2687,10 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment" -version = "0.16.19" +version = "1.1.0" dependencies = [ "criterion", - "indexmap 2.1.0", + "indexmap 2.2.6", "itertools 0.11.0", "nom", "num-traits", @@ -2688,11 +2708,11 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment-witness" -version = "0.16.19" +version = "1.1.0" [[package]] name = "snarkvm-circuit-network" -version = "0.16.19" +version = "1.1.0" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-collections", @@ -2703,7 +2723,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-program" -version = "0.16.19" +version = "1.1.0" dependencies = [ "anyhow", "paste", @@ -2721,7 +2741,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types" -version = "0.16.19" +version = "1.1.0" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-address", @@ -2736,7 +2756,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-address" -version = "0.16.19" +version = "1.1.0" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -2748,7 +2768,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-boolean" -version = "0.16.19" +version = "1.1.0" dependencies = [ "criterion", "snarkvm-circuit-environment", @@ -2757,7 +2777,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-field" -version = "0.16.19" +version = "1.1.0" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -2766,7 +2786,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-group" -version = "0.16.19" +version = "1.1.0" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -2778,7 +2798,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-integers" -version = "0.16.19" +version = "1.1.0" dependencies = [ "paste", "snarkvm-circuit-environment", @@ -2791,7 +2811,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-scalar" -version = "0.16.19" +version = "1.1.0" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -2801,7 +2821,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-string" -version = "0.16.19" +version = "1.1.0" dependencies = [ "rand", "snarkvm-circuit-environment", @@ -2814,7 +2834,7 @@ dependencies = [ [[package]] name = "snarkvm-console" -version = "0.16.19" +version = "1.1.0" dependencies = [ "snarkvm-console-account", "snarkvm-console-algorithms", @@ -2826,7 +2846,7 @@ dependencies = [ [[package]] name = "snarkvm-console-account" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "bs58", @@ -2839,7 +2859,7 @@ dependencies = [ [[package]] name = "snarkvm-console-algorithms" -version = "0.16.19" +version = "1.1.0" dependencies = [ "blake2s_simd", "criterion", @@ -2857,11 +2877,11 @@ dependencies = [ [[package]] name = "snarkvm-console-collections" -version = "0.16.19" +version = "1.1.0" dependencies = [ "aleo-std", "criterion", - "indexmap 2.1.0", + "indexmap 2.2.6", "rayon", "snarkvm-console-algorithms", "snarkvm-console-network", @@ -2870,10 +2890,10 @@ dependencies = [ [[package]] name = "snarkvm-console-network" -version = "0.16.19" +version = "1.1.0" dependencies = [ "anyhow", - "indexmap 2.1.0", + "indexmap 2.2.6", "itertools 0.11.0", "lazy_static", "once_cell", @@ -2892,7 +2912,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network-environment" -version = "0.16.19" +version = "1.1.0" dependencies = [ "anyhow", "bech32", @@ -2909,12 +2929,13 @@ dependencies = [ [[package]] name = "snarkvm-console-program" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", + "enum-iterator", "enum_index", "enum_index_derive", - "indexmap 2.1.0", + "indexmap 2.2.6", "num-derive", "num-traits", "once_cell", @@ -2930,7 +2951,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types" -version = "0.16.19" +version = "1.1.0" dependencies = [ "criterion", "snarkvm-console-network", @@ -2946,7 +2967,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-address" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "serde_json", @@ -2958,7 +2979,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-boolean" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "serde_json", @@ -2967,7 +2988,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-field" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "serde_json", @@ -2978,7 +2999,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-group" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "serde_json", @@ -2990,7 +3011,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-integers" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "serde_json", @@ -3002,7 +3023,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-scalar" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "serde_json", @@ -3014,7 +3035,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-string" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "serde_json", @@ -3026,7 +3047,7 @@ dependencies = [ [[package]] name = "snarkvm-curves" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "criterion", @@ -3041,7 +3062,7 @@ dependencies = [ [[package]] name = "snarkvm-fields" -version = "0.16.19" +version = "1.1.0" dependencies = [ "aleo-std", "anyhow", @@ -3059,34 +3080,36 @@ dependencies = [ [[package]] name = "snarkvm-ledger" -version = "0.16.19" +version = "1.1.0" dependencies = [ "aleo-std", "anyhow", "bincode", "criterion", - "indexmap 2.1.0", + "indexmap 2.2.6", "parking_lot", "rand", "rayon", "serde_json", + "snarkvm-circuit", "snarkvm-console", "snarkvm-ledger-authority", "snarkvm-ledger-block", - "snarkvm-ledger-coinbase", "snarkvm-ledger-committee", "snarkvm-ledger-narwhal", + "snarkvm-ledger-puzzle", "snarkvm-ledger-query", "snarkvm-ledger-store", "snarkvm-ledger-test-helpers", "snarkvm-synthesizer", + "snarkvm-utilities", "time", "tracing", ] [[package]] name = "snarkvm-ledger-authority" -version = "0.16.19" +version = "1.1.0" dependencies = [ "anyhow", "bincode", @@ -3099,21 +3122,22 @@ dependencies = [ [[package]] name = "snarkvm-ledger-block" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", - "indexmap 2.1.0", + "indexmap 2.2.6", "once_cell", "rayon", "serde_json", "snarkvm-circuit", "snarkvm-console", "snarkvm-ledger-authority", - "snarkvm-ledger-coinbase", "snarkvm-ledger-committee", "snarkvm-ledger-narwhal-batch-header", + "snarkvm-ledger-narwhal-data", "snarkvm-ledger-narwhal-subdag", "snarkvm-ledger-narwhal-transmission-id", + "snarkvm-ledger-puzzle", "snarkvm-ledger-query", "snarkvm-ledger-store", "snarkvm-synthesizer-process", @@ -3121,34 +3145,13 @@ dependencies = [ "snarkvm-synthesizer-snark", ] -[[package]] -name = "snarkvm-ledger-coinbase" -version = "0.16.19" -dependencies = [ - "aleo-std", - "anyhow", - "bincode", - "blake2", - "criterion", - "indexmap 2.1.0", - "rand", - "rayon", - "serde_json", - "snarkvm-algorithms", - "snarkvm-console", - "snarkvm-curves", - "snarkvm-fields", - "snarkvm-synthesizer-snark", - "snarkvm-utilities", -] - [[package]] name = "snarkvm-ledger-committee" -version = "0.16.19" +version = "1.1.0" dependencies = [ "anyhow", "bincode", - "indexmap 2.1.0", + "indexmap 2.2.6", "parking_lot", "proptest", "rand", @@ -3165,7 +3168,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal" -version = "0.16.19" +version = "1.1.0" dependencies = [ "snarkvm-ledger-narwhal", "snarkvm-ledger-narwhal-batch-certificate", @@ -3178,10 +3181,10 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-certificate" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", - "indexmap 2.1.0", + "indexmap 2.2.6", "rayon", "serde_json", "snarkvm-console", @@ -3192,10 +3195,11 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-header" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", - "indexmap 2.1.0", + "indexmap 2.2.6", + "rayon", "serde_json", "snarkvm-console", "snarkvm-ledger-narwhal-batch-header", @@ -3205,23 +3209,26 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-data" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bytes", "serde_json", "snarkvm-console", + "snarkvm-ledger-block", + "snarkvm-ledger-test-helpers", "tokio", ] [[package]] name = "snarkvm-ledger-narwhal-subdag" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", - "indexmap 2.1.0", + "indexmap 2.2.6", "rayon", "serde_json", "snarkvm-console", + "snarkvm-ledger-committee", "snarkvm-ledger-narwhal-batch-certificate", "snarkvm-ledger-narwhal-batch-header", "snarkvm-ledger-narwhal-subdag", @@ -3230,30 +3237,71 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "bytes", "serde_json", "snarkvm-console", "snarkvm-ledger-block", - "snarkvm-ledger-coinbase", "snarkvm-ledger-narwhal-data", + "snarkvm-ledger-puzzle", ] [[package]] name = "snarkvm-ledger-narwhal-transmission-id" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "serde_json", "snarkvm-console", - "snarkvm-ledger-coinbase", + "snarkvm-ledger-puzzle", +] + +[[package]] +name = "snarkvm-ledger-puzzle" +version = "1.1.0" +dependencies = [ + "aleo-std", + "anyhow", + "bincode", + "criterion", + "indexmap 2.2.6", + "lru", + "once_cell", + "parking_lot", + "rand", + "rand_chacha", + "rayon", + "serde_json", + "snarkvm-algorithms", + "snarkvm-console", + "snarkvm-ledger-puzzle-epoch", +] + +[[package]] +name = "snarkvm-ledger-puzzle-epoch" +version = "1.1.0" +dependencies = [ + "aleo-std", + "anyhow", + "colored", + "indexmap 2.2.6", + "lru", + "parking_lot", + "rand", + "rand_chacha", + "rayon", + "snarkvm-circuit", + "snarkvm-console", + "snarkvm-ledger-puzzle", + "snarkvm-synthesizer-process", + "snarkvm-synthesizer-program", ] [[package]] name = "snarkvm-ledger-query" -version = "0.16.19" +version = "1.1.0" dependencies = [ "async-trait", "reqwest", @@ -3265,24 +3313,26 @@ dependencies = [ [[package]] name = "snarkvm-ledger-store" -version = "0.16.19" +version = "1.1.0" dependencies = [ "aleo-std-storage", "anyhow", "bincode", - "indexmap 2.1.0", + "indexmap 2.2.6", "once_cell", "parking_lot", "rayon", "rocksdb", "serde", + "serde_json", "serial_test", + "smallvec", "snarkvm-console", "snarkvm-ledger-authority", "snarkvm-ledger-block", - "snarkvm-ledger-coinbase", "snarkvm-ledger-committee", "snarkvm-ledger-narwhal-batch-certificate", + "snarkvm-ledger-puzzle", "snarkvm-ledger-test-helpers", "snarkvm-synthesizer-program", "snarkvm-synthesizer-snark", @@ -3293,7 +3343,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-test-helpers" -version = "0.16.19" +version = "1.1.0" dependencies = [ "once_cell", "snarkvm-circuit", @@ -3307,7 +3357,7 @@ dependencies = [ [[package]] name = "snarkvm-metrics" -version = "0.16.19" +version = "1.1.0" dependencies = [ "metrics", "metrics-exporter-prometheus", @@ -3315,7 +3365,7 @@ dependencies = [ [[package]] name = "snarkvm-parameters" -version = "0.16.19" +version = "1.1.0" dependencies = [ "aleo-std", "anyhow", @@ -3325,7 +3375,7 @@ dependencies = [ "curl", "encoding", "hex", - "indexmap 2.1.0", + "indexmap 2.2.6", "itertools 0.11.0", "js-sys", "lazy_static", @@ -3338,6 +3388,7 @@ dependencies = [ "snarkvm-circuit", "snarkvm-console", "snarkvm-curves", + "snarkvm-ledger-block", "snarkvm-ledger-store", "snarkvm-synthesizer", "snarkvm-utilities", @@ -3348,47 +3399,56 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer" -version = "0.16.19" +version = "1.1.0" dependencies = [ "aleo-std", "anyhow", + "bincode", "criterion", - "indexmap 2.1.0", + "indexmap 2.2.6", "itertools 0.11.0", "lru", "once_cell", "parking_lot", "rand", "rayon", + "serde", "serde_json", "serde_yaml", "snarkvm-algorithms", "snarkvm-circuit", "snarkvm-console", "snarkvm-ledger-block", - "snarkvm-ledger-coinbase", "snarkvm-ledger-committee", + "snarkvm-ledger-narwhal-batch-header", + "snarkvm-ledger-narwhal-data", + "snarkvm-ledger-puzzle", + "snarkvm-ledger-puzzle-epoch", "snarkvm-ledger-query", "snarkvm-ledger-store", "snarkvm-ledger-test-helpers", "snarkvm-synthesizer-process", "snarkvm-synthesizer-program", "snarkvm-synthesizer-snark", + "snarkvm-utilities", + "tempfile", "tracing", "walkdir", ] [[package]] name = "snarkvm-synthesizer-process" -version = "0.16.19" +version = "1.1.0" dependencies = [ "aleo-std", "bincode", "colored", - "indexmap 2.1.0", + "criterion", + "indexmap 2.2.6", "once_cell", "parking_lot", "rand", + "rand_chacha", "rayon", "serde_json", "snarkvm-circuit", @@ -3406,11 +3466,11 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-program" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "criterion", - "indexmap 2.1.0", + "indexmap 2.2.6", "paste", "rand", "rand_chacha", @@ -3422,7 +3482,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-snark" -version = "0.16.19" +version = "1.1.0" dependencies = [ "bincode", "colored", @@ -3435,7 +3495,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities" -version = "0.16.19" +version = "1.1.0" dependencies = [ "aleo-std", "anyhow", @@ -3455,7 +3515,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities-derives" -version = "0.16.19" +version = "1.1.0" dependencies = [ "proc-macro2", "quote 1.0.35", @@ -3464,7 +3524,7 @@ dependencies = [ [[package]] name = "snarkvm-wasm" -version = "0.16.19" +version = "1.1.0" dependencies = [ "getrandom", "snarkvm-circuit-network", @@ -4101,9 +4161,9 @@ checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wasm-bindgen-test" -version = "0.3.40" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139bd73305d50e1c1c4333210c0db43d989395b64a237bd35c10ef3832a7f70c" +checksum = "6e6e302a7ea94f83a6d09e78e7dc7d9ca7b186bc2829c24a22d0753efd680671" dependencies = [ "console_error_panic_hook", "js-sys", @@ -4115,13 +4175,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.40" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70072aebfe5da66d2716002c729a14e4aec4da0e23cc2ea66323dac541c93928" +checksum = "ecb993dd8c836930ed130e020e77d9b2e65dd0fbab1b67c790b0f5d80b11a575" dependencies = [ "proc-macro2", "quote 1.0.35", - "syn 2.0.48", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index adf37e8061..d722810219 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -22,7 +22,7 @@ categories = [ include = [ "Cargo.toml", "vm", "README.md", "LICENSE.md" ] license = "Apache-2.0" edition = "2021" -rust-version = "1.72.1" +rust-version = "1.81.0" # Attention - Change the MSRV in rust-toolchain and in .circleci/config.yml as well [workspace] members = [ @@ -64,7 +64,6 @@ members = [ "ledger", "ledger/authority", "ledger/block", - "ledger/coinbase", "ledger/committee", "ledger/narwhal", "ledger/narwhal/batch-certificate", @@ -73,6 +72,8 @@ members = [ "ledger/narwhal/subdag", "ledger/narwhal/transmission", "ledger/narwhal/transmission-id", + "ledger/puzzle", + "ledger/puzzle/epoch", "ledger/query", "ledger/store", "ledger/test-helpers", @@ -130,6 +131,7 @@ cli = [ aleo-cli = [ "snarkvm-synthesizer/aleo-cli" ] async = [ "snarkvm-ledger/async", "snarkvm-synthesizer/async" ] cuda = [ "snarkvm-algorithms/cuda" ] +history = [ "snarkvm-synthesizer/history" ] parameters_no_std_out = [ "snarkvm-parameters/no_std_out" ] noconfig = [ ] rocks = [ "snarkvm-ledger/rocks", "snarkvm-synthesizer/rocks" ] @@ -147,61 +149,62 @@ parameters = [ "snarkvm-parameters" ] synthesizer = [ "snarkvm-synthesizer" ] utilities = [ "snarkvm-utilities" ] wasm = [ "snarkvm-wasm" ] +test_targets = [ "snarkvm-console/test_targets" ] [dependencies.snarkvm-algorithms] path = "./algorithms" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit] path = "./circuit" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-console] path = "./console" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-curves] path = "./curves" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-fields] path = "./fields" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-ledger] path = "./ledger" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-metrics] path = "./metrics" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-parameters] path = "./parameters" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-synthesizer] path = "./synthesizer" -version = "=0.16.19" +version = "=1.1.0" default-features = false optional = true [dependencies.snarkvm-utilities] path = "./utilities" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-wasm] path = "./wasm" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.anstyle] diff --git a/README.md b/README.md index 81bf265b44..f52c3d7d7d 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@

- snarkVM + snarkVM

- - + + - +

## Table of Contents @@ -34,7 +34,7 @@ | snarkvm-utilities | ![crates.io](https://img.shields.io/crates/v/snarkvm-utilities.svg?color=neon) | :white_check_mark: | :white_check_mark: | | snarkvm-wasm | ![crates.io](https://img.shields.io/crates/v/snarkvm-wasm.svg?color=neon) | :white_check_mark: | :white_check_mark: | -For more information, visit [Welcome to Aleo](https://github.com/AleoHQ/welcome) to get started. +For more information, visit [Welcome to Aleo](https://github.com/AleoNet/welcome) to get started. ## 2. Build Guide @@ -52,7 +52,7 @@ We recommend installing Rust using [rustup](https://www.rustup.rs/). You can ins Download the [Windows 64-bit executable](https://win.rustup.rs/x86_64) or [Windows 32-bit executable](https://win.rustup.rs/i686) and follow the on-screen instructions. -### 2.2a Build from Crates.io +### 2.2.1 Build from Crates.io We recommend installing `snarkvm` this way. In your terminal, run: @@ -65,16 +65,17 @@ Now to use `snarkvm`, in your terminal, run: snarkvm ``` -### 2.2b Build from Source Code +### 2.2.2 Build from Source Code Alternatively, you can install `snarkvm` by building from the source code as follows: ```bash # Download the source code -git clone https://github.com/AleoHQ/snarkvm && cd snarkvm - +git clone --branch mainnet --single-branch https://github.com/AleoNet/snarkVM.git +cd snarkVM +git checkout tags/testnet-beta # Install snarkVM -$ cargo install --path . +cargo install --path . ``` Now to use `snarkvm`, in your terminal, run: @@ -95,57 +96,57 @@ Thank you for helping make snarkVM better! - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - + + + + + + diff --git a/SECURITY.md b/SECURITY.md index 57be86957f..9111a21e49 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,16 +2,10 @@ The following describes our procedure for addressing major and minor security concerns in snarkVM. -## Testnet - -As Aleo is currently in the prototype stage and does not operate a platform intended for production use, -our security procedures are designed to promote public disclosure and quick security resolution. - -In preparation for the production stage, we will release new security guidelines and -issue new procedures for addressing the disclosure of sensitive security vulnerabilities. +Our security procedures are designed to promote public disclosure and quick security resolution. ### Reporting a Bug -During Testnet, all software bugs should be reported by filing a Github issue. +All software bugs should be reported by filing a Github issue. If you are unsure and would like to reach out to us directly, please email security \_at\_ aleo.org to elaborate on the issue. diff --git a/algorithms/Cargo.toml b/algorithms/Cargo.toml index fd8e78c5e1..3603cc1a4a 100644 --- a/algorithms/Cargo.toml +++ b/algorithms/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-algorithms" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Algorithms for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -47,27 +47,27 @@ required-features = [ "test" ] [dependencies.snarkvm-curves] path = "../curves" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-fields] path = "../fields" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-parameters] path = "../parameters" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-utilities] path = "../utilities" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-algorithms-cuda] path = "./cuda" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.aleo-std] diff --git a/algorithms/benches/crypto_hash/poseidon.rs b/algorithms/benches/crypto_hash/poseidon.rs index 283de61e45..41c7f018ba 100644 --- a/algorithms/benches/crypto_hash/poseidon.rs +++ b/algorithms/benches/crypto_hash/poseidon.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,7 +16,7 @@ #[macro_use] extern crate criterion; -use snarkvm_algorithms::{crypto_hash::PoseidonSponge, AlgebraicSponge}; +use snarkvm_algorithms::{AlgebraicSponge, crypto_hash::PoseidonSponge}; use snarkvm_curves::bls12_377::{Fq, FqParameters}; use snarkvm_fields::Fp384; use snarkvm_utilities::{TestRng, Uniform}; diff --git a/algorithms/benches/fft/fft.rs b/algorithms/benches/fft/fft.rs index 0f52c2ff37..652eef55dc 100644 --- a/algorithms/benches/fft/fft.rs +++ b/algorithms/benches/fft/fft.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,7 +20,7 @@ use snarkvm_curves::bls12_377::Fr as Bls12_377_Fr; use snarkvm_fields::PrimeField; use snarkvm_utilities::TestRng; -use criterion::{criterion_group, criterion_main, Bencher, BenchmarkId, Criterion}; +use criterion::{Bencher, BenchmarkId, Criterion, criterion_group, criterion_main}; use std::cmp::min; /// Degree bounds to benchmark on diff --git a/algorithms/benches/msm/variable_base.rs b/algorithms/benches/msm/variable_base.rs index 5382d2cd75..651a651028 100644 --- a/algorithms/benches/msm/variable_base.rs +++ b/algorithms/benches/msm/variable_base.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/benches/snark/varuna.rs b/algorithms/benches/snark/varuna.rs index ea23d8d4ed..a18522956d 100644 --- a/algorithms/benches/snark/varuna.rs +++ b/algorithms/benches/snark/varuna.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,10 +17,10 @@ extern crate criterion; use snarkvm_algorithms::{ - crypto_hash::PoseidonSponge, - snark::varuna::{ahp::AHPForR1CS, CircuitVerifyingKey, TestCircuit, VarunaHidingMode, VarunaSNARK}, AlgebraicSponge, SNARK, + crypto_hash::PoseidonSponge, + snark::varuna::{CircuitVerifyingKey, TestCircuit, VarunaHidingMode, VarunaSNARK, ahp::AHPForR1CS}, }; use snarkvm_curves::bls12_377::{Bls12_377, Fq, Fr}; use snarkvm_utilities::{CanonicalDeserialize, CanonicalSerialize, TestRng}; diff --git a/algorithms/cuda/Cargo.toml b/algorithms/cuda/Cargo.toml index 3c1ff3f252..df0ef1d5a6 100644 --- a/algorithms/cuda/Cargo.toml +++ b/algorithms/cuda/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-algorithms-cuda" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Cuda optimizations for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", diff --git a/algorithms/cuda/build.rs b/algorithms/cuda/build.rs index 8e85744b6c..174110d885 100644 --- a/algorithms/cuda/build.rs +++ b/algorithms/cuda/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -17,9 +18,6 @@ use std::{env, path::PathBuf}; fn main() { let curve = "FEATURE_BLS12_377"; - // account for cross-compilation [by examining environment variable] - let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); - // Set CC environment variable to choose an alternative C compiler. // Optimization level depends on whether or not --release is passed // or implied. @@ -29,28 +27,22 @@ fn main() { let files = vec![c_src_dir.join("lib.c")]; let mut cc_opt = None; - match (cfg!(feature = "portable"), cfg!(feature = "force-adx")) { - (true, false) => { + match cfg!(feature = "portable") { + true => { println!("Compiling in portable mode without ISA extensions"); cc_opt = Some("__BLST_PORTABLE__"); } - (false, true) => { - if target_arch.eq("x86_64") { - println!("Enabling ADX support via `force-adx` feature"); - cc_opt = Some("__ADX__"); - } else { - println!("`force-adx` is ignored for non-x86_64 targets"); - } - } - (false, false) => - { + false => { #[cfg(target_arch = "x86_64")] - if target_arch.eq("x86_64") && std::is_x86_feature_detected!("adx") { - println!("Enabling ADX because it was detected on the host"); - cc_opt = Some("__ADX__"); + { + // account for cross-compilation [by examining environment variable] + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default(); + if target_arch.eq("x86_64") && std::is_x86_feature_detected!("adx") { + println!("Enabling ADX because it was detected on the host"); + cc_opt = Some("__ADX__"); + } } } - (true, true) => panic!("Cannot compile with both `portable` and `force-adx` features"), } cc.flag_if_supported("-mno-avx") // avoid costly transitions @@ -85,8 +77,6 @@ fn main() { nvcc.flag("-Xcompiler").flag("-Wno-unused-function"); nvcc.flag("-Xcompiler").flag("-Wno-subobject-linkage"); nvcc.define("TAKE_RESPONSIBILITY_FOR_ERROR_MESSAGE", None); - #[cfg(feature = "cuda-mobile")] - nvcc.define("NTHREADS", "128"); nvcc.define(curve, None); if let Some(def) = cc_opt { nvcc.define(def, None); diff --git a/algorithms/cuda/cuda/polynomial.cuh b/algorithms/cuda/cuda/polynomial.cuh index 745075accc..cea65f8d3f 100644 --- a/algorithms/cuda/cuda/polynomial.cuh +++ b/algorithms/cuda/cuda/polynomial.cuh @@ -1,18 +1,17 @@ -// Copyright (C) 2019-2022 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. -// The snarkVM library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. +// 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: -// The snarkVM library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// http://www.apache.org/licenses/LICENSE-2.0 -// You should have received a copy of the GNU General Public License -// along with the snarkVM library. If not, see . +// 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. #ifndef __POLYNOMIAL_CUH__ #define __POLYNOMIAL_CUH__ diff --git a/algorithms/cuda/cuda/snarkvm.cu b/algorithms/cuda/cuda/snarkvm.cu index 483a038095..b9e5e6892b 100644 --- a/algorithms/cuda/cuda/snarkvm.cu +++ b/algorithms/cuda/cuda/snarkvm.cu @@ -1,18 +1,17 @@ -// Copyright (C) 2019-2022 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. -// The snarkVM library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. +// 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: -// The snarkVM library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// http://www.apache.org/licenses/LICENSE-2.0 -// You should have received a copy of the GNU General Public License -// along with the snarkVM library. If not, see . +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #include diff --git a/algorithms/cuda/cuda/snarkvm_api.cu b/algorithms/cuda/cuda/snarkvm_api.cu index 83468342bc..978cc21504 100644 --- a/algorithms/cuda/cuda/snarkvm_api.cu +++ b/algorithms/cuda/cuda/snarkvm_api.cu @@ -1,18 +1,17 @@ -// Copyright (C) 2019-2022 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. -// The snarkVM library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. +// 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: -// The snarkVM library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// http://www.apache.org/licenses/LICENSE-2.0 -// You should have received a copy of the GNU General Public License -// along with the snarkVM library. If not, see . +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #include diff --git a/algorithms/cuda/src/lib.c b/algorithms/cuda/src/lib.c index 2f3f795914..137acd8f31 100644 --- a/algorithms/cuda/src/lib.c +++ b/algorithms/cuda/src/lib.c @@ -1,15 +1,14 @@ -// Copyright (C) 2019-2022 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. -// The snarkVM library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. +// 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: -// The snarkVM library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// http://www.apache.org/licenses/LICENSE-2.0 -// You should have received a copy of the GNU General Public License -// along with the snarkVM library. If not, see . +// 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. diff --git a/algorithms/cuda/src/lib.rs b/algorithms/cuda/src/lib.rs index 11b4218a69..6a4b61527e 100644 --- a/algorithms/cuda/src/lib.rs +++ b/algorithms/cuda/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/examples/msm.rs b/algorithms/examples/msm.rs index c3abbff5ab..0a89b71b61 100644 --- a/algorithms/examples/msm.rs +++ b/algorithms/examples/msm.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/crypto_hash/mod.rs b/algorithms/src/crypto_hash/mod.rs index 2f59d8c8e4..cb9ea1f720 100644 --- a/algorithms/src/crypto_hash/mod.rs +++ b/algorithms/src/crypto_hash/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/crypto_hash/poseidon.rs b/algorithms/src/crypto_hash/poseidon.rs index 77a28d8d47..71ffd5a02d 100644 --- a/algorithms/src/crypto_hash/poseidon.rs +++ b/algorithms/src/crypto_hash/poseidon.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{nonnative_params::*, AlgebraicSponge, DuplexSpongeMode}; +use crate::{AlgebraicSponge, DuplexSpongeMode, nonnative_params::*}; use snarkvm_fields::{FieldParameters, PoseidonParameters, PrimeField, ToConstraintField}; use snarkvm_utilities::{BigInteger, FromBits, ToBits}; diff --git a/algorithms/src/crypto_hash/sha256.rs b/algorithms/src/crypto_hash/sha256.rs index db8a50957c..ed8f7f7365 100644 --- a/algorithms/src/crypto_hash/sha256.rs +++ b/algorithms/src/crypto_hash/sha256.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/crypto_hash/tests.rs b/algorithms/src/crypto_hash/tests.rs index ffd51f01ad..90021f055f 100644 --- a/algorithms/src/crypto_hash/tests.rs +++ b/algorithms/src/crypto_hash/tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{crypto_hash::PoseidonSponge, AlgebraicSponge, DuplexSpongeMode}; +use crate::{AlgebraicSponge, DuplexSpongeMode, crypto_hash::PoseidonSponge}; use snarkvm_curves::bls12_377::Fr; use snarkvm_fields::{PoseidonDefaultField, PoseidonGrainLFSR}; diff --git a/algorithms/src/errors.rs b/algorithms/src/errors.rs index a1dedf9f12..7002591676 100644 --- a/algorithms/src/errors.rs +++ b/algorithms/src/errors.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -41,6 +42,9 @@ pub enum SNARKError { #[error("Batch size was different between public input and proof")] BatchSizeMismatch, + #[error("Public input size was different from the circuit")] + PublicInputSizeMismatch, + #[error("Circuit not found")] CircuitNotFound, } diff --git a/algorithms/src/fft/domain.rs b/algorithms/src/fft/domain.rs index bbac0f4c1d..64cd932d55 100644 --- a/algorithms/src/fft/domain.rs +++ b/algorithms/src/fft/domain.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -31,7 +32,7 @@ use crate::{ cfg_iter_mut, fft::{DomainCoeff, SparsePolynomial}, }; -use snarkvm_fields::{batch_inversion, FftField, FftParameters, Field}; +use snarkvm_fields::{FftField, FftParameters, Field, batch_inversion}; #[cfg(not(feature = "serial"))] use snarkvm_utilities::max_available_threads; use snarkvm_utilities::{execute_with_max_available_threads, serialize::*}; @@ -39,7 +40,7 @@ use snarkvm_utilities::{execute_with_max_available_threads, serialize::*}; use rand::Rng; use std::{borrow::Cow, fmt}; -use anyhow::{ensure, Result}; +use anyhow::{Result, ensure}; #[cfg(not(feature = "serial"))] use rayon::prelude::*; diff --git a/algorithms/src/fft/evaluations.rs b/algorithms/src/fft/evaluations.rs index 532e06756b..fe6b8724cd 100644 --- a/algorithms/src/fft/evaluations.rs +++ b/algorithms/src/fft/evaluations.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/fft/mod.rs b/algorithms/src/fft/mod.rs index 55dcef322b..6a6855d424 100644 --- a/algorithms/src/fft/mod.rs +++ b/algorithms/src/fft/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/fft/polynomial/dense.rs b/algorithms/src/fft/polynomial/dense.rs index 80b9658fc1..735e1ab71f 100644 --- a/algorithms/src/fft/polynomial/dense.rs +++ b/algorithms/src/fft/polynomial/dense.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/fft/polynomial/mod.rs b/algorithms/src/fft/polynomial/mod.rs index 8fcb907408..33f57ccd4d 100644 --- a/algorithms/src/fft/polynomial/mod.rs +++ b/algorithms/src/fft/polynomial/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,11 +16,11 @@ //! Work with sparse and dense polynomials. use crate::fft::{EvaluationDomain, Evaluations}; -use snarkvm_fields::{Field, PrimeField}; -use snarkvm_utilities::{cfg_iter_mut, serialize::*, SerializationError}; use Polynomial::*; +use snarkvm_fields::{Field, PrimeField}; +use snarkvm_utilities::{SerializationError, cfg_iter_mut, serialize::*}; -use anyhow::{ensure, Result}; +use anyhow::{Result, ensure}; use std::{borrow::Cow, convert::TryInto}; #[cfg(not(feature = "serial"))] diff --git a/algorithms/src/fft/polynomial/multiplier.rs b/algorithms/src/fft/polynomial/multiplier.rs index 0c7519ca5d..3bdcb76bdd 100644 --- a/algorithms/src/fft/polynomial/multiplier.rs +++ b/algorithms/src/fft/polynomial/multiplier.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,7 +19,7 @@ use crate::fft::domain::{FFTPrecomputation, IFFTPrecomputation}; /// A struct that helps multiply a batch of polynomials use super::*; -use snarkvm_utilities::{cfg_into_iter, cfg_iter, cfg_iter_mut, cfg_reduce_with, ExecutionPool}; +use snarkvm_utilities::{ExecutionPool, cfg_into_iter, cfg_iter, cfg_iter_mut, cfg_reduce_with}; #[derive(Default)] pub struct PolyMultiplier<'a, F: PrimeField> { diff --git a/algorithms/src/fft/polynomial/sparse.rs b/algorithms/src/fft/polynomial/sparse.rs index 16e397e357..1dae7e126b 100644 --- a/algorithms/src/fft/polynomial/sparse.rs +++ b/algorithms/src/fft/polynomial/sparse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/fft/tests.rs b/algorithms/src/fft/tests.rs index a6733f4eda..b717d7badf 100644 --- a/algorithms/src/fft/tests.rs +++ b/algorithms/src/fft/tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::fft::{domain::*, DensePolynomial}; +use crate::fft::{DensePolynomial, domain::*}; use rand::Rng; use snarkvm_curves::bls12_377::{Fr, G1Projective}; use snarkvm_fields::{FftField, Field, One, Zero}; diff --git a/algorithms/src/lib.rs b/algorithms/src/lib.rs index 6d0f9613d3..66b56cbd75 100644 --- a/algorithms/src/lib.rs +++ b/algorithms/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/msm/fixed_base.rs b/algorithms/src/msm/fixed_base.rs index 5b167a6d96..8c6ef90094 100644 --- a/algorithms/src/msm/fixed_base.rs +++ b/algorithms/src/msm/fixed_base.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use snarkvm_curves::traits::ProjectiveCurve; use snarkvm_fields::{FieldParameters, PrimeField}; -use snarkvm_utilities::{cfg_into_iter, cfg_iter, cfg_iter_mut, ToBits}; +use snarkvm_utilities::{ToBits, cfg_into_iter, cfg_iter, cfg_iter_mut}; #[cfg(not(feature = "serial"))] use rayon::prelude::*; diff --git a/algorithms/src/msm/mod.rs b/algorithms/src/msm/mod.rs index 97fe46858e..3ef50eac63 100644 --- a/algorithms/src/msm/mod.rs +++ b/algorithms/src/msm/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/msm/tests.rs b/algorithms/src/msm/tests.rs index 80f9e5faf2..2fd1c243bd 100644 --- a/algorithms/src/msm/tests.rs +++ b/algorithms/src/msm/tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,8 +20,8 @@ use snarkvm_curves::{ }; use snarkvm_fields::{PrimeField, Zero}; use snarkvm_utilities::{ - rand::{TestRng, Uniform}, BitIteratorBE, + rand::{TestRng, Uniform}, }; fn naive_variable_base_msm( diff --git a/algorithms/src/msm/variable_base/batched.rs b/algorithms/src/msm/variable_base/batched.rs index b1f172d8a4..0c284754bf 100644 --- a/algorithms/src/msm/variable_base/batched.rs +++ b/algorithms/src/msm/variable_base/batched.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use snarkvm_curves::{AffineCurve, ProjectiveCurve}; use snarkvm_fields::{Field, One, PrimeField, Zero}; -use snarkvm_utilities::{cfg_into_iter, BigInteger, BitIteratorBE}; +use snarkvm_utilities::{BigInteger, BitIteratorBE, cfg_into_iter}; #[cfg(not(feature = "serial"))] use rayon::prelude::*; @@ -43,6 +44,7 @@ impl Ord for BucketPosition { } impl PartialOrd for BucketPosition { + #[allow(clippy::non_canonical_partial_ord_impl)] fn partial_cmp(&self, other: &Self) -> Option { self.bucket_index.partial_cmp(&other.bucket_index) } diff --git a/algorithms/src/msm/variable_base/mod.rs b/algorithms/src/msm/variable_base/mod.rs index 11d4910bf3..c5af69c50f 100644 --- a/algorithms/src/msm/variable_base/mod.rs +++ b/algorithms/src/msm/variable_base/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/msm/variable_base/prefetch.rs b/algorithms/src/msm/variable_base/prefetch.rs index 65b7592c5d..1cae8015a4 100644 --- a/algorithms/src/msm/variable_base/prefetch.rs +++ b/algorithms/src/msm/variable_base/prefetch.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/msm/variable_base/standard.rs b/algorithms/src/msm/variable_base/standard.rs index ddba995b4f..5fb1399d0f 100644 --- a/algorithms/src/msm/variable_base/standard.rs +++ b/algorithms/src/msm/variable_base/standard.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use snarkvm_curves::{AffineCurve, ProjectiveCurve}; use snarkvm_fields::{One, PrimeField, Zero}; -use snarkvm_utilities::{cfg_into_iter, BigInteger}; +use snarkvm_utilities::{BigInteger, cfg_into_iter}; #[cfg(not(feature = "serial"))] use rayon::prelude::*; diff --git a/algorithms/src/polycommit/error.rs b/algorithms/src/polycommit/error.rs index f101d30224..c5f2b38c69 100644 --- a/algorithms/src/polycommit/error.rs +++ b/algorithms/src/polycommit/error.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/polycommit/kzg10/data_structures.rs b/algorithms/src/polycommit/kzg10/data_structures.rs index 495e817788..d8b2aa91e0 100644 --- a/algorithms/src/polycommit/kzg10/data_structures.rs +++ b/algorithms/src/polycommit/kzg10/data_structures.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,19 +14,19 @@ // limitations under the License. use crate::{ - fft::{DensePolynomial, EvaluationDomain}, AlgebraicSponge, + fft::{DensePolynomial, EvaluationDomain}, }; use snarkvm_curves::{AffineCurve, PairingCurve, PairingEngine, ProjectiveCurve}; use snarkvm_fields::{ConstraintFieldError, ToConstraintField, Zero}; -use snarkvm_parameters::testnet3::PowersOfG; +use snarkvm_parameters::mainnet::PowersOfG; use snarkvm_utilities::{ + FromBytes, + ToBytes, borrow::Cow, error, io::{Read, Write}, serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Valid, Validate}, - FromBytes, - ToBytes, }; use crate::srs::{UniversalProver, UniversalVerifier}; diff --git a/algorithms/src/polycommit/kzg10/mod.rs b/algorithms/src/polycommit/kzg10/mod.rs index e6fe95d534..986dd3713e 100644 --- a/algorithms/src/polycommit/kzg10/mod.rs +++ b/algorithms/src/polycommit/kzg10/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -26,9 +27,9 @@ use crate::{ }; use snarkvm_curves::traits::{AffineCurve, PairingCurve, PairingEngine, ProjectiveCurve}; use snarkvm_fields::{One, PrimeField, Zero}; -use snarkvm_utilities::{cfg_iter, cfg_iter_mut, rand::Uniform, BitIteratorBE}; +use snarkvm_utilities::{BitIteratorBE, cfg_iter, cfg_iter_mut, rand::Uniform}; -use anyhow::{anyhow, ensure, Result}; +use anyhow::{Result, anyhow, ensure}; use core::{marker::PhantomData, ops::Mul}; use itertools::Itertools; use rand_core::RngCore; @@ -478,7 +479,7 @@ mod tests { #![allow(clippy::needless_borrow)] use super::*; use snarkvm_curves::bls12_377::{Bls12_377, Fr}; - use snarkvm_utilities::{rand::TestRng, FromBytes, ToBytes}; + use snarkvm_utilities::{FromBytes, ToBytes, rand::TestRng}; use std::borrow::Cow; diff --git a/algorithms/src/polycommit/mod.rs b/algorithms/src/polycommit/mod.rs index 3cc32b5e1d..4e574a395e 100644 --- a/algorithms/src/polycommit/mod.rs +++ b/algorithms/src/polycommit/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/polycommit/optional_rng.rs b/algorithms/src/polycommit/optional_rng.rs index 9e662591e4..8a2e6f2d74 100644 --- a/algorithms/src/polycommit/optional_rng.rs +++ b/algorithms/src/polycommit/optional_rng.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/polycommit/sonic_pc/data_structures.rs b/algorithms/src/polycommit/sonic_pc/data_structures.rs index 6504d198fa..a7aaa6d7b3 100644 --- a/algorithms/src/polycommit/sonic_pc/data_structures.rs +++ b/algorithms/src/polycommit/sonic_pc/data_structures.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,7 +17,7 @@ use super::{LabeledPolynomial, PolynomialInfo}; use crate::{crypto_hash::sha256::sha256, fft::EvaluationDomain, polycommit::kzg10}; use snarkvm_curves::PairingEngine; use snarkvm_fields::{ConstraintFieldError, Field, PrimeField, ToConstraintField}; -use snarkvm_utilities::{error, serialize::*, FromBytes, ToBytes}; +use snarkvm_utilities::{FromBytes, ToBytes, error, serialize::*}; use hashbrown::HashMap; use std::{ diff --git a/algorithms/src/polycommit/sonic_pc/mod.rs b/algorithms/src/polycommit/sonic_pc/mod.rs index 847483ca69..1f295182b2 100644 --- a/algorithms/src/polycommit/sonic_pc/mod.rs +++ b/algorithms/src/polycommit/sonic_pc/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,18 +14,18 @@ // limitations under the License. use crate::{ + AlgebraicSponge, fft::DensePolynomial, msm::variable_base::VariableBase, - polycommit::{kzg10, optional_rng::OptionalRng, PCError}, + polycommit::{PCError, kzg10, optional_rng::OptionalRng}, srs::{UniversalProver, UniversalVerifier}, - AlgebraicSponge, }; use hashbrown::HashMap; use itertools::Itertools; use snarkvm_curves::traits::{AffineCurve, PairingCurve, PairingEngine, ProjectiveCurve}; use snarkvm_fields::{One, Zero}; -use anyhow::{bail, ensure, Result}; +use anyhow::{Result, bail, ensure}; use core::{convert::TryInto, marker::PhantomData, ops::Mul}; use rand_core::{RngCore, SeedableRng}; use std::{ @@ -684,7 +685,7 @@ mod tests { use super::{CommitterKey, SonicKZG10}; use crate::{crypto_hash::PoseidonSponge, polycommit::test_templates::*}; use snarkvm_curves::bls12_377::{Bls12_377, Fq}; - use snarkvm_utilities::{rand::TestRng, FromBytes, ToBytes}; + use snarkvm_utilities::{FromBytes, ToBytes, rand::TestRng}; use rand::distributions::Distribution; diff --git a/algorithms/src/polycommit/sonic_pc/polynomial.rs b/algorithms/src/polycommit/sonic_pc/polynomial.rs index a18a0bbace..912905e35d 100644 --- a/algorithms/src/polycommit/sonic_pc/polynomial.rs +++ b/algorithms/src/polycommit/sonic_pc/polynomial.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,7 +16,7 @@ use super::PolynomialLabel; use crate::fft::{DensePolynomial, EvaluationDomain, Evaluations as EvaluationsOnDomain, Polynomial, SparsePolynomial}; use snarkvm_fields::{Field, PrimeField}; -use snarkvm_utilities::{cfg_iter, cfg_iter_mut, CanonicalDeserialize, CanonicalSerialize}; +use snarkvm_utilities::{CanonicalDeserialize, CanonicalSerialize, cfg_iter, cfg_iter_mut}; use anyhow::Result; use std::borrow::Cow; diff --git a/algorithms/src/polycommit/test_templates.rs b/algorithms/src/polycommit/test_templates.rs index 60f73f027f..47288962ff 100644 --- a/algorithms/src/polycommit/test_templates.rs +++ b/algorithms/src/polycommit/test_templates.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,13 +25,13 @@ use super::sonic_pc::{ SonicKZG10, }; use crate::{ + AlgebraicSponge, fft::DensePolynomial, polycommit::{ - sonic_pc::{LabeledPolynomial, LabeledPolynomialWithBasis, LinearCombination}, PCError, + sonic_pc::{LabeledPolynomial, LabeledPolynomialWithBasis, LinearCombination}, }, srs::UniversalVerifier, - AlgebraicSponge, }; use snarkvm_curves::PairingEngine; use snarkvm_fields::{One, Zero}; @@ -38,8 +39,8 @@ use snarkvm_utilities::rand::{TestRng, Uniform}; use itertools::Itertools; use rand::{ - distributions::{self, Distribution}, Rng, + distributions::{self, Distribution}, }; use std::marker::PhantomData; diff --git a/algorithms/src/r1cs/assignment.rs b/algorithms/src/r1cs/assignment.rs index a59e637dbd..8049c5f5d9 100644 --- a/algorithms/src/r1cs/assignment.rs +++ b/algorithms/src/r1cs/assignment.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/r1cs/constraint_counter.rs b/algorithms/src/r1cs/constraint_counter.rs index a76360f261..af59d4626c 100644 --- a/algorithms/src/r1cs/constraint_counter.rs +++ b/algorithms/src/r1cs/constraint_counter.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::r1cs::{errors::SynthesisError, ConstraintSystem, Index, LinearCombination, Variable}; +use crate::r1cs::{ConstraintSystem, Index, LinearCombination, Variable, errors::SynthesisError}; use snarkvm_fields::Field; /// Constraint counter for testing purposes. diff --git a/algorithms/src/r1cs/constraint_system.rs b/algorithms/src/r1cs/constraint_system.rs index 0c73678a1a..1c9ac45a09 100644 --- a/algorithms/src/r1cs/constraint_system.rs +++ b/algorithms/src/r1cs/constraint_system.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::r1cs::{errors::SynthesisError, Index, LinearCombination, Namespace, Variable}; +use crate::r1cs::{Index, LinearCombination, Namespace, Variable, errors::SynthesisError}; use snarkvm_fields::Field; use std::marker::PhantomData; diff --git a/algorithms/src/r1cs/errors.rs b/algorithms/src/r1cs/errors.rs index 52b386e137..64ee84abcb 100644 --- a/algorithms/src/r1cs/errors.rs +++ b/algorithms/src/r1cs/errors.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/r1cs/linear_combination.rs b/algorithms/src/r1cs/linear_combination.rs index b0d0a38763..50fc5f92b1 100644 --- a/algorithms/src/r1cs/linear_combination.rs +++ b/algorithms/src/r1cs/linear_combination.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -114,7 +115,12 @@ impl AddAssign<(F, Variable)> for LinearCombination { #[inline] fn add_assign(&mut self, (coeff, var): (F, Variable)) { match self.get_var_loc(&var) { - Ok(found) => self.0[found].1 += &coeff, + Ok(found) => { + self.0[found].1 += &coeff; + if self.0[found].1.is_zero() { + self.0.remove(found); + } + } Err(not_found) => self.0.insert(not_found, (var, coeff)), } } diff --git a/algorithms/src/r1cs/mod.rs b/algorithms/src/r1cs/mod.rs index 4dd40feaa0..2001c0810f 100644 --- a/algorithms/src/r1cs/mod.rs +++ b/algorithms/src/r1cs/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/r1cs/namespace.rs b/algorithms/src/r1cs/namespace.rs index 0b4369fad4..cb863d1c2f 100644 --- a/algorithms/src/r1cs/namespace.rs +++ b/algorithms/src/r1cs/namespace.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::r1cs::{errors::SynthesisError, ConstraintSystem, LinearCombination, Variable}; +use crate::r1cs::{ConstraintSystem, LinearCombination, Variable, errors::SynthesisError}; use snarkvm_fields::Field; use std::marker::PhantomData; diff --git a/algorithms/src/r1cs/optional_vec.rs b/algorithms/src/r1cs/optional_vec.rs index bdbcb88b24..d00febfe6c 100644 --- a/algorithms/src/r1cs/optional_vec.rs +++ b/algorithms/src/r1cs/optional_vec.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/r1cs/test_constraint_checker.rs b/algorithms/src/r1cs/test_constraint_checker.rs index 019e85f9c0..04fadafe58 100644 --- a/algorithms/src/r1cs/test_constraint_checker.rs +++ b/algorithms/src/r1cs/test_constraint_checker.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::r1cs::{errors::SynthesisError, ConstraintSystem, Index, LinearCombination, Variable}; +use crate::r1cs::{ConstraintSystem, Index, LinearCombination, Variable, errors::SynthesisError}; use snarkvm_fields::Field; /// Constraint system for testing purposes. diff --git a/algorithms/src/r1cs/test_constraint_system.rs b/algorithms/src/r1cs/test_constraint_system.rs index 9f9b43ce73..6995e80e56 100644 --- a/algorithms/src/r1cs/test_constraint_system.rs +++ b/algorithms/src/r1cs/test_constraint_system.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,17 +13,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::r1cs::{errors::SynthesisError, ConstraintSystem, Index, LinearCombination, OptionalVec, Variable}; +use crate::r1cs::{ConstraintSystem, Index, LinearCombination, OptionalVec, Variable, errors::SynthesisError}; use snarkvm_fields::Field; use cfg_if::cfg_if; use fxhash::{FxBuildHasher, FxHashMap}; -use indexmap::{map::Entry, IndexMap, IndexSet}; +use indexmap::{IndexMap, IndexSet, map::Entry}; use itertools::Itertools; /// This field is the scalar field (Fr) of BLS12-377. pub type Fr = snarkvm_curves::bls12_377::Fr; +#[allow(dead_code)] #[derive(Debug, Clone)] enum NamedObject { Constraint(usize), @@ -306,7 +308,7 @@ impl TestConstraintSystem { ns_idx } Entry::Occupied(e) => { - let interned_segments = e.remove_entry().0; + let interned_segments = e.swap_remove_entry().0; panic!("tried to create object at existing path: {}", self.unintern_path(interned_segments)); } } diff --git a/algorithms/src/snark/mod.rs b/algorithms/src/snark/mod.rs index d856b63db4..18d74c4f72 100644 --- a/algorithms/src/snark/mod.rs +++ b/algorithms/src/snark/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/snark/varuna/ahp/ahp.rs b/algorithms/src/snark/varuna/ahp/ahp.rs index 0b88868473..dca44cab16 100644 --- a/algorithms/src/snark/varuna/ahp/ahp.rs +++ b/algorithms/src/snark/varuna/ahp/ahp.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,20 +15,20 @@ use crate::{ fft::{ - domain::{FFTPrecomputation, IFFTPrecomputation}, EvaluationDomain, + domain::{FFTPrecomputation, IFFTPrecomputation}, }, polycommit::sonic_pc::{LCTerm, LabeledPolynomial, LinearCombination}, r1cs::SynthesisError, snark::varuna::{ - ahp::{verifier, AHPError, CircuitId, CircuitInfo}, + SNARKMode, + ahp::{AHPError, CircuitId, CircuitInfo, verifier}, prover, selectors::precompute_selectors, verifier::QueryPoints, - SNARKMode, }, }; -use anyhow::{anyhow, ensure, Result}; +use anyhow::{Result, anyhow, ensure}; use snarkvm_fields::{Field, PrimeField}; use core::{borrow::Borrow, marker::PhantomData}; @@ -107,7 +108,7 @@ impl AHPForR1CS { /// Get all the strict degree bounds enforced in the AHP. pub fn get_degree_bounds(info: &CircuitInfo) -> Result<[usize; 4]> { - let num_variables = info.num_variables; + let num_variables = info.num_public_and_private_variables; let num_non_zero_a = info.num_non_zero_a; let num_non_zero_b = info.num_non_zero_b; let num_non_zero_c = info.num_non_zero_c; @@ -180,23 +181,20 @@ impl AHPForR1CS { let max_constraint_domain = state.max_constraint_domain; let max_variable_domain = state.max_variable_domain; let max_non_zero_domain = state.max_non_zero_domain; - let public_inputs = state - .circuit_specific_states - .iter() - .map(|(circuit_id, circuit_state)| { - let input_domain = circuit_state.input_domain; - let public_inputs = public_inputs[circuit_id] - .iter() - .map(|p| { - let public_input = prover::ConstraintSystem::format_public_input(p); - Self::formatted_public_input_is_admissible(&public_input)?; - Ok::<_, AHPError>(public_input) - }) - .collect::, _>>()?; - ensure!(public_inputs[0].len() == input_domain.size()); - Ok(public_inputs) - }) - .collect::, _>>()?; + let mut formatted_public_inputs = Vec::with_capacity(state.circuit_specific_states.len()); + for (circuit_id, circuit_state) in &state.circuit_specific_states { + let input_domain = circuit_state.input_domain; + let public_inputs_i = public_inputs[circuit_id] + .iter() + .map(|p| { + let public_input = prover::ConstraintSystem::format_public_input(p); + Self::formatted_public_input_is_admissible(&public_input)?; + Ok::<_, AHPError>(public_input) + }) + .collect::, _>>()?; + ensure!(public_inputs_i[0].len() == input_domain.size()); + formatted_public_inputs.push(public_inputs_i); + } let verifier::FirstMessage { batch_combiners } = state.first_round_message.as_ref().unwrap(); let verifier::SecondMessage { alpha, eta_b, eta_c } = state.second_round_message.unwrap(); @@ -286,7 +284,7 @@ impl AHPForR1CS { .enumerate() .map(|(i, (circuit_id, circuit_state))| { let lag_at_beta = circuit_state.input_domain.evaluate_all_lagrange_coefficients(beta); - let x_at_beta = public_inputs[i] + let x_at_beta = formatted_public_inputs[i] .iter() .map(|x| x.iter().zip_eq(&lag_at_beta).map(|(x, l)| *x * l).sum::()) .collect_vec(); diff --git a/algorithms/src/snark/varuna/ahp/errors.rs b/algorithms/src/snark/varuna/ahp/errors.rs index a18dfb46b2..3fa39f84b3 100644 --- a/algorithms/src/snark/varuna/ahp/errors.rs +++ b/algorithms/src/snark/varuna/ahp/errors.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/snark/varuna/ahp/indexer/circuit.rs b/algorithms/src/snark/varuna/ahp/indexer/circuit.rs index 53f3ca3d6e..fb48461b83 100644 --- a/algorithms/src/snark/varuna/ahp/indexer/circuit.rs +++ b/algorithms/src/snark/varuna/ahp/indexer/circuit.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,24 +17,24 @@ use core::marker::PhantomData; use crate::{ fft::{ - domain::{FFTPrecomputation, IFFTPrecomputation}, EvaluationDomain, + domain::{FFTPrecomputation, IFFTPrecomputation}, }, polycommit::sonic_pc::LabeledPolynomial, snark::varuna::{ - ahp::matrices::MatrixEvals, - matrices::MatrixArithmetization, AHPForR1CS, CircuitInfo, Matrix, SNARKMode, + ahp::matrices::MatrixEvals, + matrices::MatrixArithmetization, }, }; -use anyhow::{anyhow, Result}; +use anyhow::{Result, anyhow}; use blake2::Digest; use hex::FromHex; use snarkvm_fields::PrimeField; -use snarkvm_utilities::{serialize::*, SerializationError}; +use snarkvm_utilities::{SerializationError, serialize::*}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, CanonicalSerialize, CanonicalDeserialize)] pub struct CircuitId(pub [u8; 32]); @@ -133,7 +134,7 @@ impl Circuit { /// The size of the variable domain in this R1CS instance. pub fn variable_domain_size(&self) -> Result { - Ok(crate::fft::EvaluationDomain::::new(self.index_info.num_variables) + Ok(crate::fft::EvaluationDomain::::new(self.index_info.num_public_and_private_variables) .ok_or(anyhow!("Cannot create EvaluationDomain"))? .size()) } @@ -197,8 +198,9 @@ impl CanonicalDeserialize for Circuit { let index_info: CircuitInfo = CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?; let constraint_domain_size = EvaluationDomain::::compute_size_of_domain(index_info.num_constraints) .ok_or(SerializationError::InvalidData)?; - let variable_domain_size = EvaluationDomain::::compute_size_of_domain(index_info.num_variables) - .ok_or(SerializationError::InvalidData)?; + let variable_domain_size = + EvaluationDomain::::compute_size_of_domain(index_info.num_public_and_private_variables) + .ok_or(SerializationError::InvalidData)?; let non_zero_a_domain_size = EvaluationDomain::::compute_size_of_domain(index_info.num_non_zero_a) .ok_or(SerializationError::InvalidData)?; let non_zero_b_domain_size = EvaluationDomain::::compute_size_of_domain(index_info.num_non_zero_b) diff --git a/algorithms/src/snark/varuna/ahp/indexer/circuit_info.rs b/algorithms/src/snark/varuna/ahp/indexer/circuit_info.rs index 5db3583414..cb586e5cc4 100644 --- a/algorithms/src/snark/varuna/ahp/indexer/circuit_info.rs +++ b/algorithms/src/snark/varuna/ahp/indexer/circuit_info.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::snark::varuna::{ahp::AHPForR1CS, SNARKMode}; +use crate::snark::varuna::{SNARKMode, ahp::AHPForR1CS}; use anyhow::Result; use snarkvm_fields::PrimeField; -use snarkvm_utilities::{serialize::*, ToBytes}; +use snarkvm_utilities::{ToBytes, serialize::*}; /// Information about the circuit, including the field of definition, the number of /// variables, the number of constraints, and the maximum number of non-zero @@ -24,8 +25,9 @@ use snarkvm_utilities::{serialize::*, ToBytes}; pub struct CircuitInfo { /// The number of public inputs after padding. pub num_public_inputs: usize, - /// The total number of variables in the constraint system. - pub num_variables: usize, + /// The number of public and private variables in the constraint system. + /// Note: This does *NOT* include the number of constants in the constraint system. + pub num_public_and_private_variables: usize, /// The number of constraints. pub num_constraints: usize, /// The number of non-zero entries in the A matrix. @@ -40,14 +42,14 @@ impl CircuitInfo { /// The maximum degree of polynomial required to represent this index in the AHP. pub fn max_degree(&self) -> Result { let max_non_zero = self.num_non_zero_a.max(self.num_non_zero_b).max(self.num_non_zero_c); - AHPForR1CS::::max_degree(self.num_constraints, self.num_variables, max_non_zero) + AHPForR1CS::::max_degree(self.num_constraints, self.num_public_and_private_variables, max_non_zero) } } impl ToBytes for CircuitInfo { fn write_le(&self, mut w: W) -> Result<(), io::Error> { (self.num_public_inputs as u64).write_le(&mut w)?; - (self.num_variables as u64).write_le(&mut w)?; + (self.num_public_and_private_variables as u64).write_le(&mut w)?; (self.num_constraints as u64).write_le(&mut w)?; (self.num_non_zero_a as u64).write_le(&mut w)?; (self.num_non_zero_b as u64).write_le(&mut w)?; diff --git a/algorithms/src/snark/varuna/ahp/indexer/constraint_system.rs b/algorithms/src/snark/varuna/ahp/indexer/constraint_system.rs index 1ad2024797..2bc8e5a59a 100644 --- a/algorithms/src/snark/varuna/ahp/indexer/constraint_system.rs +++ b/algorithms/src/snark/varuna/ahp/indexer/constraint_system.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::r1cs::{errors::SynthesisError, ConstraintSystem as CS, Index as VarIndex, LinearCombination, Variable}; +use crate::r1cs::{ConstraintSystem as CS, Index as VarIndex, LinearCombination, Variable, errors::SynthesisError}; use snarkvm_fields::Field; use snarkvm_utilities::serialize::*; diff --git a/algorithms/src/snark/varuna/ahp/indexer/indexer.rs b/algorithms/src/snark/varuna/ahp/indexer/indexer.rs index 5945df7570..b89889d344 100644 --- a/algorithms/src/snark/varuna/ahp/indexer/indexer.rs +++ b/algorithms/src/snark/varuna/ahp/indexer/indexer.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,28 +16,27 @@ use crate::{ fft::EvaluationDomain, polycommit::sonic_pc::{LinearCombination, PolynomialInfo, PolynomialLabel}, - r1cs::{errors::SynthesisError, ConstraintSynthesizer}, + r1cs::{ConstraintSynthesizer, errors::SynthesisError}, snark::varuna::{ + SNARKMode, ahp::{ - indexer::{Circuit, CircuitId, CircuitInfo, ConstraintSystem as IndexerConstraintSystem}, AHPForR1CS, + indexer::{Circuit, CircuitId, CircuitInfo, ConstraintSystem as IndexerConstraintSystem}, }, - matrices::{into_matrix_helper, matrix_evals, MatrixEvals}, + matrices::{MatrixEvals, into_matrix_helper, matrix_evals}, num_non_zero, - SNARKMode, }, }; use snarkvm_fields::PrimeField; use snarkvm_utilities::cfg_into_iter; -use anyhow::{anyhow, ensure, Result}; +use anyhow::{Result, anyhow, ensure}; use core::marker::PhantomData; use itertools::Itertools; use std::collections::BTreeMap; #[cfg(not(feature = "serial"))] use rayon::prelude::*; -#[cfg(not(feature = "std"))] use snarkvm_utilities::println; use super::Matrix; @@ -168,7 +168,7 @@ impl AHPForR1CS { let index_info = CircuitInfo { num_public_inputs: num_padded_public_variables, - num_variables, + num_public_and_private_variables: num_variables, num_constraints, num_non_zero_a, num_non_zero_b, diff --git a/algorithms/src/snark/varuna/ahp/indexer/mod.rs b/algorithms/src/snark/varuna/ahp/indexer/mod.rs index 94ab917619..d36f6dce0f 100644 --- a/algorithms/src/snark/varuna/ahp/indexer/mod.rs +++ b/algorithms/src/snark/varuna/ahp/indexer/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/snark/varuna/ahp/matrices.rs b/algorithms/src/snark/varuna/ahp/matrices.rs index 99dfbc6968..4f57b78d9b 100644 --- a/algorithms/src/snark/varuna/ahp/matrices.rs +++ b/algorithms/src/snark/varuna/ahp/matrices.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,14 +20,14 @@ use crate::{ polycommit::sonic_pc::LabeledPolynomial, r1cs::{ConstraintSystem, Index as VarIndex}, snark::varuna::{ - ahp::{indexer::Matrix, AHPForR1CS, CircuitId}, VarunaHidingMode, + ahp::{AHPForR1CS, CircuitId, indexer::Matrix}, }, }; use snarkvm_fields::{Field, PrimeField}; use snarkvm_utilities::{cfg_into_iter, cfg_iter, cfg_iter_mut, serialize::*}; -use anyhow::{anyhow, ensure, Result}; +use anyhow::{Result, anyhow, ensure}; #[cfg(feature = "serial")] use itertools::Itertools; diff --git a/algorithms/src/snark/varuna/ahp/mod.rs b/algorithms/src/snark/varuna/ahp/mod.rs index f6e10fb207..a9638332b0 100644 --- a/algorithms/src/snark/varuna/ahp/mod.rs +++ b/algorithms/src/snark/varuna/ahp/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/snark/varuna/ahp/prover/constraint_system.rs b/algorithms/src/snark/varuna/ahp/prover/constraint_system.rs index 8a4b2d7d50..dcd046a519 100644 --- a/algorithms/src/snark/varuna/ahp/prover/constraint_system.rs +++ b/algorithms/src/snark/varuna/ahp/prover/constraint_system.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::r1cs::{errors::SynthesisError, ConstraintSystem as CS, Index as VarIndex, LinearCombination, Variable}; +use crate::r1cs::{ConstraintSystem as CS, Index as VarIndex, LinearCombination, Variable, errors::SynthesisError}; use snarkvm_fields::Field; pub(crate) struct ConstraintSystem { diff --git a/algorithms/src/snark/varuna/ahp/prover/message.rs b/algorithms/src/snark/varuna/ahp/prover/message.rs index c13ed2fc26..b97e17eb60 100644 --- a/algorithms/src/snark/varuna/ahp/prover/message.rs +++ b/algorithms/src/snark/varuna/ahp/prover/message.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,9 +15,9 @@ use std::collections::BTreeMap; -use crate::snark::varuna::{verifier::BatchCombiners, CircuitId}; +use crate::snark::varuna::{CircuitId, verifier::BatchCombiners}; use snarkvm_fields::PrimeField; -use snarkvm_utilities::{error, serialize::*, ToBytes, Write}; +use snarkvm_utilities::{ToBytes, Write, error, serialize::*}; #[derive(Clone, Debug, Default, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)] pub struct MatrixSums { diff --git a/algorithms/src/snark/varuna/ahp/prover/mod.rs b/algorithms/src/snark/varuna/ahp/prover/mod.rs index 68adb3038c..3474672b1f 100644 --- a/algorithms/src/snark/varuna/ahp/prover/mod.rs +++ b/algorithms/src/snark/varuna/ahp/prover/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/snark/varuna/ahp/prover/oracles.rs b/algorithms/src/snark/varuna/ahp/prover/oracles.rs index 37b1c94728..b4ebaf8760 100644 --- a/algorithms/src/snark/varuna/ahp/prover/oracles.rs +++ b/algorithms/src/snark/varuna/ahp/prover/oracles.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/snark/varuna/ahp/prover/round_functions/fifth.rs b/algorithms/src/snark/varuna/ahp/prover/round_functions/fifth.rs index e393d8ed28..ee695bc4c0 100644 --- a/algorithms/src/snark/varuna/ahp/prover/round_functions/fifth.rs +++ b/algorithms/src/snark/varuna/ahp/prover/round_functions/fifth.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,9 +19,9 @@ use crate::{ fft::DensePolynomial, polycommit::sonic_pc::{LabeledPolynomial, PolynomialInfo, PolynomialLabel}, snark::varuna::{ - ahp::{verifier, AHPError, AHPForR1CS}, - prover, SNARKMode, + ahp::{AHPError, AHPForR1CS, verifier}, + prover, }, }; use snarkvm_fields::PrimeField; diff --git a/algorithms/src/snark/varuna/ahp/prover/round_functions/first.rs b/algorithms/src/snark/varuna/ahp/prover/round_functions/first.rs index df9d33a72c..35787e0ec6 100644 --- a/algorithms/src/snark/varuna/ahp/prover/round_functions/first.rs +++ b/algorithms/src/snark/varuna/ahp/prover/round_functions/first.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,12 +17,12 @@ use crate::{ fft::{DensePolynomial, EvaluationDomain, Evaluations as EvaluationsOnDomain, SparsePolynomial}, polycommit::sonic_pc::{LabeledPolynomial, PolynomialInfo, PolynomialLabel}, snark::varuna::{ - ahp::{AHPError, AHPForR1CS}, - prover, - witness_label, Circuit, CircuitId, SNARKMode, + ahp::{AHPError, AHPForR1CS}, + prover, + witness_label, }, }; use snarkvm_fields::PrimeField; diff --git a/algorithms/src/snark/varuna/ahp/prover/round_functions/fourth.rs b/algorithms/src/snark/varuna/ahp/prover/round_functions/fourth.rs index 17d1789961..840b421bd6 100644 --- a/algorithms/src/snark/varuna/ahp/prover/round_functions/fourth.rs +++ b/algorithms/src/snark/varuna/ahp/prover/round_functions/fourth.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,24 +15,24 @@ use crate::{ fft::{ - domain::{FFTPrecomputation, IFFTPrecomputation}, - polynomial::PolyMultiplier, DensePolynomial, EvaluationDomain, Evaluations as EvaluationsOnDomain, + domain::{FFTPrecomputation, IFFTPrecomputation}, + polynomial::PolyMultiplier, }, polycommit::sonic_pc::{LabeledPolynomial, PolynomialInfo, PolynomialLabel}, snark::varuna::{ - ahp::{indexer::CircuitInfo, verifier, AHPError, AHPForR1CS, CircuitId}, + SNARKMode, + ahp::{AHPError, AHPForR1CS, CircuitId, indexer::CircuitInfo, verifier}, matrices::MatrixEvals, prover, selectors::apply_randomized_selector, witness_label, - SNARKMode, }, }; -use snarkvm_fields::{batch_inversion_and_mul, PrimeField}; -use snarkvm_utilities::{cfg_iter, cfg_iter_mut, ExecutionPool}; +use snarkvm_fields::{PrimeField, batch_inversion_and_mul}; +use snarkvm_utilities::{ExecutionPool, cfg_iter, cfg_iter_mut}; use anyhow::Result; use core::convert::TryInto; diff --git a/algorithms/src/snark/varuna/ahp/prover/round_functions/mod.rs b/algorithms/src/snark/varuna/ahp/prover/round_functions/mod.rs index a3cc01b438..652d58bb55 100644 --- a/algorithms/src/snark/varuna/ahp/prover/round_functions/mod.rs +++ b/algorithms/src/snark/varuna/ahp/prover/round_functions/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,9 +16,9 @@ use crate::{ r1cs::ConstraintSynthesizer, snark::varuna::{ - ahp::{indexer::Circuit, AHPError, AHPForR1CS}, - prover, SNARKMode, + ahp::{AHPError, AHPForR1CS, indexer::Circuit}, + prover, }, }; use snarkvm_fields::PrimeField; @@ -28,9 +29,7 @@ use rand::Rng; use rand_core::CryptoRng; use std::collections::BTreeMap; -use snarkvm_utilities::cfg_iter; -#[cfg(not(feature = "std"))] -use snarkvm_utilities::println; +use snarkvm_utilities::{cfg_iter, println}; #[cfg(not(feature = "serial"))] use rayon::prelude::*; @@ -121,7 +120,8 @@ impl AHPForR1CS { } if circuit.index_info.num_constraints != num_constraints - || circuit.index_info.num_variables != (num_public_variables + num_private_variables) + || circuit.index_info.num_public_and_private_variables + != (num_public_variables + num_private_variables) { return Err(AHPError::InstanceDoesNotMatchIndex); } diff --git a/algorithms/src/snark/varuna/ahp/prover/round_functions/second.rs b/algorithms/src/snark/varuna/ahp/prover/round_functions/second.rs index 9060e7746e..46538ef089 100644 --- a/algorithms/src/snark/varuna/ahp/prover/round_functions/second.rs +++ b/algorithms/src/snark/varuna/ahp/prover/round_functions/second.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,22 +16,22 @@ use std::collections::BTreeMap; use crate::{ - fft::{polynomial::PolyMultiplier, DensePolynomial, EvaluationDomain, Evaluations as EvaluationsOnDomain}, + fft::{DensePolynomial, EvaluationDomain, Evaluations as EvaluationsOnDomain, polynomial::PolyMultiplier}, polycommit::sonic_pc::{LabeledPolynomial, PolynomialInfo, PolynomialLabel}, snark::varuna::{ - ahp::{verifier, AHPForR1CS}, - prover, - selectors::apply_randomized_selector, - witness_label, Circuit, CircuitId, SNARKMode, + ahp::{AHPForR1CS, verifier}, + prover, + selectors::apply_randomized_selector, + witness_label, }, }; use anyhow::Result; use rand_core::RngCore; use snarkvm_fields::PrimeField; -use snarkvm_utilities::{cfg_into_iter, cfg_iter_mut, cfg_reduce, ExecutionPool}; +use snarkvm_utilities::{ExecutionPool, cfg_into_iter, cfg_iter_mut, cfg_reduce}; #[cfg(not(feature = "serial"))] use rayon::prelude::*; diff --git a/algorithms/src/snark/varuna/ahp/prover/round_functions/third.rs b/algorithms/src/snark/varuna/ahp/prover/round_functions/third.rs index bccfedfaac..674c13b036 100644 --- a/algorithms/src/snark/varuna/ahp/prover/round_functions/third.rs +++ b/algorithms/src/snark/varuna/ahp/prover/round_functions/third.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,27 +15,27 @@ use crate::{ fft::{ - domain::{FFTPrecomputation, IFFTPrecomputation}, - polynomial::PolyMultiplier, DensePolynomial, EvaluationDomain, Evaluations, + domain::{FFTPrecomputation, IFFTPrecomputation}, + polynomial::PolyMultiplier, }, polycommit::sonic_pc::{LabeledPolynomial, PolynomialInfo, PolynomialLabel}, snark::varuna::{ - ahp::{indexer::CircuitId, verifier, AHPForR1CS}, - matrices::transpose, - prover::{self, MatrixSums, ThirdMessage}, - selectors::apply_randomized_selector, AHPError, Matrix, SNARKMode, + ahp::{AHPForR1CS, indexer::CircuitId, verifier}, + matrices::transpose, + prover::{self, MatrixSums, ThirdMessage}, + selectors::apply_randomized_selector, }, }; use snarkvm_fields::PrimeField; -use snarkvm_utilities::{cfg_iter, ExecutionPool}; +use snarkvm_utilities::{ExecutionPool, cfg_iter}; -use anyhow::{ensure, Result}; +use anyhow::{Result, ensure}; use itertools::Itertools; use rand_core::RngCore; use std::collections::BTreeMap; @@ -153,9 +154,7 @@ impl AHPForR1CS { let fft_precomputation = &circuit.fft_precomputation; let ifft_precomputation = &circuit.ifft_precomputation; - for (_j, (&instance_combiner, assignment)) in - itertools::izip!(instance_combiners, assignments_i).enumerate() - { + for (&instance_combiner, assignment) in itertools::izip!(instance_combiners, assignments_i) { for (label, matrix_combiner) in itertools::izip!(matrix_labels, matrix_combiners) { let matrix_transpose = &matrix_transposes_i[label]; let combiner = circuit_combiner * instance_combiner * matrix_combiner; diff --git a/algorithms/src/snark/varuna/ahp/prover/state.rs b/algorithms/src/snark/varuna/ahp/prover/state.rs index 02a90ea688..a22cc0f7e2 100644 --- a/algorithms/src/snark/varuna/ahp/prover/state.rs +++ b/algorithms/src/snark/varuna/ahp/prover/state.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -122,9 +123,9 @@ impl<'a, F: PrimeField, SM: SNARKMode> State<'a, F, SM> { EvaluationDomain::new(index_info.num_constraints).ok_or(SynthesisError::PolyTooLarge)?; max_num_constraints = max_num_constraints.max(index_info.num_constraints); - let variable_domain = - EvaluationDomain::new(index_info.num_variables).ok_or(SynthesisError::PolyTooLarge)?; - max_num_variables = max_num_variables.max(index_info.num_variables); + let variable_domain = EvaluationDomain::new(index_info.num_public_and_private_variables) + .ok_or(SynthesisError::PolyTooLarge)?; + max_num_variables = max_num_variables.max(index_info.num_public_and_private_variables); let non_zero_domains = AHPForR1CS::<_, SM>::cmp_non_zero_domains(index_info, max_non_zero_domain)?; max_non_zero_domain = non_zero_domains.max_non_zero_domain; diff --git a/algorithms/src/snark/varuna/ahp/selectors.rs b/algorithms/src/snark/varuna/ahp/selectors.rs index 6bf9744ae2..a202e51222 100644 --- a/algorithms/src/snark/varuna/ahp/selectors.rs +++ b/algorithms/src/snark/varuna/ahp/selectors.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,10 +15,10 @@ use super::verifier::QueryPoints; use crate::fft::{DensePolynomial, EvaluationDomain}; -use snarkvm_fields::{batch_inversion, PrimeField}; +use snarkvm_fields::{PrimeField, batch_inversion}; use snarkvm_utilities::{cfg_into_iter, cfg_iter_mut, serialize::*}; -use anyhow::{ensure, Result}; +use anyhow::{Result, ensure}; use itertools::Itertools; use std::collections::{BTreeMap, HashSet}; diff --git a/algorithms/src/snark/varuna/ahp/verifier/messages.rs b/algorithms/src/snark/varuna/ahp/verifier/messages.rs index 1abd254d6d..9b995415b3 100644 --- a/algorithms/src/snark/varuna/ahp/verifier/messages.rs +++ b/algorithms/src/snark/varuna/ahp/verifier/messages.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::snark::varuna::{witness_label, CircuitId, SNARKMode}; +use crate::snark::varuna::{CircuitId, SNARKMode, witness_label}; use snarkvm_fields::PrimeField; use itertools::Itertools; diff --git a/algorithms/src/snark/varuna/ahp/verifier/mod.rs b/algorithms/src/snark/varuna/ahp/verifier/mod.rs index c0562670b6..063c50d867 100644 --- a/algorithms/src/snark/varuna/ahp/verifier/mod.rs +++ b/algorithms/src/snark/varuna/ahp/verifier/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/snark/varuna/ahp/verifier/state.rs b/algorithms/src/snark/varuna/ahp/verifier/state.rs index 4fbd079c09..486f31e4da 100644 --- a/algorithms/src/snark/varuna/ahp/verifier/state.rs +++ b/algorithms/src/snark/varuna/ahp/verifier/state.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -17,9 +18,9 @@ use core::marker::PhantomData; use crate::{ fft::EvaluationDomain, snark::varuna::{ - ahp::verifier::{FirstMessage, FourthMessage, SecondMessage, ThirdMessage}, CircuitId, SNARKMode, + ahp::verifier::{FirstMessage, FourthMessage, SecondMessage, ThirdMessage}, }, }; use snarkvm_fields::PrimeField; diff --git a/algorithms/src/snark/varuna/ahp/verifier/verifier.rs b/algorithms/src/snark/varuna/ahp/verifier/verifier.rs index 0ec22a32ef..935778eb26 100644 --- a/algorithms/src/snark/varuna/ahp/verifier/verifier.rs +++ b/algorithms/src/snark/varuna/ahp/verifier/verifier.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,20 +16,20 @@ use core::marker::PhantomData; use crate::{ + AlgebraicSponge, fft::EvaluationDomain, snark::varuna::{ + SNARKMode, ahp::{ - indexer::{CircuitId, CircuitInfo}, - verifier::{BatchCombiners, FirstMessage, FourthMessage, QuerySet, SecondMessage, State, ThirdMessage}, AHPError, AHPForR1CS, + indexer::{CircuitId, CircuitInfo}, + verifier::{BatchCombiners, FirstMessage, FourthMessage, QuerySet, SecondMessage, State, ThirdMessage}, }, verifier::CircuitSpecificState, - SNARKMode, }, - AlgebraicSponge, }; -use anyhow::{ensure, Result}; +use anyhow::{Result, ensure}; use smallvec::SmallVec; use snarkvm_fields::PrimeField; use std::collections::BTreeMap; @@ -71,7 +72,8 @@ impl AHPForR1CS { end_timer!(constraint_domain_time); let variable_domain_time = start_timer!(|| format!("Constructing constraint domain for {circuit_id}")); - let variable_domain = EvaluationDomain::new(circuit_info.num_variables).ok_or(AHPError::PolyTooLarge)?; + let variable_domain = + EvaluationDomain::new(circuit_info.num_public_and_private_variables).ok_or(AHPError::PolyTooLarge)?; end_timer!(variable_domain_time); let non_zero_a_time = start_timer!(|| format!("Constructing non-zero-a domain for {circuit_id}")); diff --git a/algorithms/src/snark/varuna/data_structures/certificate.rs b/algorithms/src/snark/varuna/data_structures/certificate.rs index 15d71851de..48511857d9 100644 --- a/algorithms/src/snark/varuna/data_structures/certificate.rs +++ b/algorithms/src/snark/varuna/data_structures/certificate.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,11 +16,11 @@ use crate::polycommit::sonic_pc; use snarkvm_curves::PairingEngine; use snarkvm_utilities::{ + FromBytes, + ToBytes, error, io::{self, Read, Write}, serialize::*, - FromBytes, - ToBytes, }; /// A certificate for the verifying key. diff --git a/algorithms/src/snark/varuna/data_structures/circuit_proving_key.rs b/algorithms/src/snark/varuna/data_structures/circuit_proving_key.rs index 5848743d0f..789be2ba68 100644 --- a/algorithms/src/snark/varuna/data_structures/circuit_proving_key.rs +++ b/algorithms/src/snark/varuna/data_structures/circuit_proving_key.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,14 +15,14 @@ use crate::{ polycommit::sonic_pc, - snark::varuna::{ahp::indexer::*, CircuitVerifyingKey, SNARKMode}, + snark::varuna::{CircuitVerifyingKey, SNARKMode, ahp::indexer::*}, }; use snarkvm_curves::PairingEngine; use snarkvm_utilities::{ - io::{self, Read, Write}, - serialize::*, FromBytes, ToBytes, + io::{self, Read, Write}, + serialize::*, }; use std::{cmp::Ordering, sync::Arc}; diff --git a/algorithms/src/snark/varuna/data_structures/circuit_verifying_key.rs b/algorithms/src/snark/varuna/data_structures/circuit_verifying_key.rs index 6f6aea970c..186b2cc3d1 100644 --- a/algorithms/src/snark/varuna/data_structures/circuit_verifying_key.rs +++ b/algorithms/src/snark/varuna/data_structures/circuit_verifying_key.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,19 +16,19 @@ use crate::{polycommit::sonic_pc, snark::varuna::ahp::indexer::*}; use snarkvm_curves::PairingEngine; use snarkvm_utilities::{ - error, - io::{self, Read, Write}, - serialize::*, - string::String, FromBytes, FromBytesDeserializer, ToBytes, ToBytesSerializer, + error, + io::{self, Read, Write}, + serialize::*, + string::String, }; use anyhow::Result; use core::{fmt, str::FromStr}; -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; use std::cmp::Ordering; /// Verification key for a specific index (i.e., R1CS matrices). diff --git a/algorithms/src/snark/varuna/data_structures/mod.rs b/algorithms/src/snark/varuna/data_structures/mod.rs index 5b13c0c597..52326c4f1f 100644 --- a/algorithms/src/snark/varuna/data_structures/mod.rs +++ b/algorithms/src/snark/varuna/data_structures/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/snark/varuna/data_structures/proof.rs b/algorithms/src/snark/varuna/data_structures/proof.rs index 7ebc495714..d2c4c9c831 100644 --- a/algorithms/src/snark/varuna/data_structures/proof.rs +++ b/algorithms/src/snark/varuna/data_structures/proof.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,20 +14,20 @@ // limitations under the License. use crate::{ - polycommit::sonic_pc, - snark::varuna::{ahp, CircuitId}, SNARKError, + polycommit::sonic_pc, + snark::varuna::{CircuitId, ahp}, }; use ahp::prover::{FourthMessage, ThirdMessage}; use snarkvm_curves::PairingEngine; use snarkvm_fields::PrimeField; use snarkvm_utilities::{ + FromBytes, + ToBytes, error, io::{self, Read, Write}, serialize::*, - FromBytes, - ToBytes, }; use std::collections::BTreeMap; @@ -255,6 +256,10 @@ impl Proof { Ok(Self { batch_sizes, commitments, evaluations, third_msg, fourth_msg, pc_proof }) } + pub fn is_hiding(&self) -> bool { + self.pc_proof.is_hiding() + } + pub fn batch_sizes(&self) -> &[usize] { &self.batch_sizes } @@ -388,8 +393,8 @@ mod test { snark::varuna::prover::MatrixSums, }; use snarkvm_curves::{ - bls12_377::{Bls12_377, Fr, G1Affine}, AffineCurve, + bls12_377::{Bls12_377, Fr, G1Affine}, }; use snarkvm_utilities::{TestRng, Uniform}; diff --git a/algorithms/src/snark/varuna/data_structures/test_circuit.rs b/algorithms/src/snark/varuna/data_structures/test_circuit.rs index e269ef7d46..6f10c2548e 100644 --- a/algorithms/src/snark/varuna/data_structures/test_circuit.rs +++ b/algorithms/src/snark/varuna/data_structures/test_circuit.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -40,6 +41,11 @@ impl core::fmt::Debug for TestCircuit { impl ConstraintSynthesizer for TestCircuit { fn generate_constraints>(&self, cs: &mut CS) -> Result<(), SynthesisError> { + // Ensure the given `cs` is starting off clean. + assert_eq!(1, cs.num_public_variables()); + assert_eq!(0, cs.num_private_variables()); + assert_eq!(0, cs.num_constraints()); + let a = cs.alloc(|| "a", || self.a.ok_or(SynthesisError::AssignmentMissing))?; let b = cs.alloc(|| "b", || self.b.ok_or(SynthesisError::AssignmentMissing))?; @@ -91,7 +97,9 @@ impl TestCircuit { num_variables: usize, rng: &mut R, ) -> (Self, Vec) { - let mut public_inputs: Vec = Vec::with_capacity(mul_depth); + let mut public_inputs: Vec = Vec::with_capacity(1 + mul_depth); + public_inputs.push(F::one()); + let a = F::rand(rng); let b = F::rand(rng); @@ -114,7 +122,8 @@ impl TestCircuit { num_constraints: usize, num_variables: usize, ) -> (Self, Vec) { - let mut public_inputs: Vec = Vec::with_capacity(mul_depth); + let mut public_inputs: Vec = Vec::with_capacity(1 + mul_depth); + public_inputs.push(F::one()); let a = F::from(a); let b = F::from(b); for j in 1..(mul_depth + 1) { diff --git a/algorithms/src/snark/varuna/mod.rs b/algorithms/src/snark/varuna/mod.rs index 0e16caae80..59ea76f9bd 100644 --- a/algorithms/src/snark/varuna/mod.rs +++ b/algorithms/src/snark/varuna/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/snark/varuna/mode.rs b/algorithms/src/snark/varuna/mode.rs index f5fd98680e..ef982e526f 100644 --- a/algorithms/src/snark/varuna/mode.rs +++ b/algorithms/src/snark/varuna/mode.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/snark/varuna/tests.rs b/algorithms/src/snark/varuna/tests.rs index 2d2f20bccb..ef8fe24049 100644 --- a/algorithms/src/snark/varuna/tests.rs +++ b/algorithms/src/snark/varuna/tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,22 +17,23 @@ mod varuna { use crate::{ snark::varuna::{ - mode::SNARKMode, - test_circuit::TestCircuit, AHPForR1CS, CircuitVerifyingKey, VarunaHidingMode, VarunaNonHidingMode, VarunaSNARK, + mode::SNARKMode, + test_circuit::TestCircuit, }, traits::{AlgebraicSponge, SNARK}, }; + use std::collections::BTreeMap; use snarkvm_curves::bls12_377::{Bls12_377, Fq, Fr}; use snarkvm_utilities::{ - rand::{TestRng, Uniform}, ToBytes, + rand::{TestRng, Uniform}, }; type FS = crate::crypto_hash::PoseidonSponge; @@ -57,6 +59,8 @@ mod varuna { let mul_depth = 1; println!("running test with SM::ZK: {}, mul_depth: {}, num_constraints: {}, num_variables: {}", $snark_mode::ZK, mul_depth + i, num_constraints + i, num_variables + i); let (circ, public_inputs) = TestCircuit::gen_rand(mul_depth + i, num_constraints + i, num_variables + i, rng); + let mut fake_inputs = public_inputs.clone(); + fake_inputs[public_inputs.len() - 1] = random; let (index_pk, index_vk) = $snark_inst::circuit_setup(&universal_srs, &circ).unwrap(); println!("Called circuit setup"); @@ -76,7 +80,7 @@ mod varuna { assert!($snark_inst::verify(universal_verifier, &fs_parameters, &index_vk, public_inputs, &proof).unwrap()); println!("Called verifier"); eprintln!("\nShould not verify (i.e. verifier messages should print below):"); - assert!(!$snark_inst::verify(universal_verifier, &fs_parameters, &index_vk, [random, random], &proof).unwrap()); + assert!(!$snark_inst::verify(universal_verifier, &fs_parameters, &index_vk, fake_inputs, &proof).unwrap()); } for circuit_batch_size in (0..4).map(|i| 2usize.pow(i)) { @@ -129,7 +133,8 @@ mod varuna { for instance_input in vks_to_inputs.values() { let mut fake_instance_input = Vec::with_capacity(instance_input.len()); for input in instance_input.iter() { - let fake_input: Vec<_> = (0..input.len()).map(|_| Fr::rand(rng)).collect(); + let mut fake_input = input.clone(); + fake_input[input.len() - 1] = Fr::rand(rng); fake_instance_input.push(fake_input); } fake_instance_inputs.push(fake_instance_input); @@ -300,19 +305,19 @@ mod varuna_hiding { use crate::{ crypto_hash::PoseidonSponge, snark::varuna::{ - ahp::AHPForR1CS, - test_circuit::TestCircuit, CircuitVerifyingKey, VarunaHidingMode, VarunaSNARK, + ahp::AHPForR1CS, + test_circuit::TestCircuit, }, traits::{AlgebraicSponge, SNARK}, }; use snarkvm_curves::bls12_377::{Bls12_377, Fq, Fr}; use snarkvm_utilities::{ - rand::{TestRng, Uniform}, FromBytes, ToBytes, + rand::{TestRng, Uniform}, }; use std::str::FromStr; @@ -332,6 +337,8 @@ mod varuna_hiding { for _ in 0..num_times { let mul_depth = 2; let (circuit, public_inputs) = TestCircuit::gen_rand(mul_depth, num_constraints, num_variables, rng); + let mut fake_inputs = public_inputs.clone(); + fake_inputs[public_inputs.len() - 1] = Fr::rand(rng); let (index_pk, index_vk) = VarunaInst::circuit_setup(&universal_srs, &circuit).unwrap(); println!("Called circuit setup"); @@ -342,16 +349,7 @@ mod varuna_hiding { assert!(VarunaInst::verify(universal_verifier, &fs_parameters, &index_vk, public_inputs, &proof).unwrap()); println!("Called verifier"); eprintln!("\nShould not verify (i.e. verifier messages should print below):"); - assert!( - !VarunaInst::verify( - universal_verifier, - &fs_parameters, - &index_vk, - [Fr::rand(rng), Fr::rand(rng)], - &proof - ) - .unwrap() - ); + assert!(!VarunaInst::verify(universal_verifier, &fs_parameters, &index_vk, fake_inputs, &proof).unwrap()); } } @@ -535,7 +533,7 @@ mod varuna_hiding { mod varuna_test_vectors { use crate::{ fft::EvaluationDomain, - snark::varuna::{ahp::verifier, AHPForR1CS, TestCircuit, VarunaNonHidingMode, VarunaSNARK}, + snark::varuna::{AHPForR1CS, TestCircuit, VarunaNonHidingMode, VarunaSNARK, ahp::verifier}, traits::snark::SNARK, }; use snarkvm_curves::bls12_377::{Bls12_377, Fq, Fr}; @@ -743,7 +741,8 @@ mod varuna_test_vectors { let non_zero_a_domain = EvaluationDomain::::new(index_pk.circuit.index_info.num_non_zero_a).unwrap(); let non_zero_b_domain = EvaluationDomain::::new(index_pk.circuit.index_info.num_non_zero_b).unwrap(); let non_zero_c_domain = EvaluationDomain::::new(index_pk.circuit.index_info.num_non_zero_c).unwrap(); - let variable_domain = EvaluationDomain::::new(index_pk.circuit.index_info.num_variables).unwrap(); + let variable_domain = + EvaluationDomain::::new(index_pk.circuit.index_info.num_public_and_private_variables).unwrap(); let constraint_domain = EvaluationDomain::::new(index_pk.circuit.index_info.num_constraints).unwrap(); let input_domain = EvaluationDomain::::new(index_pk.circuit.index_info.num_public_inputs).unwrap(); diff --git a/algorithms/src/snark/varuna/varuna.rs b/algorithms/src/snark/varuna/varuna.rs index b4fb57a534..f4fa998a14 100644 --- a/algorithms/src/snark/varuna/varuna.rs +++ b/algorithms/src/snark/varuna/varuna.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,6 +15,9 @@ use super::Certificate; use crate::{ + AlgebraicSponge, + SNARK, + SNARKError, fft::EvaluationDomain, polycommit::sonic_pc::{ Commitment, @@ -26,34 +30,30 @@ use crate::{ }, r1cs::{ConstraintSynthesizer, SynthesisError}, snark::varuna::{ - ahp::{AHPError, AHPForR1CS, CircuitId, EvaluationsProvider}, - proof, - prover, - witness_label, CircuitProvingKey, CircuitVerifyingKey, Proof, SNARKMode, UniversalSRS, + ahp::{AHPError, AHPForR1CS, CircuitId, EvaluationsProvider}, + proof, + prover, + witness_label, }, srs::UniversalVerifier, - AlgebraicSponge, - SNARKError, - SNARK, }; use rand::RngCore; use snarkvm_curves::PairingEngine; use snarkvm_fields::{One, PrimeField, ToConstraintField, Zero}; -use snarkvm_utilities::{to_bytes_le, ToBytes}; +use snarkvm_utilities::{ToBytes, to_bytes_le}; -use anyhow::{anyhow, bail, ensure, Result}; +use anyhow::{Result, anyhow, bail, ensure}; use core::marker::PhantomData; use itertools::Itertools; use rand::{CryptoRng, Rng}; use std::{borrow::Borrow, collections::BTreeMap, ops::Deref, sync::Arc}; use crate::srs::UniversalProver; -#[cfg(not(feature = "std"))] use snarkvm_utilities::println; /// The Varuna proof system. @@ -332,7 +332,7 @@ where /// This is the main entrypoint for creating proofs. /// You can find a specification of the prover algorithm in: - /// https://github.com/AleoHQ/protocol-docs + /// https://github.com/AleoNet/protocol-docs fn prove_batch, R: Rng + CryptoRng>( universal_prover: &Self::UniversalProver, fs_parameters: &Self::FSParameters, @@ -621,7 +621,7 @@ where /// This is the main entrypoint for verifying proofs. /// You can find a specification of the verifier algorithm in: - /// https://github.com/AleoHQ/protocol-docs + /// https://github.com/AleoNet/protocol-docs fn verify_batch>( universal_verifier: &Self::UniversalVerifier, fs_parameters: &Self::FSParameters, @@ -657,9 +657,9 @@ where let mut input_domains = BTreeMap::new(); let mut circuit_infos = BTreeMap::new(); let mut circuit_ids = Vec::with_capacity(keys_to_inputs.len()); - for (vk, public_inputs_i) in keys_to_inputs.iter() { + for (&vk, &public_inputs_i) in keys_to_inputs.iter() { max_num_constraints = max_num_constraints.max(vk.circuit_info.num_constraints); - max_num_variables = max_num_variables.max(vk.circuit_info.num_variables); + max_num_variables = max_num_variables.max(vk.circuit_info.num_public_and_private_variables); let non_zero_domains = AHPForR1CS::<_, SM>::cmp_non_zero_domains(&vk.circuit_info, max_non_zero_domain)?; max_non_zero_domain = non_zero_domains.max_non_zero_domain; @@ -670,17 +670,25 @@ where let input_fields = public_inputs_i .iter() - .map(|input| input.borrow().to_field_elements()) + .map(|input| { + let input = input.borrow().to_field_elements()?; + ensure!(input.len() > 0); + ensure!(input[0] == E::Fr::one()); + if input.len() > input_domain.size() { + bail!(SNARKError::PublicInputSizeMismatch); + } + Ok(input) + }) .collect::, _>>()?; let (padded_public_inputs_i, parsed_public_inputs_i): (Vec<_>, Vec<_>) = { input_fields .iter() .map(|input| { - let mut new_input = Vec::with_capacity((1 + input.len()).max(input_domain.size())); - new_input.push(E::Fr::one()); + let input_len = input.len().max(input_domain.size()); + let mut new_input = Vec::with_capacity(input_len); new_input.extend_from_slice(input); - new_input.resize(input.len().max(input_domain.size()), E::Fr::zero()); + new_input.resize(input_len, E::Fr::zero()); if cfg!(debug_assertions) { println!("Number of padded public variables: {}", new_input.len()); } diff --git a/algorithms/src/srs/mod.rs b/algorithms/src/srs/mod.rs index ac2d48cea8..f8b1fcdde0 100644 --- a/algorithms/src/srs/mod.rs +++ b/algorithms/src/srs/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/srs/universal_prover.rs b/algorithms/src/srs/universal_prover.rs index 057aee80b1..aefbc60778 100644 --- a/algorithms/src/srs/universal_prover.rs +++ b/algorithms/src/srs/universal_prover.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/srs/universal_verifier.rs b/algorithms/src/srs/universal_verifier.rs index cf5e6f27a4..c7481f8d65 100644 --- a/algorithms/src/srs/universal_verifier.rs +++ b/algorithms/src/srs/universal_verifier.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/traits/algebraic_sponge.rs b/algorithms/src/traits/algebraic_sponge.rs index 7cf9025cad..042e9f9e27 100644 --- a/algorithms/src/traits/algebraic_sponge.rs +++ b/algorithms/src/traits/algebraic_sponge.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/traits/mod.rs b/algorithms/src/traits/mod.rs index 0938424081..b27b127327 100644 --- a/algorithms/src/traits/mod.rs +++ b/algorithms/src/traits/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/algorithms/src/traits/snark.rs b/algorithms/src/traits/snark.rs index a5f48c456b..cbf1ea6087 100644 --- a/algorithms/src/traits/snark.rs +++ b/algorithms/src/traits/snark.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{r1cs::ConstraintSynthesizer, AlgebraicSponge}; +use crate::{AlgebraicSponge, r1cs::ConstraintSynthesizer}; use snarkvm_fields::PrimeField; use snarkvm_utilities::{CanonicalDeserialize, CanonicalSerialize, FromBytes, ToBytes}; diff --git a/build.rs b/build.rs index 0f309c6106..8d74d23780 100644 --- a/build.rs +++ b/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/Cargo.toml b/circuit/Cargo.toml index bfc0896c5f..a8b936bf5f 100644 --- a/circuit/Cargo.toml +++ b/circuit/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-circuit" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Circuits for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -25,28 +25,28 @@ edition = "2021" [dependencies.snarkvm-circuit-account] path = "./account" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-algorithms] path = "./algorithms" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-collections] path = "./collections" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-environment] path = "./environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-network] path = "./network" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-program] path = "./program" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types] path = "./types" -version = "=0.16.19" +version = "=1.1.0" diff --git a/circuit/account/Cargo.toml b/circuit/account/Cargo.toml index 8c493b19bc..5ea321f4b3 100644 --- a/circuit/account/Cargo.toml +++ b/circuit/account/Cargo.toml @@ -1,28 +1,30 @@ [package] name = "snarkvm-circuit-account" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Account circuit library for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.console] package = "snarkvm-console-account" path = "../../console/account" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit-algorithms] path = "../algorithms" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-network] path = "../network" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types] path = "../types" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.snarkvm-utilities] path = "../../utilities" diff --git a/circuit/account/build.rs b/circuit/account/build.rs index ff14549b2c..1d0fe74e7c 100644 --- a/circuit/account/build.rs +++ b/circuit/account/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/account/src/compute_key/equal.rs b/circuit/account/src/compute_key/equal.rs index 18be73b2b5..83661d7fcb 100644 --- a/circuit/account/src/compute_key/equal.rs +++ b/circuit/account/src/compute_key/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use super::*; -#[cfg(console)] +#[cfg(feature = "console")] impl Equal for ComputeKey { type Output = Boolean; @@ -66,7 +67,7 @@ impl OutputMode, Output = Boolean>> for Comp } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; @@ -97,12 +98,12 @@ mod tests { console::ComputeKey::try_from(console::PrivateKey::new(rng).unwrap()).unwrap(), ); - CurrentAleo::scope(&format!("{mode_a} {mode_a} {i}"), || { + CurrentAleo::scope(format!("{mode_a} {mode_a} {i}"), || { let equals = a.is_equal(&a); assert!(equals.eject_value()); }); - CurrentAleo::scope(&format!("{mode_a} {mode_b} {i}"), || { + CurrentAleo::scope(format!("{mode_a} {mode_b} {i}"), || { let equals = a.is_equal(&b); assert!(!equals.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); @@ -130,12 +131,12 @@ mod tests { console::ComputeKey::try_from(console::PrivateKey::new(rng).unwrap()).unwrap(), ); - CurrentAleo::scope(&format!("{mode_a} {mode_a} {i}"), || { + CurrentAleo::scope(format!("{mode_a} {mode_a} {i}"), || { let equals = a.is_not_equal(&a); assert!(!equals.eject_value()); }); - CurrentAleo::scope(&format!("{mode_a} {mode_b} {i}"), || { + CurrentAleo::scope(format!("{mode_a} {mode_b} {i}"), || { let equals = a.is_not_equal(&b); assert!(equals.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); diff --git a/circuit/account/src/compute_key/from.rs b/circuit/account/src/compute_key/from.rs index 2cc69ea16e..a3a8557e82 100644 --- a/circuit/account/src/compute_key/from.rs +++ b/circuit/account/src/compute_key/from.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,10 +25,10 @@ impl From<(Group, Group)> for ComputeKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use anyhow::Result; use snarkvm_circuit_network::AleoV0; @@ -49,7 +50,7 @@ mod tests { let pk_sig = Group::new(mode, compute_key.pk_sig()); let pr_sig = Group::new(mode, compute_key.pr_sig()); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = ComputeKey::::from((pk_sig, pr_sig)); assert_eq!(compute_key, candidate.eject_value()); if i > 0 { diff --git a/circuit/account/src/compute_key/from_private_key.rs b/circuit/account/src/compute_key/from_private_key.rs index 26f88c4f0b..e0c7d0aecf 100644 --- a/circuit/account/src/compute_key/from_private_key.rs +++ b/circuit/account/src/compute_key/from_private_key.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -32,10 +33,10 @@ impl ComputeKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use anyhow::Result; @@ -55,7 +56,7 @@ mod tests { // Initialize the private key. let private_key = PrivateKey::::new(mode, private_key); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = ComputeKey::from_private_key(&private_key); assert_eq!(compute_key, candidate.eject_value()); // TODO (howardwu): Resolve skipping the cost count checks for the burn-in round. diff --git a/circuit/account/src/compute_key/helpers/from_bits.rs b/circuit/account/src/compute_key/helpers/from_bits.rs index ada16ba6e7..0e8c0b6466 100644 --- a/circuit/account/src/compute_key/helpers/from_bits.rs +++ b/circuit/account/src/compute_key/helpers/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use super::*; -#[cfg(console)] +#[cfg(feature = "console")] impl FromBits for ComputeKey { type Boolean = Boolean; @@ -53,7 +54,7 @@ impl FromBits for ComputeKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; @@ -72,7 +73,7 @@ mod tests { let expected = console::ComputeKey::try_from(console::PrivateKey::new(rng).unwrap()).unwrap(); let candidate = ComputeKey::::new(mode, expected).to_bits_le(); - CurrentAleo::scope(&format!("{mode} {i}"), || { + CurrentAleo::scope(format!("{mode} {i}"), || { let candidate = ComputeKey::::from_bits_le(&candidate); assert_eq!(expected, candidate.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); @@ -89,7 +90,7 @@ mod tests { let expected = console::ComputeKey::try_from(console::PrivateKey::new(rng).unwrap()).unwrap(); let candidate = ComputeKey::::new(mode, expected).to_bits_be(); - CurrentAleo::scope(&format!("{mode} {i}"), || { + CurrentAleo::scope(format!("{mode} {i}"), || { let candidate = ComputeKey::::from_bits_be(&candidate); assert_eq!(expected, candidate.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); diff --git a/circuit/account/src/compute_key/helpers/mod.rs b/circuit/account/src/compute_key/helpers/mod.rs index 10a4036948..b5a7ea8481 100644 --- a/circuit/account/src/compute_key/helpers/mod.rs +++ b/circuit/account/src/compute_key/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/account/src/compute_key/helpers/to_bits.rs b/circuit/account/src/compute_key/helpers/to_bits.rs index 172b6b1e0c..21fdad5fb7 100644 --- a/circuit/account/src/compute_key/helpers/to_bits.rs +++ b/circuit/account/src/compute_key/helpers/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use super::*; -#[cfg(console)] +#[cfg(feature = "console")] impl ToBits for ComputeKey { type Boolean = Boolean; @@ -29,7 +30,7 @@ impl ToBits for ComputeKey { } } -#[cfg(console)] +#[cfg(feature = "console")] impl ToBits for &ComputeKey { type Boolean = Boolean; @@ -50,7 +51,7 @@ impl ToBits for &ComputeKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; @@ -71,7 +72,7 @@ mod tests { let expected = console::ComputeKey::try_from(console::PrivateKey::new(rng).unwrap()).unwrap(); let candidate = ComputeKey::::new(mode, expected); - CurrentAleo::scope(&format!("{mode} {i}"), || { + CurrentAleo::scope(format!("{mode} {i}"), || { let candidate = candidate.to_bits_le(); assert_eq!(expected_number_of_bits, candidate.len()); @@ -98,7 +99,7 @@ mod tests { let expected = console::ComputeKey::try_from(console::PrivateKey::new(rng).unwrap()).unwrap(); let candidate = ComputeKey::::new(mode, expected); - CurrentAleo::scope(&format!("{mode} {i}"), || { + CurrentAleo::scope(format!("{mode} {i}"), || { let candidate = candidate.to_bits_be(); assert_eq!(expected_number_of_bits, candidate.len()); diff --git a/circuit/account/src/compute_key/helpers/to_fields.rs b/circuit/account/src/compute_key/helpers/to_fields.rs index a292a47f4c..b4281e750f 100644 --- a/circuit/account/src/compute_key/helpers/to_fields.rs +++ b/circuit/account/src/compute_key/helpers/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -23,7 +24,7 @@ impl ToFields for ComputeKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; @@ -44,7 +45,7 @@ mod tests { let expected = console::ComputeKey::try_from(console::PrivateKey::new(rng).unwrap()).unwrap(); let candidate = ComputeKey::::new(mode, expected); - CurrentAleo::scope(&format!("{mode} {i}"), || { + CurrentAleo::scope(format!("{mode} {i}"), || { let candidate = candidate.to_fields(); assert_eq!(candidate.len(), 2); diff --git a/circuit/account/src/compute_key/mod.rs b/circuit/account/src/compute_key/mod.rs index 478e7b1ce6..68a1507253 100644 --- a/circuit/account/src/compute_key/mod.rs +++ b/circuit/account/src/compute_key/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,7 +25,7 @@ use snarkvm_circuit_types::environment::{assert_count, assert_output_mode, asser use crate::PrivateKey; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Address, Boolean, Field, Group, Scalar}; +use snarkvm_circuit_types::{Address, Boolean, Field, Group, Scalar, environment::prelude::*}; #[derive(Clone)] pub struct ComputeKey { @@ -36,7 +37,7 @@ pub struct ComputeKey { sk_prf: Scalar, } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for ComputeKey { type Primitive = console::ComputeKey; @@ -68,7 +69,7 @@ impl ComputeKey { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for ComputeKey { type Primitive = console::ComputeKey; @@ -86,10 +87,10 @@ impl Eject for ComputeKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] pub(crate) mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use anyhow::Result; diff --git a/circuit/account/src/compute_key/ternary.rs b/circuit/account/src/compute_key/ternary.rs index 93867ee829..85128d63e9 100644 --- a/circuit/account/src/compute_key/ternary.rs +++ b/circuit/account/src/compute_key/ternary.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -58,7 +59,7 @@ impl OutputMode, Output = Self>> for C } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; diff --git a/circuit/account/src/compute_key/to_address.rs b/circuit/account/src/compute_key/to_address.rs index c7a0dfd7d1..2d25308bb9 100644 --- a/circuit/account/src/compute_key/to_address.rs +++ b/circuit/account/src/compute_key/to_address.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,10 +25,10 @@ impl ComputeKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use anyhow::Result; @@ -47,7 +48,7 @@ mod tests { // Initialize the compute key. let candidate = ComputeKey::::new(mode, compute_key); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_address(); assert_eq!(*address, candidate.to_group().eject_value()); // TODO (howardwu): Resolve skipping the cost count checks for the burn-in round. diff --git a/circuit/account/src/graph_key/mod.rs b/circuit/account/src/graph_key/mod.rs index d464180843..2f357682f9 100644 --- a/circuit/account/src/graph_key/mod.rs +++ b/circuit/account/src/graph_key/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,14 +17,14 @@ use snarkvm_circuit_types::environment::assert_scope; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Field}; +use snarkvm_circuit_types::{Field, environment::prelude::*}; pub struct GraphKey { /// The graph key `sk_tag` := Hash(view_key || ctr). sk_tag: Field, } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for GraphKey { type Primitive = console::GraphKey; @@ -43,7 +44,7 @@ impl GraphKey { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for GraphKey { type Primitive = console::GraphKey; @@ -61,10 +62,10 @@ impl Eject for GraphKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] pub(crate) mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use anyhow::Result; diff --git a/circuit/account/src/lib.rs b/circuit/account/src/lib.rs index 5b912dc4b4..836f7248e6 100644 --- a/circuit/account/src/lib.rs +++ b/circuit/account/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -33,7 +34,7 @@ pub use signature::*; pub mod view_key; pub use view_key::*; -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] pub(crate) mod helpers { use snarkvm_circuit_network::AleoV0; use snarkvm_circuit_types::environment::Environment; diff --git a/circuit/account/src/private_key/mod.rs b/circuit/account/src/private_key/mod.rs index 28376d742d..58c6890e18 100644 --- a/circuit/account/src/private_key/mod.rs +++ b/circuit/account/src/private_key/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,7 +21,7 @@ use snarkvm_circuit_types::environment::assert_scope; use crate::{ComputeKey, ViewKey}; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Scalar}; +use snarkvm_circuit_types::{Scalar, environment::prelude::*}; pub struct PrivateKey { /// The signature secret key. @@ -29,7 +30,7 @@ pub struct PrivateKey { r_sig: Scalar, } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for PrivateKey { type Primitive = console::PrivateKey; @@ -51,7 +52,7 @@ impl PrivateKey { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for PrivateKey { type Primitive = (console::Scalar, console::Scalar); @@ -66,10 +67,10 @@ impl Eject for PrivateKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use anyhow::Result; diff --git a/circuit/account/src/private_key/to_compute_key.rs b/circuit/account/src/private_key/to_compute_key.rs index 2d1f2efd81..2150da9191 100644 --- a/circuit/account/src/private_key/to_compute_key.rs +++ b/circuit/account/src/private_key/to_compute_key.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,10 +22,10 @@ impl PrivateKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use anyhow::Result; @@ -44,7 +45,7 @@ mod tests { // Initialize the private key. let candidate = PrivateKey::::new(mode, private_key); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_compute_key(); assert_eq!(compute_key, candidate.eject_value()); // TODO (howardwu): Resolve skipping the cost count checks for the burn-in round. diff --git a/circuit/account/src/private_key/to_view_key.rs b/circuit/account/src/private_key/to_view_key.rs index cb0170b30e..5544a769da 100644 --- a/circuit/account/src/private_key/to_view_key.rs +++ b/circuit/account/src/private_key/to_view_key.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,10 +22,10 @@ impl PrivateKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use anyhow::Result; @@ -44,7 +45,7 @@ mod tests { // Initialize the private key. let candidate = PrivateKey::::new(mode, private_key); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_view_key(); assert_eq!(view_key, candidate.eject_value()); // TODO (howardwu): Resolve skipping the cost count checks for the burn-in round. diff --git a/circuit/account/src/signature/equal.rs b/circuit/account/src/signature/equal.rs index f85dab3dda..b4da29cfe7 100644 --- a/circuit/account/src/signature/equal.rs +++ b/circuit/account/src/signature/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use super::*; -#[cfg(console)] +#[cfg(feature = "console")] impl Equal for Signature { type Output = Boolean; @@ -66,7 +67,7 @@ impl OutputMode, Output = Boolean>> for Signa } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; @@ -91,12 +92,12 @@ mod tests { let a = Signature::::new(mode_a, crate::helpers::generate_signature(i, rng)); let b = Signature::::new(mode_b, crate::helpers::generate_signature(i, rng)); - CurrentAleo::scope(&format!("{mode_a} {mode_a} {i}"), || { + CurrentAleo::scope(format!("{mode_a} {mode_a} {i}"), || { let equals = a.is_equal(&a); assert!(equals.eject_value()); }); - CurrentAleo::scope(&format!("{mode_a} {mode_b} {i}"), || { + CurrentAleo::scope(format!("{mode_a} {mode_b} {i}"), || { let equals = a.is_equal(&b); assert!(!equals.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); @@ -118,12 +119,12 @@ mod tests { let a = Signature::::new(mode_a, crate::helpers::generate_signature(i, rng)); let b = Signature::::new(mode_b, crate::helpers::generate_signature(i, rng)); - CurrentAleo::scope(&format!("{mode_a} {mode_a} {i}"), || { + CurrentAleo::scope(format!("{mode_a} {mode_a} {i}"), || { let equals = a.is_not_equal(&a); assert!(!equals.eject_value()); }); - CurrentAleo::scope(&format!("{mode_a} {mode_b} {i}"), || { + CurrentAleo::scope(format!("{mode_a} {mode_b} {i}"), || { let equals = a.is_not_equal(&b); assert!(equals.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); diff --git a/circuit/account/src/signature/helpers/from_bits.rs b/circuit/account/src/signature/helpers/from_bits.rs index 04e028231f..1d8d8737d6 100644 --- a/circuit/account/src/signature/helpers/from_bits.rs +++ b/circuit/account/src/signature/helpers/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use super::*; -#[cfg(console)] +#[cfg(feature = "console")] impl FromBits for Signature { type Boolean = Boolean; @@ -71,7 +72,7 @@ impl FromBits for Signature { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; @@ -90,7 +91,7 @@ mod tests { let expected = crate::helpers::generate_signature(i, rng); let candidate = Signature::::new(mode, expected).to_bits_le(); - CurrentAleo::scope(&format!("{mode} {i}"), || { + CurrentAleo::scope(format!("{mode} {i}"), || { let candidate = Signature::::from_bits_le(&candidate); assert_eq!(expected, candidate.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); @@ -107,7 +108,7 @@ mod tests { let expected = crate::helpers::generate_signature(i, rng); let candidate = Signature::::new(mode, expected).to_bits_be(); - CurrentAleo::scope(&format!("{mode} {i}"), || { + CurrentAleo::scope(format!("{mode} {i}"), || { let candidate = Signature::::from_bits_be(&candidate); assert_eq!(expected, candidate.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); diff --git a/circuit/account/src/signature/helpers/mod.rs b/circuit/account/src/signature/helpers/mod.rs index 10a4036948..b5a7ea8481 100644 --- a/circuit/account/src/signature/helpers/mod.rs +++ b/circuit/account/src/signature/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/account/src/signature/helpers/to_bits.rs b/circuit/account/src/signature/helpers/to_bits.rs index b719a7ac11..d924e0bfa0 100644 --- a/circuit/account/src/signature/helpers/to_bits.rs +++ b/circuit/account/src/signature/helpers/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use super::*; -#[cfg(console)] +#[cfg(feature = "console")] impl ToBits for Signature { type Boolean = Boolean; @@ -29,7 +30,7 @@ impl ToBits for Signature { } } -#[cfg(console)] +#[cfg(feature = "console")] impl ToBits for &Signature { type Boolean = Boolean; @@ -54,7 +55,7 @@ impl ToBits for &Signature { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; @@ -75,7 +76,7 @@ mod tests { let expected = crate::helpers::generate_signature(i, rng); let candidate = Signature::::new(mode, expected); - CurrentAleo::scope(&format!("{mode} {i}"), || { + CurrentAleo::scope(format!("{mode} {i}"), || { let candidate = candidate.to_bits_le(); assert_eq!(expected_number_of_bits, candidate.len()); @@ -103,7 +104,7 @@ mod tests { let expected = crate::helpers::generate_signature(i, rng); let candidate = Signature::::new(mode, expected); - CurrentAleo::scope(&format!("{mode} {i}"), || { + CurrentAleo::scope(format!("{mode} {i}"), || { let candidate = candidate.to_bits_be(); assert_eq!(expected_number_of_bits, candidate.len()); diff --git a/circuit/account/src/signature/helpers/to_fields.rs b/circuit/account/src/signature/helpers/to_fields.rs index aa20d8f9c1..20c945917c 100644 --- a/circuit/account/src/signature/helpers/to_fields.rs +++ b/circuit/account/src/signature/helpers/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use super::*; -#[cfg(console)] +#[cfg(feature = "console")] impl ToFields for Signature { type Field = Field; @@ -26,7 +27,7 @@ impl ToFields for Signature { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; diff --git a/circuit/account/src/signature/mod.rs b/circuit/account/src/signature/mod.rs index 19b02b4c26..8583113a48 100644 --- a/circuit/account/src/signature/mod.rs +++ b/circuit/account/src/signature/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -22,7 +23,7 @@ use snarkvm_circuit_types::environment::{assert_count, assert_output_mode, asser use crate::ComputeKey; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Address, Boolean, Field, Scalar}; +use snarkvm_circuit_types::{Address, Boolean, Field, Scalar, environment::prelude::*}; #[derive(Clone)] pub struct Signature { @@ -34,7 +35,7 @@ pub struct Signature { compute_key: ComputeKey, } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Signature { type Primitive = console::Signature; @@ -65,7 +66,7 @@ impl Signature { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Signature { type Primitive = console::Signature; @@ -80,7 +81,7 @@ impl Eject for Signature { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Parser for Signature { /// Parses a string into a signature circuit. #[inline] @@ -97,7 +98,7 @@ impl Parser for Signature { } } -#[cfg(console)] +#[cfg(feature = "console")] impl FromStr for Signature { type Err = Error; @@ -116,7 +117,7 @@ impl FromStr for Signature { } } -#[cfg(console)] +#[cfg(feature = "console")] impl TypeName for Signature { /// Returns the type name of the circuit as a string. #[inline] @@ -125,24 +126,24 @@ impl TypeName for Signature { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Debug for Signature { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(self, f) } } -#[cfg(console)] +#[cfg(feature = "console")] impl Display for Signature { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}.{}", self.eject_value(), self.eject_mode()) } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use snarkvm_utilities::{TestRng, Uniform}; use anyhow::Result; diff --git a/circuit/account/src/signature/ternary.rs b/circuit/account/src/signature/ternary.rs index ec05c19753..2fdf9b6e20 100644 --- a/circuit/account/src/signature/ternary.rs +++ b/circuit/account/src/signature/ternary.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -28,16 +29,6 @@ impl Ternary for Signature { } } -impl Ternary for Box> { - type Boolean = Boolean; - type Output = Box>; - - /// Returns `first` if `condition` is `true`, otherwise returns `second`. - fn ternary(condition: &Self::Boolean, first: &Self, second: &Self) -> Self::Output { - Box::new(Signature::ternary(condition, first, second)) - } -} - impl Metrics, Output = Signature>> for Signature { type Case = (Mode, Mode, Mode); @@ -68,7 +59,7 @@ impl OutputMode, Output = Self>> for S } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; diff --git a/circuit/account/src/signature/verify.rs b/circuit/account/src/signature/verify.rs index cdaebe9cdd..1dd98f89e3 100644 --- a/circuit/account/src/signature/verify.rs +++ b/circuit/account/src/signature/verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -41,10 +42,10 @@ impl Signature { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] pub(crate) mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use snarkvm_circuit_types::Group; use snarkvm_utilities::{TestRng, Uniform}; @@ -73,7 +74,7 @@ pub(crate) mod tests { let signature = Signature::::new(mode, signature); let address = Address::new(mode, address); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = signature.verify(&address, &message); assert!(candidate.eject_value()); // TODO (howardwu): Resolve skipping the cost count checks for the burn-in round. @@ -113,7 +114,7 @@ pub(crate) mod tests { let signature = Signature::::new(mode, signature); let address = Address::new(mode, address); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = signature.verify(&address, &message); assert!(candidate.eject_value()); // TODO (howardwu): Resolve skipping the cost count checks for the burn-in round. diff --git a/circuit/account/src/view_key/from_private_key.rs b/circuit/account/src/view_key/from_private_key.rs index 6bd1ddc7ea..d0ab79a4bc 100644 --- a/circuit/account/src/view_key/from_private_key.rs +++ b/circuit/account/src/view_key/from_private_key.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,10 +25,10 @@ impl ViewKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use anyhow::Result; @@ -47,7 +48,7 @@ mod tests { // Initialize the private key. let private_key = PrivateKey::::new(mode, private_key); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = ViewKey::from_private_key(&private_key); assert_eq!(view_key, candidate.eject_value()); // TODO (howardwu): Resolve skipping the cost count checks for the burn-in round. diff --git a/circuit/account/src/view_key/mod.rs b/circuit/account/src/view_key/mod.rs index 9b9f0b87ef..1227ef6f7a 100644 --- a/circuit/account/src/view_key/mod.rs +++ b/circuit/account/src/view_key/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,14 +21,14 @@ use snarkvm_circuit_types::environment::assert_scope; use crate::PrivateKey; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Address, Scalar}; +use snarkvm_circuit_types::{Address, Scalar, environment::prelude::*}; use core::ops::Deref; /// The account view key is able to decrypt records and ciphertext. pub struct ViewKey(Scalar, OnceCell>); -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for ViewKey { type Primitive = console::ViewKey; @@ -37,7 +38,7 @@ impl Inject for ViewKey { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for ViewKey { type Primitive = console::ViewKey; @@ -60,10 +61,10 @@ impl Deref for ViewKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use anyhow::Result; diff --git a/circuit/account/src/view_key/to_address.rs b/circuit/account/src/view_key/to_address.rs index 148bc3e7d9..f4aa01e0a1 100644 --- a/circuit/account/src/view_key/to_address.rs +++ b/circuit/account/src/view_key/to_address.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,10 +22,10 @@ impl ViewKey { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{helpers::generate_account, Circuit}; + use crate::{Circuit, helpers::generate_account}; use anyhow::Result; @@ -44,7 +45,7 @@ mod tests { // Initialize the view key. let candidate = ViewKey::::new(mode, view_key); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_address(); assert_eq!(*address, candidate.to_group().eject_value()); // TODO (howardwu): Resolve skipping the cost count checks for the burn-in round. diff --git a/circuit/algorithms/Cargo.toml b/circuit/algorithms/Cargo.toml index 8749d46f84..1698c5ab8b 100644 --- a/circuit/algorithms/Cargo.toml +++ b/circuit/algorithms/Cargo.toml @@ -1,24 +1,26 @@ [package] name = "snarkvm-circuit-algorithms" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Algorithm circuit library for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.console] package = "snarkvm-console-algorithms" path = "../../console/algorithms" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit-types] path = "../types" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-fields] path = "../../fields" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dev-dependencies.anyhow] diff --git a/circuit/algorithms/build.rs b/circuit/algorithms/build.rs index ff14549b2c..1d0fe74e7c 100644 --- a/circuit/algorithms/build.rs +++ b/circuit/algorithms/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/algorithms/src/bhp/commit.rs b/circuit/algorithms/src/bhp/commit.rs index bb8c7923ca..3d14287636 100644 --- a/circuit/algorithms/src/bhp/commit.rs +++ b/circuit/algorithms/src/bhp/commit.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -25,7 +26,7 @@ impl Commit for BH } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/bhp/commit_uncompressed.rs b/circuit/algorithms/src/bhp/commit_uncompressed.rs index 36e31a25a0..ba79a19055 100644 --- a/circuit/algorithms/src/bhp/commit_uncompressed.rs +++ b/circuit/algorithms/src/bhp/commit_uncompressed.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -35,7 +36,7 @@ impl CommitUncompr } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/bhp/hash.rs b/circuit/algorithms/src/bhp/hash.rs index ad529f5a56..54839026d0 100644 --- a/circuit/algorithms/src/bhp/hash.rs +++ b/circuit/algorithms/src/bhp/hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,7 +25,7 @@ impl Hash for BHP< } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/bhp/hash_uncompressed.rs b/circuit/algorithms/src/bhp/hash_uncompressed.rs index 2bcac4d09a..4179c545e3 100644 --- a/circuit/algorithms/src/bhp/hash_uncompressed.rs +++ b/circuit/algorithms/src/bhp/hash_uncompressed.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -70,7 +71,7 @@ impl HashUncompres } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/bhp/hasher/hash_uncompressed.rs b/circuit/algorithms/src/bhp/hasher/hash_uncompressed.rs index 4783a24d7b..7872933e80 100644 --- a/circuit/algorithms/src/bhp/hasher/hash_uncompressed.rs +++ b/circuit/algorithms/src/bhp/hasher/hash_uncompressed.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -157,7 +158,8 @@ impl HashUncompres // Otherwise, call `montgomery_add` to add to the accumulating sum. Some((sum_x, sum_y)) => { // Sum the new Montgomery point into the accumulating sum. - sum = Some(montgomery_add((sum_x, sum_y), (&montgomery_x, &montgomery_y))); // 3 constraints + sum = Some(montgomery_add((sum_x, sum_y), (&montgomery_x, &montgomery_y))); + // 3 constraints } } }); @@ -168,7 +170,8 @@ impl HashUncompres // Convert the accumulated sum into a point on the twisted Edwards curve. let edwards_x = sum_x.div_unchecked(sum_y); // 1 constraint (`sum_y` is never 0) let edwards_y = (sum_x - &one).div_unchecked(&(sum_x + &one)); // 1 constraint (numerator & denominator are never both 0) - Group::from_xy_coordinates_unchecked(edwards_x, edwards_y) // 0 constraints (this is safe) + Group::from_xy_coordinates_unchecked(edwards_x, edwards_y) + // 0 constraints (this is safe) } None => E::halt("Invalid iteration of BHP detected, a window was not evaluated"), } @@ -177,7 +180,7 @@ impl HashUncompres } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/bhp/hasher/mod.rs b/circuit/algorithms/src/bhp/hasher/mod.rs index 63bee114d3..a79715a29b 100644 --- a/circuit/algorithms/src/bhp/hasher/mod.rs +++ b/circuit/algorithms/src/bhp/hasher/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ mod hash_uncompressed; -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] use snarkvm_circuit_types::environment::assert_scope; use crate::HashUncompressed; @@ -55,7 +56,7 @@ impl BHPHasher Inject for BHPHasher { type Primitive = console::BHP; @@ -99,7 +100,7 @@ impl Inject for BH } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::{Circuit, Eject}; diff --git a/circuit/algorithms/src/bhp/mod.rs b/circuit/algorithms/src/bhp/mod.rs index 6845dd343b..946aecb207 100644 --- a/circuit/algorithms/src/bhp/mod.rs +++ b/circuit/algorithms/src/bhp/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,7 +21,7 @@ mod commit_uncompressed; mod hash; mod hash_uncompressed; -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] use snarkvm_circuit_types::environment::assert_scope; use crate::{Commit, CommitUncompressed, Hash, HashUncompressed}; @@ -59,7 +60,7 @@ pub struct BHP { hasher: BHPHasher, } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for BHP { type Primitive = console::BHP; @@ -84,7 +85,7 @@ impl Inject for BH } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::{Circuit, Eject}; diff --git a/circuit/algorithms/src/elligator2/encode.rs b/circuit/algorithms/src/elligator2/encode.rs index 62db70c64d..2dc4853a62 100644 --- a/circuit/algorithms/src/elligator2/encode.rs +++ b/circuit/algorithms/src/elligator2/encode.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -126,7 +127,7 @@ impl Elligator2 { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/elligator2/mod.rs b/circuit/algorithms/src/elligator2/mod.rs index 270f7f396b..aff5ab78c9 100644 --- a/circuit/algorithms/src/elligator2/mod.rs +++ b/circuit/algorithms/src/elligator2/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ mod encode; -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] use snarkvm_circuit_types::environment::assert_scope; use snarkvm_circuit_types::prelude::*; diff --git a/circuit/algorithms/src/keccak/hash.rs b/circuit/algorithms/src/keccak/hash.rs index 66c9919f63..bee4fa598b 100644 --- a/circuit/algorithms/src/keccak/hash.rs +++ b/circuit/algorithms/src/keccak/hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -281,7 +282,7 @@ impl Keccak = Keccak; diff --git a/circuit/algorithms/src/lib.rs b/circuit/algorithms/src/lib.rs index 8e23ee9f96..8501a008f3 100644 --- a/circuit/algorithms/src/lib.rs +++ b/circuit/algorithms/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/algorithms/src/pedersen/commit.rs b/circuit/algorithms/src/pedersen/commit.rs index 157504b7f2..94bf0ee949 100644 --- a/circuit/algorithms/src/pedersen/commit.rs +++ b/circuit/algorithms/src/pedersen/commit.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -94,7 +95,7 @@ impl } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/pedersen/commit_uncompressed.rs b/circuit/algorithms/src/pedersen/commit_uncompressed.rs index b0f539e069..a38eeceef4 100644 --- a/circuit/algorithms/src/pedersen/commit_uncompressed.rs +++ b/circuit/algorithms/src/pedersen/commit_uncompressed.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -104,7 +105,7 @@ impl } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/pedersen/hash.rs b/circuit/algorithms/src/pedersen/hash.rs index 40027d5f5b..cd10747163 100644 --- a/circuit/algorithms/src/pedersen/hash.rs +++ b/circuit/algorithms/src/pedersen/hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -47,7 +48,7 @@ impl OutputMode, } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/pedersen/hash_uncompressed.rs b/circuit/algorithms/src/pedersen/hash_uncompressed.rs index c9216207ba..1f756efa8f 100644 --- a/circuit/algorithms/src/pedersen/hash_uncompressed.rs +++ b/circuit/algorithms/src/pedersen/hash_uncompressed.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -101,7 +102,7 @@ impl OutputMode { random_base: Vec>, } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Pedersen { type Primitive = console::Pedersen; @@ -55,7 +56,7 @@ impl Inject for Pedersen { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/poseidon/hash.rs b/circuit/algorithms/src/poseidon/hash.rs index 168c566e56..2666ea75ad 100644 --- a/circuit/algorithms/src/poseidon/hash.rs +++ b/circuit/algorithms/src/poseidon/hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,7 +25,7 @@ impl Hash for Poseidon { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/poseidon/hash_many.rs b/circuit/algorithms/src/poseidon/hash_many.rs index d2baf7fcc5..0e5a1ad687 100644 --- a/circuit/algorithms/src/poseidon/hash_many.rs +++ b/circuit/algorithms/src/poseidon/hash_many.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -192,7 +193,7 @@ impl Poseidon { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/poseidon/hash_to_group.rs b/circuit/algorithms/src/poseidon/hash_to_group.rs index 4b526432b7..4176805beb 100644 --- a/circuit/algorithms/src/poseidon/hash_to_group.rs +++ b/circuit/algorithms/src/poseidon/hash_to_group.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -35,7 +36,7 @@ impl HashToGroup for Poseidon { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/poseidon/hash_to_scalar.rs b/circuit/algorithms/src/poseidon/hash_to_scalar.rs index 0de7fef0ad..512dc4ad63 100644 --- a/circuit/algorithms/src/poseidon/hash_to_scalar.rs +++ b/circuit/algorithms/src/poseidon/hash_to_scalar.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -30,7 +31,7 @@ impl HashToScalar for Poseidon { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/poseidon/mod.rs b/circuit/algorithms/src/poseidon/mod.rs index 932413c171..b65115236f 100644 --- a/circuit/algorithms/src/poseidon/mod.rs +++ b/circuit/algorithms/src/poseidon/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,13 +19,13 @@ mod hash_to_group; mod hash_to_scalar; mod prf; -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] use snarkvm_circuit_types::environment::assert_scope; #[cfg(test)] use snarkvm_utilities::{TestRng, Uniform}; use crate::{Elligator2, Hash, HashMany, HashToGroup, HashToScalar, PRF}; -use snarkvm_circuit_types::{environment::prelude::*, Field, Group, Scalar}; +use snarkvm_circuit_types::{Field, Group, Scalar, environment::prelude::*}; /// Poseidon2 is a cryptographic hash function of input rate 2. pub type Poseidon2 = Poseidon; @@ -67,7 +68,7 @@ pub struct Poseidon { mds: Vec>>, } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Poseidon { type Primitive = console::Poseidon; diff --git a/circuit/algorithms/src/poseidon/prf.rs b/circuit/algorithms/src/poseidon/prf.rs index 460a9b0805..292ab181af 100644 --- a/circuit/algorithms/src/poseidon/prf.rs +++ b/circuit/algorithms/src/poseidon/prf.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -31,7 +32,7 @@ impl PRF for Poseidon { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_types::environment::Circuit; diff --git a/circuit/algorithms/src/traits.rs b/circuit/algorithms/src/traits.rs index 85437d05a6..64dcbb98e8 100644 --- a/circuit/algorithms/src/traits.rs +++ b/circuit/algorithms/src/traits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/collections/Cargo.toml b/circuit/collections/Cargo.toml index 6cc949c5b9..48a87019d2 100644 --- a/circuit/collections/Cargo.toml +++ b/circuit/collections/Cargo.toml @@ -1,24 +1,26 @@ [package] name = "snarkvm-circuit-collections" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Collections circuit library for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.console] package = "snarkvm-console-collections" path = "../../console/collections" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit-algorithms] path = "../algorithms" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types] path = "../types" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.snarkvm-circuit-network] path = "../network" diff --git a/circuit/collections/build.rs b/circuit/collections/build.rs index ff14549b2c..1d0fe74e7c 100644 --- a/circuit/collections/build.rs +++ b/circuit/collections/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/collections/src/kary_merkle_tree/helpers/leaf_hash.rs b/circuit/collections/src/kary_merkle_tree/helpers/leaf_hash.rs index b60c2b4931..5a05eda3da 100644 --- a/circuit/collections/src/kary_merkle_tree/helpers/leaf_hash.rs +++ b/circuit/collections/src/kary_merkle_tree/helpers/leaf_hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use super::*; -use snarkvm_circuit_algorithms::{Hash, Keccak, Poseidon, BHP}; +use snarkvm_circuit_algorithms::{BHP, Hash, Keccak, Poseidon}; /// A trait for a Merkle leaf hash function. pub trait LeafHash { @@ -73,10 +74,10 @@ impl LeafHash for Keccak Default for BooleanHash { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for BooleanHash { type Primitive = console::kary_merkle_tree::BooleanHash; @@ -47,7 +48,7 @@ impl Inject for BooleanHash { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for BooleanHash { type Primitive = console::kary_merkle_tree::BooleanHash; diff --git a/circuit/collections/src/kary_merkle_tree/helpers/path_hash.rs b/circuit/collections/src/kary_merkle_tree/helpers/path_hash.rs index c2ae5f49f9..1cb44c200e 100644 --- a/circuit/collections/src/kary_merkle_tree/helpers/path_hash.rs +++ b/circuit/collections/src/kary_merkle_tree/helpers/path_hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use super::*; -use snarkvm_circuit_algorithms::{Hash, Keccak, Poseidon, BHP}; +use snarkvm_circuit_algorithms::{BHP, Hash, Keccak, Poseidon}; /// A trait for a Merkle path hash function. pub trait PathHash { @@ -90,10 +91,10 @@ impl PathHash for Kecca } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use snarkvm_circuit_algorithms::{Keccak256, Poseidon2, Sha3_256, BHP512}; + use snarkvm_circuit_algorithms::{BHP512, Keccak256, Poseidon2, Sha3_256}; use snarkvm_circuit_types::environment::Circuit; use snarkvm_utilities::{TestRng, Uniform}; diff --git a/circuit/collections/src/kary_merkle_tree/mod.rs b/circuit/collections/src/kary_merkle_tree/mod.rs index dc43e3e740..dea7af97cf 100644 --- a/circuit/collections/src/kary_merkle_tree/mod.rs +++ b/circuit/collections/src/kary_merkle_tree/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -17,10 +18,10 @@ pub use helpers::{BooleanHash, LeafHash, PathHash}; mod verify; -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] use snarkvm_circuit_types::environment::assert_scope; -use snarkvm_circuit_types::{environment::prelude::*, Boolean, Field, U16, U64}; +use snarkvm_circuit_types::{Boolean, Field, U16, U64, environment::prelude::*}; pub struct KaryMerklePath, const DEPTH: u8, const ARITY: u8> { /// The leaf index for the path. @@ -29,7 +30,7 @@ pub struct KaryMerklePath, const DEPTH: u8, cons siblings: Vec>, } -#[cfg(console)] +#[cfg(feature = "console")] impl, const DEPTH: u8, const ARITY: u8> Inject for KaryMerklePath { type Primitive = console::kary_merkle_tree::KaryMerklePath; @@ -59,7 +60,7 @@ impl, const DEPTH: u8, const ARITY: u8> Inject f } } -#[cfg(console)] +#[cfg(feature = "console")] impl, const DEPTH: u8, const ARITY: u8> Eject for KaryMerklePath { type Primitive = console::kary_merkle_tree::KaryMerklePath; @@ -77,11 +78,11 @@ impl, const DEPTH: u8, const ARITY: u8> Eject fo } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use console::{ - algorithms::{BHP1024 as NativeBHP1024, BHP512 as NativeBHP512}, + algorithms::{BHP512 as NativeBHP512, BHP1024 as NativeBHP1024}, kary_merkle_tree::KaryMerkleTree, }; use snarkvm_circuit_algorithms::BHP512; diff --git a/circuit/collections/src/kary_merkle_tree/verify.rs b/circuit/collections/src/kary_merkle_tree/verify.rs index 613fd80c94..f3e76d5cc0 100644 --- a/circuit/collections/src/kary_merkle_tree/verify.rs +++ b/circuit/collections/src/kary_merkle_tree/verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -102,10 +103,10 @@ impl, const DEPTH: u8, const ARITY: u8> KaryMerk } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use snarkvm_circuit_algorithms::{Keccak256, Poseidon2, Poseidon4, Sha3_256, BHP1024, BHP512}; + use snarkvm_circuit_algorithms::{BHP512, BHP1024, Keccak256, Poseidon2, Poseidon4, Sha3_256}; use snarkvm_circuit_types::environment::Circuit; use snarkvm_utilities::{TestRng, Uniform}; diff --git a/circuit/collections/src/lib.rs b/circuit/collections/src/lib.rs index 70e1e74edd..3c72d01606 100644 --- a/circuit/collections/src/lib.rs +++ b/circuit/collections/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/collections/src/merkle_tree/helpers/leaf_hash.rs b/circuit/collections/src/merkle_tree/helpers/leaf_hash.rs index 79f8883af8..1f33c070a7 100644 --- a/circuit/collections/src/merkle_tree/helpers/leaf_hash.rs +++ b/circuit/collections/src/merkle_tree/helpers/leaf_hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use super::*; -use snarkvm_circuit_algorithms::{Hash, Poseidon, BHP}; +use snarkvm_circuit_algorithms::{BHP, Hash, Poseidon}; /// A trait for a Merkle leaf hash function. pub trait LeafHash { @@ -54,10 +55,10 @@ impl LeafHash for Poseidon { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use snarkvm_circuit_algorithms::{Poseidon4, BHP1024}; + use snarkvm_circuit_algorithms::{BHP1024, Poseidon4}; use snarkvm_circuit_types::environment::Circuit; use snarkvm_utilities::{TestRng, Uniform}; diff --git a/circuit/collections/src/merkle_tree/helpers/mod.rs b/circuit/collections/src/merkle_tree/helpers/mod.rs index 9bfbdc3744..25278aadfb 100644 --- a/circuit/collections/src/merkle_tree/helpers/mod.rs +++ b/circuit/collections/src/merkle_tree/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/collections/src/merkle_tree/helpers/path_hash.rs b/circuit/collections/src/merkle_tree/helpers/path_hash.rs index bd5f8578cf..2b90ddff3f 100644 --- a/circuit/collections/src/merkle_tree/helpers/path_hash.rs +++ b/circuit/collections/src/merkle_tree/helpers/path_hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use super::*; -use snarkvm_circuit_algorithms::{Hash, Poseidon, BHP}; +use snarkvm_circuit_algorithms::{BHP, Hash, Poseidon}; /// A trait for a Merkle path hash function. pub trait PathHash { @@ -55,10 +56,10 @@ impl PathHash for Poseidon { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use snarkvm_circuit_algorithms::{Poseidon2, BHP512}; + use snarkvm_circuit_algorithms::{BHP512, Poseidon2}; use snarkvm_circuit_types::environment::Circuit; use snarkvm_utilities::{TestRng, Uniform}; diff --git a/circuit/collections/src/merkle_tree/mod.rs b/circuit/collections/src/merkle_tree/mod.rs index 2c85087b47..2d58338d9f 100644 --- a/circuit/collections/src/merkle_tree/mod.rs +++ b/circuit/collections/src/merkle_tree/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -17,10 +18,10 @@ use helpers::{LeafHash, PathHash}; mod verify; -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] use snarkvm_circuit_types::environment::assert_scope; -use snarkvm_circuit_types::{environment::prelude::*, Boolean, Field, U64}; +use snarkvm_circuit_types::{Boolean, Field, U64, environment::prelude::*}; pub struct MerklePath { /// The leaf index for the path. @@ -29,7 +30,7 @@ pub struct MerklePath { siblings: Vec>, } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for MerklePath { type Primitive = console::merkle_tree::MerklePath; @@ -48,7 +49,7 @@ impl Inject for MerklePath { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for MerklePath { type Primitive = console::merkle_tree::MerklePath; @@ -66,7 +67,7 @@ impl Eject for MerklePath { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_network::AleoV0 as Circuit; diff --git a/circuit/collections/src/merkle_tree/verify.rs b/circuit/collections/src/merkle_tree/verify.rs index bd36950cbc..1d72a31b11 100644 --- a/circuit/collections/src/merkle_tree/verify.rs +++ b/circuit/collections/src/merkle_tree/verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -55,10 +56,10 @@ impl MerklePath { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use snarkvm_circuit_algorithms::{Poseidon2, Poseidon4, BHP1024, BHP512}; + use snarkvm_circuit_algorithms::{BHP512, BHP1024, Poseidon2, Poseidon4}; use snarkvm_circuit_types::environment::Circuit; use snarkvm_utilities::{TestRng, Uniform}; diff --git a/circuit/environment/Cargo.toml b/circuit/environment/Cargo.toml index 894d81274c..32565fc279 100644 --- a/circuit/environment/Cargo.toml +++ b/circuit/environment/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "snarkvm-circuit-environment" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Circuit environment for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" @@ -14,32 +16,32 @@ harness = false [dependencies.console] package = "snarkvm-console-network" path = "../../console/network" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-algorithms] path = "../../algorithms" -version = "=0.16.19" +version = "=1.1.0" default-features = false features = [ "r1cs" ] [dependencies.snarkvm-circuit-environment-witness] path = "./witness" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-curves] path = "../../curves" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-fields] path = "../../fields" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-utilities] path = "../../utilities" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.indexmap] diff --git a/circuit/environment/benches/linear_combination.rs b/circuit/environment/benches/linear_combination.rs index ca8f7df1d1..bb5b089519 100644 --- a/circuit/environment/benches/linear_combination.rs +++ b/circuit/environment/benches/linear_combination.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,7 +17,7 @@ extern crate criterion; use snarkvm_circuit::{ - environment::{prelude::num_traits::One as _, Circuit, Eject, Environment, Inject, LinearCombination, Mode, One}, + environment::{Circuit, Eject, Environment, Inject, LinearCombination, Mode, One, prelude::num_traits::One as _}, types::Field, }; diff --git a/circuit/environment/src/canary_circuit.rs b/circuit/environment/src/canary_circuit.rs new file mode 100644 index 0000000000..99edef9eba --- /dev/null +++ b/circuit/environment/src/canary_circuit.rs @@ -0,0 +1,410 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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::{Mode, helpers::Constraint, *}; + +use core::{ + cell::{Cell, RefCell}, + fmt, +}; + +type Field = ::Field; + +thread_local! { + static VARIABLE_LIMIT: Cell> = const { Cell::new(None) }; + static CONSTRAINT_LIMIT: Cell> = const { Cell::new(None) }; + pub(super) static CANARY_CIRCUIT: RefCell> = RefCell::new(R1CS::new()); + static IN_WITNESS: Cell = const { Cell::new(false) }; + static ZERO: LinearCombination = LinearCombination::zero(); + static ONE: LinearCombination = LinearCombination::one(); +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub struct CanaryCircuit; + +impl Environment for CanaryCircuit { + type Affine = ::Affine; + type BaseField = Field; + type Network = console::CanaryV0; + type ScalarField = ::Scalar; + + /// Returns the `zero` constant. + fn zero() -> LinearCombination { + ZERO.with(|zero| zero.clone()) + } + + /// Returns the `one` constant. + fn one() -> LinearCombination { + ONE.with(|one| one.clone()) + } + + /// Returns a new variable of the given mode and value. + fn new_variable(mode: Mode, value: Self::BaseField) -> Variable { + IN_WITNESS.with(|in_witness| { + // Ensure we are not in witness mode. + if !in_witness.get() { + // Ensure that we do not surpass the variable limit for the circuit. + VARIABLE_LIMIT.with(|variable_limit| { + if let Some(limit) = variable_limit.get() { + if Self::num_variables() > limit { + Self::halt(format!("Surpassed the variable limit ({limit})")) + } + } + }); + CANARY_CIRCUIT.with(|circuit| match mode { + Mode::Constant => circuit.borrow_mut().new_constant(value), + Mode::Public => circuit.borrow_mut().new_public(value), + Mode::Private => circuit.borrow_mut().new_private(value), + }) + } else { + Self::halt("Tried to initialize a new variable in witness mode") + } + }) + } + + /// Returns a new witness of the given mode and value. + fn new_witness Output::Primitive, Output: Inject>(mode: Mode, logic: Fn) -> Output { + IN_WITNESS.with(|in_witness| { + // Set the entire environment to witness mode. + in_witness.replace(true); + + // Run the logic. + let output = logic(); + + // Return the entire environment from witness mode. + in_witness.replace(false); + + Inject::new(mode, output) + }) + } + + /// Enters a new scope for the environment. + fn scope, Fn, Output>(name: S, logic: Fn) -> Output + where + Fn: FnOnce() -> Output, + { + IN_WITNESS.with(|in_witness| { + // Ensure we are not in witness mode. + if !in_witness.get() { + CANARY_CIRCUIT.with(|circuit| { + // Set the entire environment to the new scope. + let name = name.into(); + if let Err(error) = circuit.borrow_mut().push_scope(&name) { + Self::halt(error) + } + + // Run the logic. + let output = logic(); + + // Return the entire environment to the previous scope. + if let Err(error) = circuit.borrow_mut().pop_scope(name) { + Self::halt(error) + } + + output + }) + } else { + Self::halt("Tried to initialize a new scope in witness mode") + } + }) + } + + /// Adds one constraint enforcing that `(A * B) == C`. + fn enforce(constraint: Fn) + where + Fn: FnOnce() -> (A, B, C), + A: Into>, + B: Into>, + C: Into>, + { + IN_WITNESS.with(|in_witness| { + // Ensure we are not in witness mode. + if !in_witness.get() { + CANARY_CIRCUIT.with(|circuit| { + // Ensure that we do not surpass the constraint limit for the circuit. + CONSTRAINT_LIMIT.with(|constraint_limit| { + if let Some(limit) = constraint_limit.get() { + if circuit.borrow().num_constraints() > limit { + Self::halt(format!("Surpassed the constraint limit ({limit})")) + } + } + }); + + let (a, b, c) = constraint(); + let (a, b, c) = (a.into(), b.into(), c.into()); + + // Ensure the constraint is not comprised of constants. + match a.is_constant() && b.is_constant() && c.is_constant() { + true => { + // Evaluate the constant constraint. + assert_eq!( + a.value() * b.value(), + c.value(), + "Constant constraint failed: ({a} * {b}) =?= {c}" + ); + + // match self.counter.scope().is_empty() { + // true => println!("Enforced constraint with constant terms: ({} * {}) =?= {}", a, b, c), + // false => println!( + // "Enforced constraint with constant terms ({}): ({} * {}) =?= {}", + // self.counter.scope(), a, b, c + // ), + // } + } + false => { + // Construct the constraint object. + let constraint = Constraint(circuit.borrow().scope(), a, b, c); + // Append the constraint. + circuit.borrow_mut().enforce(constraint) + } + } + }); + } else { + Self::halt("Tried to add a new constraint in witness mode") + } + }) + } + + /// Returns `true` if all constraints in the environment are satisfied. + fn is_satisfied() -> bool { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().is_satisfied()) + } + + /// Returns `true` if all constraints in the current scope are satisfied. + fn is_satisfied_in_scope() -> bool { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().is_satisfied_in_scope()) + } + + /// Returns the number of constants in the entire circuit. + fn num_constants() -> u64 { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().num_constants()) + } + + /// Returns the number of public variables in the entire circuit. + fn num_public() -> u64 { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().num_public()) + } + + /// Returns the number of private variables in the entire circuit. + fn num_private() -> u64 { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().num_private()) + } + + /// Returns the number of constant, public, and private variables in the entire circuit. + fn num_variables() -> u64 { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().num_variables()) + } + + /// Returns the number of constraints in the entire circuit. + fn num_constraints() -> u64 { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().num_constraints()) + } + + /// Returns the number of nonzeros in the entire circuit. + fn num_nonzeros() -> (u64, u64, u64) { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().num_nonzeros()) + } + + /// Returns the number of constants for the current scope. + fn num_constants_in_scope() -> u64 { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().num_constants_in_scope()) + } + + /// Returns the number of public variables for the current scope. + fn num_public_in_scope() -> u64 { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().num_public_in_scope()) + } + + /// Returns the number of private variables for the current scope. + fn num_private_in_scope() -> u64 { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().num_private_in_scope()) + } + + /// Returns the number of constraints for the current scope. + fn num_constraints_in_scope() -> u64 { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().num_constraints_in_scope()) + } + + /// Returns the number of nonzeros for the current scope. + fn num_nonzeros_in_scope() -> (u64, u64, u64) { + CANARY_CIRCUIT.with(|circuit| circuit.borrow().num_nonzeros_in_scope()) + } + + /// Returns the variable limit for the circuit, if one exists. + fn get_variable_limit() -> Option { + VARIABLE_LIMIT.with(|current_limit| current_limit.get()) + } + + /// Sets the variable limit for the circuit. + fn set_variable_limit(limit: Option) { + VARIABLE_LIMIT.with(|current_limit| current_limit.replace(limit)); + } + + /// Returns the constraint limit for the circuit, if one exists. + fn get_constraint_limit() -> Option { + CONSTRAINT_LIMIT.with(|current_limit| current_limit.get()) + } + + /// Sets the constraint limit for the circuit. + fn set_constraint_limit(limit: Option) { + CONSTRAINT_LIMIT.with(|current_limit| current_limit.replace(limit)); + } + + /// Halts the program from further synthesis, evaluation, and execution in the current environment. + fn halt, T>(message: S) -> T { + let error = message.into(); + // eprintln!("{}", &error); + panic!("{}", &error) + } + + /// Returns the R1CS circuit, resetting the circuit. + fn inject_r1cs(r1cs: R1CS) { + CANARY_CIRCUIT.with(|circuit| { + // Ensure the circuit is empty before injecting. + assert_eq!(0, circuit.borrow().num_constants()); + assert_eq!(1, circuit.borrow().num_public()); + assert_eq!(0, circuit.borrow().num_private()); + assert_eq!(1, circuit.borrow().num_variables()); + assert_eq!(0, circuit.borrow().num_constraints()); + // Inject the R1CS instance. + let r1cs = circuit.replace(r1cs); + // Ensure the circuit that was replaced is empty. + assert_eq!(0, r1cs.num_constants()); + assert_eq!(1, r1cs.num_public()); + assert_eq!(0, r1cs.num_private()); + assert_eq!(1, r1cs.num_variables()); + assert_eq!(0, r1cs.num_constraints()); + }) + } + + /// Returns the R1CS circuit, resetting the circuit. + fn eject_r1cs_and_reset() -> R1CS { + CANARY_CIRCUIT.with(|circuit| { + // Reset the witness mode. + IN_WITNESS.with(|in_witness| in_witness.replace(false)); + // Reset the variable limit. + Self::set_variable_limit(None); + // Reset the constraint limit. + Self::set_constraint_limit(None); + // Eject the R1CS instance. + let r1cs = circuit.replace(R1CS::<::BaseField>::new()); + // Ensure the circuit is now empty. + assert_eq!(0, circuit.borrow().num_constants()); + assert_eq!(1, circuit.borrow().num_public()); + assert_eq!(0, circuit.borrow().num_private()); + assert_eq!(1, circuit.borrow().num_variables()); + assert_eq!(0, circuit.borrow().num_constraints()); + // Return the R1CS instance. + r1cs + }) + } + + /// Returns the R1CS assignment of the circuit, resetting the circuit. + fn eject_assignment_and_reset() -> Assignment<::Field> { + CANARY_CIRCUIT.with(|circuit| { + // Reset the witness mode. + IN_WITNESS.with(|in_witness| in_witness.replace(false)); + // Reset the variable limit. + Self::set_variable_limit(None); + // Reset the constraint limit. + Self::set_constraint_limit(None); + // Eject the R1CS instance. + let r1cs = circuit.replace(R1CS::<::BaseField>::new()); + assert_eq!(0, circuit.borrow().num_constants()); + assert_eq!(1, circuit.borrow().num_public()); + assert_eq!(0, circuit.borrow().num_private()); + assert_eq!(1, circuit.borrow().num_variables()); + assert_eq!(0, circuit.borrow().num_constraints()); + // Convert the R1CS instance to an assignment. + Assignment::from(r1cs) + }) + } + + /// Clears the circuit and initializes an empty environment. + fn reset() { + CANARY_CIRCUIT.with(|circuit| { + // Reset the witness mode. + IN_WITNESS.with(|in_witness| in_witness.replace(false)); + // Reset the variable limit. + Self::set_variable_limit(None); + // Reset the constraint limit. + Self::set_constraint_limit(None); + // Reset the circuit. + *circuit.borrow_mut() = R1CS::<::BaseField>::new(); + assert_eq!(0, circuit.borrow().num_constants()); + assert_eq!(1, circuit.borrow().num_public()); + assert_eq!(0, circuit.borrow().num_private()); + assert_eq!(1, circuit.borrow().num_variables()); + assert_eq!(0, circuit.borrow().num_constraints()); + }); + } +} + +impl fmt::Display for CanaryCircuit { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + CANARY_CIRCUIT.with(|circuit| write!(f, "{}", circuit.borrow())) + } +} + +#[cfg(test)] +mod tests { + use snarkvm_circuit::prelude::*; + + /// Compute 2^EXPONENT - 1, in a purposefully constraint-inefficient manner for testing. + fn create_example_circuit() -> Field { + let one = snarkvm_console_types::Field::::one(); + let two = one + one; + + const EXPONENT: u64 = 64; + + // Compute 2^EXPONENT - 1, in a purposefully constraint-inefficient manner for testing. + let mut candidate = Field::::new(Mode::Public, one); + let mut accumulator = Field::new(Mode::Private, two); + for _ in 0..EXPONENT { + candidate += &accumulator; + accumulator *= Field::new(Mode::Private, two); + } + + assert_eq!((accumulator - Field::one()).eject_value(), candidate.eject_value()); + assert_eq!(2, E::num_public()); + assert_eq!(2 * EXPONENT + 1, E::num_private()); + assert_eq!(EXPONENT, E::num_constraints()); + assert!(E::is_satisfied()); + + candidate + } + + #[test] + fn test_print_circuit() { + let _candidate = create_example_circuit::(); + let output = format!("{CanaryCircuit}"); + println!("{output}"); + } + + #[test] + fn test_circuit_scope() { + CanaryCircuit::scope("test_circuit_scope", || { + assert_eq!(0, CanaryCircuit::num_constants()); + assert_eq!(1, CanaryCircuit::num_public()); + assert_eq!(0, CanaryCircuit::num_private()); + assert_eq!(0, CanaryCircuit::num_constraints()); + + assert_eq!(0, CanaryCircuit::num_constants_in_scope()); + assert_eq!(0, CanaryCircuit::num_public_in_scope()); + assert_eq!(0, CanaryCircuit::num_private_in_scope()); + assert_eq!(0, CanaryCircuit::num_constraints_in_scope()); + }) + } +} diff --git a/circuit/environment/src/circuit.rs b/circuit/environment/src/circuit.rs index be60fe946b..3bf3742a40 100644 --- a/circuit/environment/src/circuit.rs +++ b/circuit/environment/src/circuit.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,30 +13,32 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{helpers::Constraint, Mode, *}; +use crate::{Mode, helpers::Constraint, *}; use core::{ cell::{Cell, RefCell}, fmt, }; -type Field = ::Field; +type Field = ::Field; thread_local! { + static VARIABLE_LIMIT: Cell> = const { Cell::new(None) }; + static CONSTRAINT_LIMIT: Cell> = const { Cell::new(None) }; pub(super) static CIRCUIT: RefCell> = RefCell::new(R1CS::new()); - pub(super) static IN_WITNESS: Cell = Cell::new(false); - pub(super) static ZERO: LinearCombination = LinearCombination::zero(); - pub(super) static ONE: LinearCombination = LinearCombination::one(); + static IN_WITNESS: Cell = const { Cell::new(false) }; + static ZERO: LinearCombination = LinearCombination::zero(); + static ONE: LinearCombination = LinearCombination::one(); } #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub struct Circuit; impl Environment for Circuit { - type Affine = ::Affine; + type Affine = ::Affine; type BaseField = Field; - type Network = console::Testnet3; - type ScalarField = ::Scalar; + type Network = console::MainnetV0; + type ScalarField = ::Scalar; /// Returns the `zero` constant. fn zero() -> LinearCombination { @@ -52,6 +55,14 @@ impl Environment for Circuit { IN_WITNESS.with(|in_witness| { // Ensure we are not in witness mode. if !in_witness.get() { + // Ensure that we do not surpass the variable limit for the circuit. + VARIABLE_LIMIT.with(|variable_limit| { + if let Some(limit) = variable_limit.get() { + if Self::num_variables() > limit { + Self::halt(format!("Surpassed the variable limit ({limit})")) + } + } + }); CIRCUIT.with(|circuit| match mode { Mode::Constant => circuit.borrow_mut().new_constant(value), Mode::Public => circuit.borrow_mut().new_public(value), @@ -146,6 +157,15 @@ impl Environment for Circuit { // Ensure we are not in witness mode. if !in_witness.get() { CIRCUIT.with(|circuit| { + // Ensure that we do not surpass the constraint limit for the circuit. + CONSTRAINT_LIMIT.with(|constraint_limit| { + if let Some(limit) = constraint_limit.get() { + if circuit.borrow().num_constraints() > limit { + Self::halt(format!("Surpassed the constraint limit ({limit})")) + } + } + }); + let (a, b, c) = constraint(); let (a, b, c) = (a.into(), b.into(), c.into()); @@ -206,6 +226,11 @@ impl Environment for Circuit { CIRCUIT.with(|circuit| circuit.borrow().num_private()) } + /// Returns the number of constant, public, and private variables in the entire circuit. + fn num_variables() -> u64 { + CIRCUIT.with(|circuit| circuit.borrow().num_variables()) + } + /// Returns the number of constraints in the entire circuit. fn num_constraints() -> u64 { CIRCUIT.with(|circuit| circuit.borrow().num_constraints()) @@ -241,6 +266,26 @@ impl Environment for Circuit { CIRCUIT.with(|circuit| circuit.borrow().num_nonzeros_in_scope()) } + /// Returns the variable limit for the circuit, if one exists. + fn get_variable_limit() -> Option { + VARIABLE_LIMIT.with(|current_limit| current_limit.get()) + } + + /// Sets the variable limit for the circuit. + fn set_variable_limit(limit: Option) { + VARIABLE_LIMIT.with(|current_limit| current_limit.replace(limit)); + } + + /// Returns the constraint limit for the circuit, if one exists. + fn get_constraint_limit() -> Option { + CONSTRAINT_LIMIT.with(|current_limit| current_limit.get()) + } + + /// Sets the constraint limit for the circuit. + fn set_constraint_limit(limit: Option) { + CONSTRAINT_LIMIT.with(|current_limit| current_limit.replace(limit)); + } + /// Halts the program from further synthesis, evaluation, and execution in the current environment. fn halt, T>(message: S) -> T { let error = message.into(); @@ -248,8 +293,6 @@ impl Environment for Circuit { panic!("{}", &error) } - /// TODO (howardwu): Abstraction - Refactor this into an appropriate design. - /// Circuits should not have easy access to this during synthesis. /// Returns the R1CS circuit, resetting the circuit. fn inject_r1cs(r1cs: R1CS) { CIRCUIT.with(|circuit| { @@ -257,6 +300,7 @@ impl Environment for Circuit { assert_eq!(0, circuit.borrow().num_constants()); assert_eq!(1, circuit.borrow().num_public()); assert_eq!(0, circuit.borrow().num_private()); + assert_eq!(1, circuit.borrow().num_variables()); assert_eq!(0, circuit.borrow().num_constraints()); // Inject the R1CS instance. let r1cs = circuit.replace(r1cs); @@ -264,41 +308,48 @@ impl Environment for Circuit { assert_eq!(0, r1cs.num_constants()); assert_eq!(1, r1cs.num_public()); assert_eq!(0, r1cs.num_private()); + assert_eq!(1, r1cs.num_variables()); assert_eq!(0, r1cs.num_constraints()); }) } - /// TODO (howardwu): Abstraction - Refactor this into an appropriate design. - /// Circuits should not have easy access to this during synthesis. /// Returns the R1CS circuit, resetting the circuit. fn eject_r1cs_and_reset() -> R1CS { CIRCUIT.with(|circuit| { // Reset the witness mode. IN_WITNESS.with(|in_witness| in_witness.replace(false)); + // Reset the variable limit. + Self::set_variable_limit(None); + // Reset the constraint limit. + Self::set_constraint_limit(None); // Eject the R1CS instance. let r1cs = circuit.replace(R1CS::<::BaseField>::new()); // Ensure the circuit is now empty. assert_eq!(0, circuit.borrow().num_constants()); assert_eq!(1, circuit.borrow().num_public()); assert_eq!(0, circuit.borrow().num_private()); + assert_eq!(1, circuit.borrow().num_variables()); assert_eq!(0, circuit.borrow().num_constraints()); // Return the R1CS instance. r1cs }) } - /// TODO (howardwu): Abstraction - Refactor this into an appropriate design. - /// Circuits should not have easy access to this during synthesis. /// Returns the R1CS assignment of the circuit, resetting the circuit. fn eject_assignment_and_reset() -> Assignment<::Field> { CIRCUIT.with(|circuit| { // Reset the witness mode. IN_WITNESS.with(|in_witness| in_witness.replace(false)); + // Reset the variable limit. + Self::set_variable_limit(None); + // Reset the constraint limit. + Self::set_constraint_limit(None); // Eject the R1CS instance. let r1cs = circuit.replace(R1CS::<::BaseField>::new()); assert_eq!(0, circuit.borrow().num_constants()); assert_eq!(1, circuit.borrow().num_public()); assert_eq!(0, circuit.borrow().num_private()); + assert_eq!(1, circuit.borrow().num_variables()); assert_eq!(0, circuit.borrow().num_constraints()); // Convert the R1CS instance to an assignment. Assignment::from(r1cs) @@ -310,10 +361,16 @@ impl Environment for Circuit { CIRCUIT.with(|circuit| { // Reset the witness mode. IN_WITNESS.with(|in_witness| in_witness.replace(false)); + // Reset the variable limit. + Self::set_variable_limit(None); + // Reset the constraint limit. + Self::set_constraint_limit(None); + // Reset the circuit. *circuit.borrow_mut() = R1CS::<::BaseField>::new(); assert_eq!(0, circuit.borrow().num_constants()); assert_eq!(1, circuit.borrow().num_public()); assert_eq!(0, circuit.borrow().num_private()); + assert_eq!(1, circuit.borrow().num_variables()); assert_eq!(0, circuit.borrow().num_constraints()); }); } diff --git a/circuit/environment/src/environment.rs b/circuit/environment/src/environment.rs index 34ef4370ea..f58fd7d7ea 100644 --- a/circuit/environment/src/environment.rs +++ b/circuit/environment/src/environment.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,12 +13,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{witness_mode, Assignment, Inject, LinearCombination, Mode, Variable, R1CS}; +use crate::{Assignment, Inject, LinearCombination, Mode, R1CS, Variable, witness_mode}; use snarkvm_curves::AffineCurve; use snarkvm_fields::traits::*; use core::{fmt, hash}; +/// Attention: Do not use `Send + Sync` on this trait, as it is not thread-safe. pub trait Environment: 'static + Copy + Clone + fmt::Debug + fmt::Display + Eq + PartialEq + hash::Hash { type Network: console::Network; @@ -118,6 +120,9 @@ pub trait Environment: 'static + Copy + Clone + fmt::Debug + fmt::Display + Eq + /// Returns the number of private variables in the entire environment. fn num_private() -> u64; + /// Returns the number of constant, public, and private variables in the entire environment. + fn num_variables() -> u64; + /// Returns the number of constraints in the entire environment. fn num_constraints() -> u64; @@ -155,6 +160,18 @@ pub trait Environment: 'static + Copy + Clone + fmt::Debug + fmt::Display + Eq + ) } + /// Returns the variable limit for the circuit, if one exists. + fn get_variable_limit() -> Option; + + /// Sets the variable limit for the circuit. + fn set_variable_limit(limit: Option); + + /// Returns the constraint limit for the circuit, if one exists. + fn get_constraint_limit() -> Option; + + /// Sets the constraint limit for the circuit. + fn set_constraint_limit(limit: Option); + /// Halts the program from further synthesis, evaluation, and execution in the current environment. fn halt, T>(message: S) -> T { ::halt(message) diff --git a/circuit/environment/src/helpers/assignment.rs b/circuit/environment/src/helpers/assignment.rs index c9f51c7c95..d8181dbdad 100644 --- a/circuit/environment/src/helpers/assignment.rs +++ b/circuit/environment/src/helpers/assignment.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -85,9 +86,14 @@ impl AssignmentLC { /// and constraint assignments. #[derive(Clone, Debug)] pub struct Assignment { + /// The public variables. public: Arc<[(Index, F)]>, + /// The private variables. private: Arc<[(Index, F)]>, + /// The constraints. constraints: Arc<[(AssignmentLC, AssignmentLC, AssignmentLC)]>, + /// The number of constants, public, and private variables in the assignment. + num_variables: u64, } impl From> for Assignment { @@ -104,6 +110,7 @@ impl From> for Assignment { let (a, b, c) = constraint.to_terms(); (a.into(), b.into(), c.into()) })), + num_variables: r1cs.num_variables(), } } } @@ -134,6 +141,11 @@ impl Assignment { self.private.len() as u64 } + /// Returns the number of constants, public, and private variables in the assignment. + pub fn num_variables(&self) -> u64 { + self.num_variables + } + /// Returns the number of constraints in the assignment. pub fn num_constraints(&self) -> u64 { self.constraints.len() as u64 @@ -167,14 +179,18 @@ impl snarkvm_algorithms::r1cs::ConstraintSynthesizer for Assig assert_eq!(0, cs.num_private_variables()); assert_eq!(0, cs.num_constraints()); + let result = converter.public.insert(0, CS::one()); + assert!(result.is_none(), "Overwrote an existing public variable in the converter"); + // Allocate the public variables. - for (i, (index, value)) in self.public.iter().enumerate() { - assert_eq!(i as u64, *index, "Public variables in first system must be processed in lexicographic order"); + // NOTE: we skip the first public `One` variable because we already allocated it in the `ConstraintSystem` constructor. + for (i, (index, value)) in self.public.iter().skip(1).enumerate() { + assert_eq!((i + 1) as u64, *index, "Public vars in first system must be processed in lexicographic order"); let gadget = cs.alloc_input(|| format!("Public {i}"), || Ok(*value))?; assert_eq!( - snarkvm_algorithms::r1cs::Index::Public((index + 1) as usize), + snarkvm_algorithms::r1cs::Index::Public(*index as usize), gadget.get_unchecked(), "Public variables in the second system must match the first system (with an off-by-1 for the public case)" ); @@ -219,7 +235,7 @@ impl snarkvm_algorithms::r1cs::ConstraintSynthesizer for Assig AssignmentVariable::Public(index) => { let gadget = converter.public.get(index).unwrap(); assert_eq!( - snarkvm_algorithms::r1cs::Index::Public((index + 1) as usize), + snarkvm_algorithms::r1cs::Index::Public(*index as usize), gadget.get_unchecked(), "Failed during constraint translation. The public variable in the second system must match the first system (with an off-by-1 for the public case)" ); @@ -258,7 +274,7 @@ impl snarkvm_algorithms::r1cs::ConstraintSynthesizer for Assig } // Ensure the given `cs` matches in size with the first system. - assert_eq!(self.num_public() + 1, cs.num_public_variables() as u64); + assert_eq!(self.num_public(), cs.num_public_variables() as u64); assert_eq!(self.num_private(), cs.num_private_variables() as u64); assert_eq!(self.num_constraints(), cs.num_constraints() as u64); @@ -268,7 +284,7 @@ impl snarkvm_algorithms::r1cs::ConstraintSynthesizer for Assig #[cfg(test)] mod tests { - use snarkvm_algorithms::{r1cs::ConstraintSynthesizer, AlgebraicSponge, SNARK}; + use snarkvm_algorithms::{AlgebraicSponge, SNARK, r1cs::ConstraintSynthesizer}; use snarkvm_circuit::prelude::*; use snarkvm_curves::bls12_377::Fr; @@ -309,7 +325,7 @@ mod tests { assignment.generate_constraints(&mut cs).unwrap(); { use snarkvm_algorithms::r1cs::ConstraintSystem; - assert_eq!(assignment.num_public() + 1, cs.num_public_variables() as u64); + assert_eq!(assignment.num_public(), cs.num_public_variables() as u64); assert_eq!(assignment.num_private(), cs.num_private_variables() as u64); assert_eq!(assignment.num_constraints(), cs.num_constraints() as u64); assert!(cs.is_satisfied()); @@ -329,7 +345,7 @@ mod tests { use snarkvm_algorithms::{ crypto_hash::PoseidonSponge, - snark::varuna::{ahp::AHPForR1CS, VarunaHidingMode, VarunaSNARK}, + snark::varuna::{VarunaHidingMode, VarunaSNARK, ahp::AHPForR1CS}, }; use snarkvm_curves::bls12_377::{Bls12_377, Fq}; use snarkvm_utilities::rand::TestRng; diff --git a/circuit/environment/src/helpers/circuit_type.rs b/circuit/environment/src/helpers/circuit_type.rs index 7f66a26514..ee3603c1e1 100644 --- a/circuit/environment/src/helpers/circuit_type.rs +++ b/circuit/environment/src/helpers/circuit_type.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/helpers/constraint.rs b/circuit/environment/src/helpers/constraint.rs index f3ee765b2d..5dad958730 100644 --- a/circuit/environment/src/helpers/constraint.rs +++ b/circuit/environment/src/helpers/constraint.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/helpers/converter.rs b/circuit/environment/src/helpers/converter.rs index 2466c5954d..f404d17078 100644 --- a/circuit/environment/src/helpers/converter.rs +++ b/circuit/environment/src/helpers/converter.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{Circuit, LinearCombination, Variable, R1CS}; +use crate::{CanaryCircuit, Circuit, LinearCombination, R1CS, TestnetCircuit, Variable}; use snarkvm_curves::edwards_bls12::Fq; use snarkvm_fields::PrimeField; @@ -34,6 +35,26 @@ impl snarkvm_algorithms::r1cs::ConstraintSynthesizer for Circuit { } } +impl snarkvm_algorithms::r1cs::ConstraintSynthesizer for TestnetCircuit { + /// Synthesizes the constraints from the environment into a `snarkvm_algorithms::r1cs`-compliant constraint system. + fn generate_constraints>( + &self, + cs: &mut CS, + ) -> Result<(), snarkvm_algorithms::r1cs::SynthesisError> { + crate::testnet_circuit::TESTNET_CIRCUIT.with(|circuit| circuit.borrow().generate_constraints(cs)) + } +} + +impl snarkvm_algorithms::r1cs::ConstraintSynthesizer for CanaryCircuit { + /// Synthesizes the constraints from the environment into a `snarkvm_algorithms::r1cs`-compliant constraint system. + fn generate_constraints>( + &self, + cs: &mut CS, + ) -> Result<(), snarkvm_algorithms::r1cs::SynthesisError> { + crate::canary_circuit::CANARY_CIRCUIT.with(|circuit| circuit.borrow().generate_constraints(cs)) + } +} + impl R1CS { /// Synthesizes the constraints from the environment into a `snarkvm_algorithms::r1cs`-compliant constraint system. fn generate_constraints>( @@ -47,21 +68,26 @@ impl R1CS { assert_eq!(0, cs.num_private_variables()); assert_eq!(0, cs.num_constraints()); + let result = converter.public.insert(0, CS::one()); + assert!(result.is_none(), "Overwrote an existing public variable in the converter"); + // Allocate the public variables. - for (i, public) in self.to_public_variables().iter().enumerate() { + // NOTE: we skip the first public `One` variable because we already allocated it in the `ConstraintSystem` constructor. + for (i, public) in self.to_public_variables().iter().skip(1).enumerate() { match public { Variable::Public(index_value) => { let (index, value) = index_value.as_ref(); assert_eq!( - i as u64, *index, - "Public variables in first system must be processed in lexicographic order" + (i + 1) as u64, + *index, + "Public vars in first system must be processed in lexicographic order" ); let gadget = cs.alloc_input(|| format!("Public {i}"), || Ok(*value))?; assert_eq!( - snarkvm_algorithms::r1cs::Index::Public((index + 1) as usize), + snarkvm_algorithms::r1cs::Index::Public(*index as usize), gadget.get_unchecked(), "Public variables in the second system must match the first system (with an off-by-1 for the public case)" ); @@ -165,7 +191,7 @@ impl R1CS { } // Ensure the given `cs` matches in size with the first system. - assert_eq!(self.num_public() + 1, cs.num_public_variables() as u64); + assert_eq!(self.num_public(), cs.num_public_variables() as u64); assert_eq!(self.num_private(), cs.num_private_variables() as u64); assert_eq!(self.num_constraints(), cs.num_constraints() as u64); @@ -175,7 +201,7 @@ impl R1CS { #[cfg(test)] mod tests { - use snarkvm_algorithms::{r1cs::ConstraintSynthesizer, AlgebraicSponge, SNARK}; + use snarkvm_algorithms::{AlgebraicSponge, SNARK, r1cs::ConstraintSynthesizer}; use snarkvm_circuit::prelude::*; use snarkvm_curves::bls12_377::Fr; @@ -211,7 +237,7 @@ mod tests { Circuit.generate_constraints(&mut cs).unwrap(); { use snarkvm_algorithms::r1cs::ConstraintSystem; - assert_eq!(Circuit::num_public() + 1, cs.num_public_variables() as u64); + assert_eq!(Circuit::num_public(), cs.num_public_variables() as u64); assert_eq!(Circuit::num_private(), cs.num_private_variables() as u64); assert_eq!(Circuit::num_constraints(), cs.num_constraints() as u64); assert!(cs.is_satisfied()); @@ -227,7 +253,7 @@ mod tests { use snarkvm_algorithms::{ crypto_hash::PoseidonSponge, - snark::varuna::{ahp::AHPForR1CS, VarunaHidingMode, VarunaSNARK}, + snark::varuna::{VarunaHidingMode, VarunaSNARK, ahp::AHPForR1CS}, }; use snarkvm_curves::bls12_377::{Bls12_377, Fq}; use snarkvm_utilities::rand::TestRng; diff --git a/circuit/environment/src/helpers/count.rs b/circuit/environment/src/helpers/count.rs index 98a92472c2..4c8799372c 100644 --- a/circuit/environment/src/helpers/count.rs +++ b/circuit/environment/src/helpers/count.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/helpers/counter.rs b/circuit/environment/src/helpers/counter.rs index 8631f95af1..3f59d12fa0 100644 --- a/circuit/environment/src/helpers/counter.rs +++ b/circuit/environment/src/helpers/counter.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/helpers/linear_combination.rs b/circuit/environment/src/helpers/linear_combination.rs index 4d33d210ff..dbff6c06c2 100644 --- a/circuit/environment/src/helpers/linear_combination.rs +++ b/circuit/environment/src/helpers/linear_combination.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/helpers/mod.rs b/circuit/environment/src/helpers/mod.rs index 35d948a7da..8237d3ff3d 100644 --- a/circuit/environment/src/helpers/mod.rs +++ b/circuit/environment/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/helpers/mode.rs b/circuit/environment/src/helpers/mode.rs index 886a305f4d..ff1d9296e8 100644 --- a/circuit/environment/src/helpers/mode.rs +++ b/circuit/environment/src/helpers/mode.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,10 +15,10 @@ use crate::prelude::*; use snarkvm_utilities::{ - error, - io::{Read, Result as IoResult, Write}, FromBytes, ToBytes, + error, + io::{Read, Result as IoResult, Write}, }; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] diff --git a/circuit/environment/src/helpers/r1cs.rs b/circuit/environment/src/helpers/r1cs.rs index d08adbdfdb..4003775b53 100644 --- a/circuit/environment/src/helpers/r1cs.rs +++ b/circuit/environment/src/helpers/r1cs.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -29,6 +30,7 @@ pub struct R1CS { private: Vec>, constraints: Vec>>, counter: Counter, + num_variables: u64, nonzeros: (u64, u64, u64), } @@ -41,6 +43,7 @@ impl R1CS { private: Default::default(), constraints: Default::default(), counter: Default::default(), + num_variables: 1u64, nonzeros: (0, 0, 0), } } @@ -60,6 +63,7 @@ impl R1CS { let variable = Variable::Constant(Rc::new(value)); self.constants.push(variable.clone()); self.counter.increment_constant(); + self.num_variables += 1; variable } @@ -68,6 +72,7 @@ impl R1CS { let variable = Variable::Public(Rc::new((self.public.len() as u64, value))); self.public.push(variable.clone()); self.counter.increment_public(); + self.num_variables += 1; variable } @@ -76,6 +81,7 @@ impl R1CS { let variable = Variable::Private(Rc::new((self.private.len() as u64, value))); self.private.push(variable.clone()); self.counter.increment_private(); + self.num_variables += 1; variable } @@ -149,6 +155,11 @@ impl R1CS { self.private.len() as u64 } + /// Returns the number of constant, public, and private variables in the constraint system. + pub fn num_variables(&self) -> u64 { + self.num_variables + } + /// Returns the number of constraints in the constraint system. pub fn num_constraints(&self) -> u64 { self.constraints.len() as u64 diff --git a/circuit/environment/src/helpers/updatable_count.rs b/circuit/environment/src/helpers/updatable_count.rs index 9193237af0..122db5c861 100644 --- a/circuit/environment/src/helpers/updatable_count.rs +++ b/circuit/environment/src/helpers/updatable_count.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -32,7 +33,7 @@ static WORKSPACE_ROOT: OnceCell = OnceCell::new(); /// To update the arguments to `count_is!`, run cargo test with the `UPDATE_COUNT` flag set to the name of the file containing the macro invocation. /// e.g. `UPDATE_COUNT=boolean cargo test -/// See https://github.com/AleoHQ/snarkVM/pull/1688 for more details. +/// See https://github.com/AleoNet/snarkVM/pull/1688 for more details. #[macro_export] macro_rules! count_is { ($num_constants:literal, $num_public:literal, $num_private:literal, $num_constraints:literal) => { @@ -50,7 +51,7 @@ macro_rules! count_is { /// To update the arguments to `count_less_than!`, run cargo test with the `UPDATE_COUNT` flag set to the name of the file containing the macro invocation. /// e.g. `UPDATE_COUNT=boolean cargo test -/// See https://github.com/AleoHQ/snarkVM/pull/1688 for more details. +/// See https://github.com/AleoNet/snarkVM/pull/1688 for more details. #[macro_export] macro_rules! count_less_than { ($num_constants:literal, $num_public:literal, $num_private:literal, $num_constraints:literal) => { @@ -498,7 +499,7 @@ mod test { fn check_position() { let count = count_is!(0, 0, 0, 0); assert_eq!(count.file, "circuit/environment/src/helpers/updatable_count.rs"); - assert_eq!(count.line, 499); + assert_eq!(count.line, 500); assert_eq!(count.column, 21); } diff --git a/circuit/environment/src/helpers/variable.rs b/circuit/environment/src/helpers/variable.rs index 6dd7012af4..80abeb4531 100644 --- a/circuit/environment/src/helpers/variable.rs +++ b/circuit/environment/src/helpers/variable.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/lib.rs b/circuit/environment/src/lib.rs index 9443e5eabd..6b9da587d3 100644 --- a/circuit/environment/src/lib.rs +++ b/circuit/environment/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,6 +20,9 @@ extern crate snarkvm_circuit_environment_witness; pub use snarkvm_circuit_environment_witness::rename_selfs; +pub mod canary_circuit; +pub use canary_circuit::*; + pub mod circuit; pub use circuit::*; @@ -32,11 +36,21 @@ pub mod macros; #[allow(unused_imports)] pub use macros::*; +pub mod testnet_circuit; +pub use testnet_circuit::*; + pub mod traits; pub use traits::*; pub mod prelude { pub use crate::{ + CircuitType, + Count, + Environment, + LinearCombination, + Mode, + OutputMode, + Variable, count, count_is, count_less_than, @@ -45,20 +59,12 @@ pub mod prelude { traits::*, witness, witness_mode, - CircuitType, - Count, - Environment, - LinearCombination, - Mode, - OutputMode, - Variable, }; pub use console::{ + Parser, + ParserResult, + TypeName, prelude::{ - bail, - ensure, - fmt, - has_duplicates, Debug, Display, Error, @@ -67,23 +73,24 @@ pub mod prelude { One as _, Result, Zero as _, + bail, + ensure, + fmt, + has_duplicates, }, traits::{ - string_parser, - types::{ - integer_magnitude::Magnitude, - integer_type::{CheckedPow, IntegerProperties, IntegerType, WrappingDiv, WrappingPow, WrappingRem}, - }, Double as _, FromBits as _, Inverse as _, Square as _, SquareRoot as _, ToBits as _, + string_parser, + types::{ + integer_magnitude::Magnitude, + integer_type::{CheckedPow, IntegerProperties, IntegerType, WrappingDiv, WrappingPow, WrappingRem}, + }, }, - Parser, - ParserResult, - TypeName, }; pub use snarkvm_fields::{self, Field as _, PrimeField, Zero as _}; diff --git a/circuit/environment/src/macros/metrics.rs b/circuit/environment/src/macros/metrics.rs index 5717abbceb..b6e4881631 100644 --- a/circuit/environment/src/macros/metrics.rs +++ b/circuit/environment/src/macros/metrics.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/macros/mod.rs b/circuit/environment/src/macros/mod.rs index bed7fb825f..5a0c0c473d 100644 --- a/circuit/environment/src/macros/mod.rs +++ b/circuit/environment/src/macros/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/macros/scope.rs b/circuit/environment/src/macros/scope.rs index 07290ec0cd..e8080c4bc1 100644 --- a/circuit/environment/src/macros/scope.rs +++ b/circuit/environment/src/macros/scope.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/macros/witness.rs b/circuit/environment/src/macros/witness.rs index af498e6aab..789c4744fd 100644 --- a/circuit/environment/src/macros/witness.rs +++ b/circuit/environment/src/macros/witness.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/testnet_circuit.rs b/circuit/environment/src/testnet_circuit.rs new file mode 100644 index 0000000000..add19ad89a --- /dev/null +++ b/circuit/environment/src/testnet_circuit.rs @@ -0,0 +1,410 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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::{Mode, helpers::Constraint, *}; + +use core::{ + cell::{Cell, RefCell}, + fmt, +}; + +type Field = ::Field; + +thread_local! { + static VARIABLE_LIMIT: Cell> = const { Cell::new(None) }; + static CONSTRAINT_LIMIT: Cell> = const { Cell::new(None) }; + pub(super) static TESTNET_CIRCUIT: RefCell> = RefCell::new(R1CS::new()); + static IN_WITNESS: Cell = const { Cell::new(false) }; + static ZERO: LinearCombination = LinearCombination::zero(); + static ONE: LinearCombination = LinearCombination::one(); +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub struct TestnetCircuit; + +impl Environment for TestnetCircuit { + type Affine = ::Affine; + type BaseField = Field; + type Network = console::TestnetV0; + type ScalarField = ::Scalar; + + /// Returns the `zero` constant. + fn zero() -> LinearCombination { + ZERO.with(|zero| zero.clone()) + } + + /// Returns the `one` constant. + fn one() -> LinearCombination { + ONE.with(|one| one.clone()) + } + + /// Returns a new variable of the given mode and value. + fn new_variable(mode: Mode, value: Self::BaseField) -> Variable { + IN_WITNESS.with(|in_witness| { + // Ensure we are not in witness mode. + if !in_witness.get() { + // Ensure that we do not surpass the variable limit for the circuit. + VARIABLE_LIMIT.with(|variable_limit| { + if let Some(limit) = variable_limit.get() { + if Self::num_variables() > limit { + Self::halt(format!("Surpassed the variable limit ({limit})")) + } + } + }); + TESTNET_CIRCUIT.with(|circuit| match mode { + Mode::Constant => circuit.borrow_mut().new_constant(value), + Mode::Public => circuit.borrow_mut().new_public(value), + Mode::Private => circuit.borrow_mut().new_private(value), + }) + } else { + Self::halt("Tried to initialize a new variable in witness mode") + } + }) + } + + /// Returns a new witness of the given mode and value. + fn new_witness Output::Primitive, Output: Inject>(mode: Mode, logic: Fn) -> Output { + IN_WITNESS.with(|in_witness| { + // Set the entire environment to witness mode. + in_witness.replace(true); + + // Run the logic. + let output = logic(); + + // Return the entire environment from witness mode. + in_witness.replace(false); + + Inject::new(mode, output) + }) + } + + /// Enters a new scope for the environment. + fn scope, Fn, Output>(name: S, logic: Fn) -> Output + where + Fn: FnOnce() -> Output, + { + IN_WITNESS.with(|in_witness| { + // Ensure we are not in witness mode. + if !in_witness.get() { + TESTNET_CIRCUIT.with(|circuit| { + // Set the entire environment to the new scope. + let name = name.into(); + if let Err(error) = circuit.borrow_mut().push_scope(&name) { + Self::halt(error) + } + + // Run the logic. + let output = logic(); + + // Return the entire environment to the previous scope. + if let Err(error) = circuit.borrow_mut().pop_scope(name) { + Self::halt(error) + } + + output + }) + } else { + Self::halt("Tried to initialize a new scope in witness mode") + } + }) + } + + /// Adds one constraint enforcing that `(A * B) == C`. + fn enforce(constraint: Fn) + where + Fn: FnOnce() -> (A, B, C), + A: Into>, + B: Into>, + C: Into>, + { + IN_WITNESS.with(|in_witness| { + // Ensure we are not in witness mode. + if !in_witness.get() { + TESTNET_CIRCUIT.with(|circuit| { + // Ensure that we do not surpass the constraint limit for the circuit. + CONSTRAINT_LIMIT.with(|constraint_limit| { + if let Some(limit) = constraint_limit.get() { + if circuit.borrow().num_constraints() > limit { + Self::halt(format!("Surpassed the constraint limit ({limit})")) + } + } + }); + + let (a, b, c) = constraint(); + let (a, b, c) = (a.into(), b.into(), c.into()); + + // Ensure the constraint is not comprised of constants. + match a.is_constant() && b.is_constant() && c.is_constant() { + true => { + // Evaluate the constant constraint. + assert_eq!( + a.value() * b.value(), + c.value(), + "Constant constraint failed: ({a} * {b}) =?= {c}" + ); + + // match self.counter.scope().is_empty() { + // true => println!("Enforced constraint with constant terms: ({} * {}) =?= {}", a, b, c), + // false => println!( + // "Enforced constraint with constant terms ({}): ({} * {}) =?= {}", + // self.counter.scope(), a, b, c + // ), + // } + } + false => { + // Construct the constraint object. + let constraint = Constraint(circuit.borrow().scope(), a, b, c); + // Append the constraint. + circuit.borrow_mut().enforce(constraint) + } + } + }); + } else { + Self::halt("Tried to add a new constraint in witness mode") + } + }) + } + + /// Returns `true` if all constraints in the environment are satisfied. + fn is_satisfied() -> bool { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().is_satisfied()) + } + + /// Returns `true` if all constraints in the current scope are satisfied. + fn is_satisfied_in_scope() -> bool { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().is_satisfied_in_scope()) + } + + /// Returns the number of constants in the entire circuit. + fn num_constants() -> u64 { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_constants()) + } + + /// Returns the number of public variables in the entire circuit. + fn num_public() -> u64 { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_public()) + } + + /// Returns the number of private variables in the entire circuit. + fn num_private() -> u64 { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_private()) + } + + /// Returns the number of constant, public, and private variables in the entire circuit. + fn num_variables() -> u64 { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_variables()) + } + + /// Returns the number of constraints in the entire circuit. + fn num_constraints() -> u64 { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_constraints()) + } + + /// Returns the number of nonzeros in the entire circuit. + fn num_nonzeros() -> (u64, u64, u64) { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_nonzeros()) + } + + /// Returns the number of constants for the current scope. + fn num_constants_in_scope() -> u64 { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_constants_in_scope()) + } + + /// Returns the number of public variables for the current scope. + fn num_public_in_scope() -> u64 { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_public_in_scope()) + } + + /// Returns the number of private variables for the current scope. + fn num_private_in_scope() -> u64 { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_private_in_scope()) + } + + /// Returns the number of constraints for the current scope. + fn num_constraints_in_scope() -> u64 { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_constraints_in_scope()) + } + + /// Returns the number of nonzeros for the current scope. + fn num_nonzeros_in_scope() -> (u64, u64, u64) { + TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_nonzeros_in_scope()) + } + + /// Returns the variable limit for the circuit, if one exists. + fn get_variable_limit() -> Option { + VARIABLE_LIMIT.with(|current_limit| current_limit.get()) + } + + /// Sets the variable limit for the circuit. + fn set_variable_limit(limit: Option) { + VARIABLE_LIMIT.with(|current_limit| current_limit.replace(limit)); + } + + /// Returns the constraint limit for the circuit, if one exists. + fn get_constraint_limit() -> Option { + CONSTRAINT_LIMIT.with(|current_limit| current_limit.get()) + } + + /// Sets the constraint limit for the circuit. + fn set_constraint_limit(limit: Option) { + CONSTRAINT_LIMIT.with(|current_limit| current_limit.replace(limit)); + } + + /// Halts the program from further synthesis, evaluation, and execution in the current environment. + fn halt, T>(message: S) -> T { + let error = message.into(); + // eprintln!("{}", &error); + panic!("{}", &error) + } + + /// Returns the R1CS circuit, resetting the circuit. + fn inject_r1cs(r1cs: R1CS) { + TESTNET_CIRCUIT.with(|circuit| { + // Ensure the circuit is empty before injecting. + assert_eq!(0, circuit.borrow().num_constants()); + assert_eq!(1, circuit.borrow().num_public()); + assert_eq!(0, circuit.borrow().num_private()); + assert_eq!(1, circuit.borrow().num_variables()); + assert_eq!(0, circuit.borrow().num_constraints()); + // Inject the R1CS instance. + let r1cs = circuit.replace(r1cs); + // Ensure the circuit that was replaced is empty. + assert_eq!(0, r1cs.num_constants()); + assert_eq!(1, r1cs.num_public()); + assert_eq!(0, r1cs.num_private()); + assert_eq!(1, r1cs.num_variables()); + assert_eq!(0, r1cs.num_constraints()); + }) + } + + /// Returns the R1CS circuit, resetting the circuit. + fn eject_r1cs_and_reset() -> R1CS { + TESTNET_CIRCUIT.with(|circuit| { + // Reset the witness mode. + IN_WITNESS.with(|in_witness| in_witness.replace(false)); + // Reset the variable limit. + Self::set_variable_limit(None); + // Reset the constraint limit. + Self::set_constraint_limit(None); + // Eject the R1CS instance. + let r1cs = circuit.replace(R1CS::<::BaseField>::new()); + // Ensure the circuit is now empty. + assert_eq!(0, circuit.borrow().num_constants()); + assert_eq!(1, circuit.borrow().num_public()); + assert_eq!(0, circuit.borrow().num_private()); + assert_eq!(1, circuit.borrow().num_variables()); + assert_eq!(0, circuit.borrow().num_constraints()); + // Return the R1CS instance. + r1cs + }) + } + + /// Returns the R1CS assignment of the circuit, resetting the circuit. + fn eject_assignment_and_reset() -> Assignment<::Field> { + TESTNET_CIRCUIT.with(|circuit| { + // Reset the witness mode. + IN_WITNESS.with(|in_witness| in_witness.replace(false)); + // Reset the variable limit. + Self::set_variable_limit(None); + // Reset the constraint limit. + Self::set_constraint_limit(None); + // Eject the R1CS instance. + let r1cs = circuit.replace(R1CS::<::BaseField>::new()); + assert_eq!(0, circuit.borrow().num_constants()); + assert_eq!(1, circuit.borrow().num_public()); + assert_eq!(0, circuit.borrow().num_private()); + assert_eq!(1, circuit.borrow().num_variables()); + assert_eq!(0, circuit.borrow().num_constraints()); + // Convert the R1CS instance to an assignment. + Assignment::from(r1cs) + }) + } + + /// Clears the circuit and initializes an empty environment. + fn reset() { + TESTNET_CIRCUIT.with(|circuit| { + // Reset the witness mode. + IN_WITNESS.with(|in_witness| in_witness.replace(false)); + // Reset the variable limit. + Self::set_variable_limit(None); + // Reset the constraint limit. + Self::set_constraint_limit(None); + // Reset the circuit. + *circuit.borrow_mut() = R1CS::<::BaseField>::new(); + assert_eq!(0, circuit.borrow().num_constants()); + assert_eq!(1, circuit.borrow().num_public()); + assert_eq!(0, circuit.borrow().num_private()); + assert_eq!(1, circuit.borrow().num_variables()); + assert_eq!(0, circuit.borrow().num_constraints()); + }); + } +} + +impl fmt::Display for TestnetCircuit { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + TESTNET_CIRCUIT.with(|circuit| write!(f, "{}", circuit.borrow())) + } +} + +#[cfg(test)] +mod tests { + use snarkvm_circuit::prelude::*; + + /// Compute 2^EXPONENT - 1, in a purposefully constraint-inefficient manner for testing. + fn create_example_circuit() -> Field { + let one = snarkvm_console_types::Field::::one(); + let two = one + one; + + const EXPONENT: u64 = 64; + + // Compute 2^EXPONENT - 1, in a purposefully constraint-inefficient manner for testing. + let mut candidate = Field::::new(Mode::Public, one); + let mut accumulator = Field::new(Mode::Private, two); + for _ in 0..EXPONENT { + candidate += &accumulator; + accumulator *= Field::new(Mode::Private, two); + } + + assert_eq!((accumulator - Field::one()).eject_value(), candidate.eject_value()); + assert_eq!(2, E::num_public()); + assert_eq!(2 * EXPONENT + 1, E::num_private()); + assert_eq!(EXPONENT, E::num_constraints()); + assert!(E::is_satisfied()); + + candidate + } + + #[test] + fn test_print_circuit() { + let _candidate = create_example_circuit::(); + let output = format!("{TestnetCircuit}"); + println!("{output}"); + } + + #[test] + fn test_circuit_scope() { + TestnetCircuit::scope("test_circuit_scope", || { + assert_eq!(0, TestnetCircuit::num_constants()); + assert_eq!(1, TestnetCircuit::num_public()); + assert_eq!(0, TestnetCircuit::num_private()); + assert_eq!(0, TestnetCircuit::num_constraints()); + + assert_eq!(0, TestnetCircuit::num_constants_in_scope()); + assert_eq!(0, TestnetCircuit::num_public_in_scope()); + assert_eq!(0, TestnetCircuit::num_private_in_scope()); + assert_eq!(0, TestnetCircuit::num_constraints_in_scope()); + }) + } +} diff --git a/circuit/environment/src/traits/eject.rs b/circuit/environment/src/traits/eject.rs index 7eb9386f98..c65df118d9 100644 --- a/circuit/environment/src/traits/eject.rs +++ b/circuit/environment/src/traits/eject.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -69,7 +70,7 @@ impl Eject for Vec { fn eject_mode(&self) -> Mode { // TODO (howardwu): Determine if a default mode of `constant` is appropriate. // Retrieve the mode of the first circuit. - match self.get(0) { + match self.first() { Some(first) => Mode::combine(*first, self.iter().copied().skip(1)), // None => Mode::Constant, None => panic!("Attempted to eject the mode on an empty circuit"), @@ -123,7 +124,7 @@ impl, P> Eject for &[C] { fn eject_mode(&self) -> Mode { // TODO (howardwu): Determine if a default mode of `constant` is appropriate. // Retrieve the mode of the first circuit. - match self.get(0) { + match self.first() { Some(first) => Mode::combine(first.eject_mode(), self.iter().skip(1).map(Eject::eject_mode)), None => Mode::Constant, // None => panic!("Attempted to eject the mode on an empty circuit"), diff --git a/circuit/environment/src/traits/from.rs b/circuit/environment/src/traits/from.rs index c7b266cb6a..fb0d9eb1bd 100644 --- a/circuit/environment/src/traits/from.rs +++ b/circuit/environment/src/traits/from.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/inject.rs b/circuit/environment/src/traits/inject.rs index cebff36ee3..0de38db025 100644 --- a/circuit/environment/src/traits/inject.rs +++ b/circuit/environment/src/traits/inject.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/metrics.rs b/circuit/environment/src/traits/metrics.rs index d46d59967a..6a301d4380 100644 --- a/circuit/environment/src/traits/metrics.rs +++ b/circuit/environment/src/traits/metrics.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/mod.rs b/circuit/environment/src/traits/mod.rs index f1cfa96d20..8cce823148 100644 --- a/circuit/environment/src/traits/mod.rs +++ b/circuit/environment/src/traits/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/operators.rs b/circuit/environment/src/traits/operators.rs index 39d8eac78b..a678e94148 100644 --- a/circuit/environment/src/traits/operators.rs +++ b/circuit/environment/src/traits/operators.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/to.rs b/circuit/environment/src/traits/to.rs index 80ac4f7c12..79f90b2c6e 100644 --- a/circuit/environment/src/traits/to.rs +++ b/circuit/environment/src/traits/to.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/to_bits.rs b/circuit/environment/src/traits/to_bits.rs index a090eddca3..4a6d408086 100644 --- a/circuit/environment/src/traits/to_bits.rs +++ b/circuit/environment/src/traits/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/types/address.rs b/circuit/environment/src/traits/types/address.rs index d388d9a1ae..f14a972b60 100644 --- a/circuit/environment/src/traits/types/address.rs +++ b/circuit/environment/src/traits/types/address.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/types/boolean.rs b/circuit/environment/src/traits/types/boolean.rs index 7e5a53c3d0..9fed1f5914 100644 --- a/circuit/environment/src/traits/types/boolean.rs +++ b/circuit/environment/src/traits/types/boolean.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/types/field.rs b/circuit/environment/src/traits/types/field.rs index 04369108cf..3261974210 100644 --- a/circuit/environment/src/traits/types/field.rs +++ b/circuit/environment/src/traits/types/field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/types/group.rs b/circuit/environment/src/traits/types/group.rs index dc56893e53..7e858bd30e 100644 --- a/circuit/environment/src/traits/types/group.rs +++ b/circuit/environment/src/traits/types/group.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/types/integers.rs b/circuit/environment/src/traits/types/integers.rs index f6f7e388c4..00d1337ddd 100644 --- a/circuit/environment/src/traits/types/integers.rs +++ b/circuit/environment/src/traits/types/integers.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/types/mod.rs b/circuit/environment/src/traits/types/mod.rs index f57ced5233..7d551ecd10 100644 --- a/circuit/environment/src/traits/types/mod.rs +++ b/circuit/environment/src/traits/types/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/types/scalar.rs b/circuit/environment/src/traits/types/scalar.rs index 50a980456c..0d7f9fd488 100644 --- a/circuit/environment/src/traits/types/scalar.rs +++ b/circuit/environment/src/traits/types/scalar.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/src/traits/types/string.rs b/circuit/environment/src/traits/types/string.rs index 9039ef4d30..30ec503e3b 100644 --- a/circuit/environment/src/traits/types/string.rs +++ b/circuit/environment/src/traits/types/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/environment/witness/Cargo.toml b/circuit/environment/witness/Cargo.toml index a6660d0684..a18c69c0ca 100644 --- a/circuit/environment/witness/Cargo.toml +++ b/circuit/environment/witness/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "snarkvm-circuit-environment-witness" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A procedural macro to construct a witness in an environment" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2018" diff --git a/circuit/environment/witness/src/lib.rs b/circuit/environment/witness/src/lib.rs index 3d4c8c085d..4b0728347d 100644 --- a/circuit/environment/witness/src/lib.rs +++ b/circuit/environment/witness/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/network/Cargo.toml b/circuit/network/Cargo.toml index efd63a8cdc..b24c179eed 100644 --- a/circuit/network/Cargo.toml +++ b/circuit/network/Cargo.toml @@ -1,28 +1,30 @@ [package] name = "snarkvm-circuit-network" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Network circuit library for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.console] package = "snarkvm-console-network" path = "../../console/network" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit-algorithms] path = "../algorithms" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-collections] path = "../collections" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types] path = "../types" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.snarkvm-console-types] path = "../../console/types" diff --git a/circuit/network/build.rs b/circuit/network/build.rs index ff14549b2c..1d0fe74e7c 100644 --- a/circuit/network/build.rs +++ b/circuit/network/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/network/src/canary_v0.rs b/circuit/network/src/canary_v0.rs new file mode 100644 index 0000000000..6480f58fe6 --- /dev/null +++ b/circuit/network/src/canary_v0.rs @@ -0,0 +1,599 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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::Aleo; +use snarkvm_circuit_algorithms::{ + BHP256, + BHP512, + BHP768, + BHP1024, + Commit, + CommitUncompressed, + Hash, + HashMany, + HashToGroup, + HashToScalar, + HashUncompressed, + Keccak256, + Keccak384, + Keccak512, + Pedersen64, + Pedersen128, + Poseidon2, + Poseidon4, + Poseidon8, + Sha3_256, + Sha3_384, + Sha3_512, +}; +use snarkvm_circuit_collections::merkle_tree::MerklePath; +use snarkvm_circuit_types::{ + Boolean, + Field, + Group, + Scalar, + environment::{Assignment, CanaryCircuit, R1CS, prelude::*}, +}; + +use core::fmt; + +type E = CanaryCircuit; + +thread_local! { + /// The group bases for the Aleo signature and encryption schemes. + static GENERATOR_G: Vec> = Vec::constant(::g_powers().to_vec()); + + /// The encryption domain as a constant field element. + static ENCRYPTION_DOMAIN: Field = Field::constant(::encryption_domain()); + /// The graph key domain as a constant field element. + static GRAPH_KEY_DOMAIN: Field = Field::constant(::graph_key_domain()); + /// The serial number domain as a constant field element. + static SERIAL_NUMBER_DOMAIN: Field = Field::constant(::serial_number_domain()); + + /// The BHP hash function, which can take an input of up to 256 bits. + static BHP_256: BHP256 = BHP256::::constant(console::CANARY_BHP_256.clone()); + /// The BHP hash function, which can take an input of up to 512 bits. + static BHP_512: BHP512 = BHP512::::constant(console::CANARY_BHP_512.clone()); + /// The BHP hash function, which can take an input of up to 768 bits. + static BHP_768: BHP768 = BHP768::::constant(console::CANARY_BHP_768.clone()); + /// The BHP hash function, which can take an input of up to 1024 bits. + static BHP_1024: BHP1024 = BHP1024::::constant(console::CANARY_BHP_1024.clone()); + + /// The Keccak hash function, which outputs 256 bits. + static KECCAK_256: Keccak256 = Keccak256::::new(); + /// The Keccak hash function, which outputs 384 bits. + static KECCAK_384: Keccak384 = Keccak384::::new(); + /// The Keccak hash function, which outputs 512 bits. + static KECCAK_512: Keccak512 = Keccak512::::new(); + + /// The Pedersen hash function, which can take an input of up to 64 bits. + static PEDERSEN_64: Pedersen64 = Pedersen64::::constant(console::CANARY_PEDERSEN_64.clone()); + /// The Pedersen hash function, which can take an input of up to 128 bits. + static PEDERSEN_128: Pedersen128 = Pedersen128::::constant(console::CANARY_PEDERSEN_128.clone()); + + /// The Poseidon hash function, using a rate of 2. + static POSEIDON_2: Poseidon2 = Poseidon2::::constant(console::CANARY_POSEIDON_2.clone()); + /// The Poseidon hash function, using a rate of 4. + static POSEIDON_4: Poseidon4 = Poseidon4::::constant(console::CANARY_POSEIDON_4.clone()); + /// The Poseidon hash function, using a rate of 8. + static POSEIDON_8: Poseidon8 = Poseidon8::::constant(console::CANARY_POSEIDON_8.clone()); + + /// The SHA-3 hash function, which outputs 256 bits. + static SHA3_256: Sha3_256 = Sha3_256::::new(); + /// The SHA-3 hash function, which outputs 384 bits. + static SHA3_384: Sha3_384 = Sha3_384::::new(); + /// The SHA-3 hash function, which outputs 512 bits. + static SHA3_512: Sha3_512 = Sha3_512::::new(); +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub struct AleoCanaryV0; + +impl Aleo for AleoCanaryV0 { + /// Initializes the global constants for the Aleo environment. + fn initialize_global_constants() { + GENERATOR_G.with(|_| ()); + ENCRYPTION_DOMAIN.with(|_| ()); + GRAPH_KEY_DOMAIN.with(|_| ()); + SERIAL_NUMBER_DOMAIN.with(|_| ()); + BHP_256.with(|_| ()); + BHP_512.with(|_| ()); + BHP_768.with(|_| ()); + BHP_1024.with(|_| ()); + KECCAK_256.with(|_| ()); + KECCAK_384.with(|_| ()); + KECCAK_512.with(|_| ()); + PEDERSEN_64.with(|_| ()); + PEDERSEN_128.with(|_| ()); + POSEIDON_2.with(|_| ()); + POSEIDON_4.with(|_| ()); + POSEIDON_8.with(|_| ()); + SHA3_256.with(|_| ()); + SHA3_384.with(|_| ()); + SHA3_512.with(|_| ()); + } + + /// Returns the encryption domain as a constant field element. + fn encryption_domain() -> Field { + ENCRYPTION_DOMAIN.with(|domain| domain.clone()) + } + + /// Returns the graph key domain as a constant field element. + fn graph_key_domain() -> Field { + GRAPH_KEY_DOMAIN.with(|domain| domain.clone()) + } + + /// Returns the serial number domain as a constant field element. + fn serial_number_domain() -> Field { + SERIAL_NUMBER_DOMAIN.with(|domain| domain.clone()) + } + + /// Returns the scalar multiplication on the generator `G`. + #[inline] + fn g_scalar_multiply(scalar: &Scalar) -> Group { + GENERATOR_G.with(|bases| { + bases + .iter() + .zip_eq(&scalar.to_bits_le()) + .fold(Group::zero(), |output, (base, bit)| Group::ternary(bit, &(&output + base), &output)) + }) + } + + /// Returns a BHP commitment with an input hasher of 256-bits. + fn commit_bhp256(input: &[Boolean], randomizer: &Scalar) -> Field { + BHP_256.with(|bhp| bhp.commit(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 512-bits. + fn commit_bhp512(input: &[Boolean], randomizer: &Scalar) -> Field { + BHP_512.with(|bhp| bhp.commit(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 768-bits. + fn commit_bhp768(input: &[Boolean], randomizer: &Scalar) -> Field { + BHP_768.with(|bhp| bhp.commit(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 1024-bits. + fn commit_bhp1024(input: &[Boolean], randomizer: &Scalar) -> Field { + BHP_1024.with(|bhp| bhp.commit(input, randomizer)) + } + + /// Returns a Pedersen commitment for the given (up to) 64-bit input and randomizer. + fn commit_ped64(input: &[Boolean], randomizer: &Scalar) -> Field { + PEDERSEN_64.with(|pedersen| pedersen.commit(input, randomizer)) + } + + /// Returns a Pedersen commitment for the given (up to) 128-bit input and randomizer. + fn commit_ped128(input: &[Boolean], randomizer: &Scalar) -> Field { + PEDERSEN_128.with(|pedersen| pedersen.commit(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 256-bits. + fn commit_to_group_bhp256(input: &[Boolean], randomizer: &Scalar) -> Group { + BHP_256.with(|bhp| bhp.commit_uncompressed(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 512-bits. + fn commit_to_group_bhp512(input: &[Boolean], randomizer: &Scalar) -> Group { + BHP_512.with(|bhp| bhp.commit_uncompressed(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 768-bits. + fn commit_to_group_bhp768(input: &[Boolean], randomizer: &Scalar) -> Group { + BHP_768.with(|bhp| bhp.commit_uncompressed(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 1024-bits. + fn commit_to_group_bhp1024(input: &[Boolean], randomizer: &Scalar) -> Group { + BHP_1024.with(|bhp| bhp.commit_uncompressed(input, randomizer)) + } + + /// Returns a Pedersen commitment for the given (up to) 64-bit input and randomizer. + fn commit_to_group_ped64(input: &[Boolean], randomizer: &Scalar) -> Group { + PEDERSEN_64.with(|pedersen| pedersen.commit_uncompressed(input, randomizer)) + } + + /// Returns a Pedersen commitment for the given (up to) 128-bit input and randomizer. + fn commit_to_group_ped128(input: &[Boolean], randomizer: &Scalar) -> Group { + PEDERSEN_128.with(|pedersen| pedersen.commit_uncompressed(input, randomizer)) + } + + /// Returns the BHP hash with an input hasher of 256-bits. + fn hash_bhp256(input: &[Boolean]) -> Field { + BHP_256.with(|bhp| bhp.hash(input)) + } + + /// Returns the BHP hash with an input hasher of 512-bits. + fn hash_bhp512(input: &[Boolean]) -> Field { + BHP_512.with(|bhp| bhp.hash(input)) + } + + /// Returns the BHP hash with an input hasher of 768-bits. + fn hash_bhp768(input: &[Boolean]) -> Field { + BHP_768.with(|bhp| bhp.hash(input)) + } + + /// Returns the BHP hash with an input hasher of 1024-bits. + fn hash_bhp1024(input: &[Boolean]) -> Field { + BHP_1024.with(|bhp| bhp.hash(input)) + } + + /// Returns the Keccak hash with a 256-bit output. + fn hash_keccak256(input: &[Boolean]) -> Vec> { + KECCAK_256.with(|keccak| keccak.hash(input)) + } + + /// Returns the Keccak hash with a 384-bit output. + fn hash_keccak384(input: &[Boolean]) -> Vec> { + KECCAK_384.with(|keccak| keccak.hash(input)) + } + + /// Returns the Keccak hash with a 512-bit output. + fn hash_keccak512(input: &[Boolean]) -> Vec> { + KECCAK_512.with(|keccak| keccak.hash(input)) + } + + /// Returns the Pedersen hash for a given (up to) 64-bit input. + fn hash_ped64(input: &[Boolean]) -> Field { + PEDERSEN_64.with(|pedersen| pedersen.hash(input)) + } + + /// Returns the Pedersen hash for a given (up to) 128-bit input. + fn hash_ped128(input: &[Boolean]) -> Field { + PEDERSEN_128.with(|pedersen| pedersen.hash(input)) + } + + /// Returns the Poseidon hash with an input rate of 2. + fn hash_psd2(input: &[Field]) -> Field { + POSEIDON_2.with(|poseidon| poseidon.hash(input)) + } + + /// Returns the Poseidon hash with an input rate of 4. + fn hash_psd4(input: &[Field]) -> Field { + POSEIDON_4.with(|poseidon| poseidon.hash(input)) + } + + /// Returns the Poseidon hash with an input rate of 8. + fn hash_psd8(input: &[Field]) -> Field { + POSEIDON_8.with(|poseidon| poseidon.hash(input)) + } + + /// Returns the SHA-3 hash with a 256-bit output. + fn hash_sha3_256(input: &[Boolean]) -> Vec> { + SHA3_256.with(|sha3| sha3.hash(input)) + } + + /// Returns the SHA-3 hash with a 384-bit output. + fn hash_sha3_384(input: &[Boolean]) -> Vec> { + SHA3_384.with(|sha3| sha3.hash(input)) + } + + /// Returns the SHA-3 hash with a 512-bit output. + fn hash_sha3_512(input: &[Boolean]) -> Vec> { + SHA3_512.with(|sha3| sha3.hash(input)) + } + + /// Returns the extended Poseidon hash with an input rate of 2. + fn hash_many_psd2(input: &[Field], num_outputs: u16) -> Vec> { + POSEIDON_2.with(|poseidon| poseidon.hash_many(input, num_outputs)) + } + + /// Returns the extended Poseidon hash with an input rate of 4. + fn hash_many_psd4(input: &[Field], num_outputs: u16) -> Vec> { + POSEIDON_4.with(|poseidon| poseidon.hash_many(input, num_outputs)) + } + + /// Returns the extended Poseidon hash with an input rate of 8. + fn hash_many_psd8(input: &[Field], num_outputs: u16) -> Vec> { + POSEIDON_8.with(|poseidon| poseidon.hash_many(input, num_outputs)) + } + + /// Returns the BHP hash with an input hasher of 256-bits. + fn hash_to_group_bhp256(input: &[Boolean]) -> Group { + BHP_256.with(|bhp| bhp.hash_uncompressed(input)) + } + + /// Returns the BHP hash with an input hasher of 512-bits. + fn hash_to_group_bhp512(input: &[Boolean]) -> Group { + BHP_512.with(|bhp| bhp.hash_uncompressed(input)) + } + + /// Returns the BHP hash with an input hasher of 768-bits. + fn hash_to_group_bhp768(input: &[Boolean]) -> Group { + BHP_768.with(|bhp| bhp.hash_uncompressed(input)) + } + + /// Returns the BHP hash with an input hasher of 1024-bits. + fn hash_to_group_bhp1024(input: &[Boolean]) -> Group { + BHP_1024.with(|bhp| bhp.hash_uncompressed(input)) + } + + /// Returns the Pedersen hash for a given (up to) 64-bit input. + fn hash_to_group_ped64(input: &[Boolean]) -> Group { + PEDERSEN_64.with(|pedersen| pedersen.hash_uncompressed(input)) + } + + /// Returns the Pedersen hash for a given (up to) 128-bit input. + fn hash_to_group_ped128(input: &[Boolean]) -> Group { + PEDERSEN_128.with(|pedersen| pedersen.hash_uncompressed(input)) + } + + /// Returns the Poseidon hash with an input rate of 2 on the affine curve. + fn hash_to_group_psd2(input: &[Field]) -> Group { + POSEIDON_2.with(|poseidon| poseidon.hash_to_group(input)) + } + + /// Returns the Poseidon hash with an input rate of 4 on the affine curve. + fn hash_to_group_psd4(input: &[Field]) -> Group { + POSEIDON_4.with(|poseidon| poseidon.hash_to_group(input)) + } + + /// Returns the Poseidon hash with an input rate of 8 on the affine curve. + fn hash_to_group_psd8(input: &[Field]) -> Group { + POSEIDON_8.with(|poseidon| poseidon.hash_to_group(input)) + } + + /// Returns the Poseidon hash with an input rate of 2 on the scalar field. + fn hash_to_scalar_psd2(input: &[Field]) -> Scalar { + POSEIDON_2.with(|poseidon| poseidon.hash_to_scalar(input)) + } + + /// Returns the Poseidon hash with an input rate of 4 on the scalar field. + fn hash_to_scalar_psd4(input: &[Field]) -> Scalar { + POSEIDON_4.with(|poseidon| poseidon.hash_to_scalar(input)) + } + + /// Returns the Poseidon hash with an input rate of 8 on the scalar field. + fn hash_to_scalar_psd8(input: &[Field]) -> Scalar { + POSEIDON_8.with(|poseidon| poseidon.hash_to_scalar(input)) + } + + /// Returns `true` if the given Merkle path is valid for the given root and leaf. + fn verify_merkle_path_bhp( + path: &MerklePath, + root: &Field, + leaf: &Vec>, + ) -> Boolean { + BHP_1024.with(|bhp1024| BHP_512.with(|bhp512| path.verify(bhp1024, bhp512, root, leaf))) + } + + /// Returns `true` if the given Merkle path is valid for the given root and leaf. + fn verify_merkle_path_psd( + path: &MerklePath, + root: &Field, + leaf: &Vec>, + ) -> Boolean { + POSEIDON_4.with(|psd4| POSEIDON_2.with(|psd2| path.verify(psd4, psd2, root, leaf))) + } +} + +impl Environment for AleoCanaryV0 { + type Affine = ::Affine; + type BaseField = ::BaseField; + type Network = ::Network; + type ScalarField = ::ScalarField; + + /// Returns the `zero` constant. + fn zero() -> LinearCombination { + E::zero() + } + + /// Returns the `one` constant. + fn one() -> LinearCombination { + E::one() + } + + /// Returns a new variable of the given mode and value. + fn new_variable(mode: Mode, value: Self::BaseField) -> Variable { + E::new_variable(mode, value) + } + + /// Returns a new witness of the given mode and value. + fn new_witness Output::Primitive, Output: Inject>(mode: Mode, logic: Fn) -> Output { + E::new_witness(mode, logic) + } + + /// Enters a new scope for the environment. + fn scope, Fn, Output>(name: S, logic: Fn) -> Output + where + Fn: FnOnce() -> Output, + { + E::scope(name, logic) + } + + /// Adds one constraint enforcing that `(A * B) == C`. + fn enforce(constraint: Fn) + where + Fn: FnOnce() -> (A, B, C), + A: Into>, + B: Into>, + C: Into>, + { + E::enforce(constraint) + } + + /// Returns `true` if all constraints in the environment are satisfied. + fn is_satisfied() -> bool { + E::is_satisfied() + } + + /// Returns `true` if all constraints in the current scope are satisfied. + fn is_satisfied_in_scope() -> bool { + E::is_satisfied_in_scope() + } + + /// Returns the number of constants in the entire circuit. + fn num_constants() -> u64 { + E::num_constants() + } + + /// Returns the number of public variables in the entire circuit. + fn num_public() -> u64 { + E::num_public() + } + + /// Returns the number of private variables in the entire circuit. + fn num_private() -> u64 { + E::num_private() + } + + /// Returns the number of constant, public, and private variables in the entire circuit. + fn num_variables() -> u64 { + E::num_variables() + } + + /// Returns the number of constraints in the entire circuit. + fn num_constraints() -> u64 { + E::num_constraints() + } + + /// Returns the number of nonzeros in the entire circuit. + fn num_nonzeros() -> (u64, u64, u64) { + E::num_nonzeros() + } + + /// Returns the number of constants for the current scope. + fn num_constants_in_scope() -> u64 { + E::num_constants_in_scope() + } + + /// Returns the number of public variables for the current scope. + fn num_public_in_scope() -> u64 { + E::num_public_in_scope() + } + + /// Returns the number of private variables for the current scope. + fn num_private_in_scope() -> u64 { + E::num_private_in_scope() + } + + /// Returns the number of constraints for the current scope. + fn num_constraints_in_scope() -> u64 { + E::num_constraints_in_scope() + } + + /// Returns the number of nonzeros for the current scope. + fn num_nonzeros_in_scope() -> (u64, u64, u64) { + E::num_nonzeros_in_scope() + } + + /// Returns the variable limit for the circuit, if one exists. + fn get_variable_limit() -> Option { + E::get_variable_limit() + } + + /// Sets the variable limit for the circuit. + fn set_variable_limit(limit: Option) { + E::set_variable_limit(limit) + } + + /// Returns the constraint limit for the circuit, if one exists. + fn get_constraint_limit() -> Option { + E::get_constraint_limit() + } + + /// Sets the constraint limit for the circuit. + fn set_constraint_limit(limit: Option) { + E::set_constraint_limit(limit) + } + + /// Halts the program from further synthesis, evaluation, and execution in the current environment. + fn halt, T>(message: S) -> T { + E::halt(message) + } + + /// Returns the R1CS circuit, resetting the circuit. + fn inject_r1cs(r1cs: R1CS) { + E::inject_r1cs(r1cs) + } + + /// Returns the R1CS circuit, resetting the circuit. + fn eject_r1cs_and_reset() -> R1CS { + E::eject_r1cs_and_reset() + } + + /// Returns the R1CS assignment of the circuit, resetting the circuit. + fn eject_assignment_and_reset() -> Assignment<::Field> { + E::eject_assignment_and_reset() + } + + /// Clears the circuit and initializes an empty environment. + fn reset() { + E::reset() + } +} + +impl Display for AleoCanaryV0 { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + // TODO (howardwu): Find a better way to print the circuit. + fmt::Display::fmt(&CanaryCircuit, f) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use snarkvm_circuit_types::Field; + + type CurrentAleo = AleoCanaryV0; + + /// Compute 2^EXPONENT - 1, in a purposefully constraint-inefficient manner for testing. + fn create_example_circuit() -> Field { + let one = snarkvm_console_types::Field::<::Network>::one(); + let two = one + one; + + const EXPONENT: u64 = 64; + + // Compute 2^EXPONENT - 1, in a purposefully constraint-inefficient manner for testing. + let mut candidate = Field::::new(Mode::Public, one); + let mut accumulator = Field::new(Mode::Private, two); + for _ in 0..EXPONENT { + candidate += &accumulator; + accumulator *= Field::new(Mode::Private, two); + } + + assert_eq!((accumulator - Field::one()).eject_value(), candidate.eject_value()); + assert_eq!(2, E::num_public()); + assert_eq!(2 * EXPONENT + 1, E::num_private()); + assert_eq!(EXPONENT, E::num_constraints()); + assert!(E::is_satisfied()); + + candidate + } + + #[test] + fn test_print_circuit() { + let circuit = CurrentAleo {}; + let _candidate = create_example_circuit::(); + let output = format!("{circuit}"); + println!("{output}"); + } + + #[test] + fn test_circuit_scope() { + CurrentAleo::scope("test_circuit_scope", || { + assert_eq!(0, CurrentAleo::num_constants()); + assert_eq!(1, CurrentAleo::num_public()); + assert_eq!(0, CurrentAleo::num_private()); + assert_eq!(0, CurrentAleo::num_constraints()); + + assert_eq!(0, CurrentAleo::num_constants_in_scope()); + assert_eq!(0, CurrentAleo::num_public_in_scope()); + assert_eq!(0, CurrentAleo::num_private_in_scope()); + assert_eq!(0, CurrentAleo::num_constraints_in_scope()); + }) + } +} diff --git a/circuit/network/src/lib.rs b/circuit/network/src/lib.rs index d79538cf64..d2558eb9a9 100644 --- a/circuit/network/src/lib.rs +++ b/circuit/network/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,16 +16,26 @@ #![forbid(unsafe_code)] #![allow(clippy::too_many_arguments)] +pub mod canary_v0; +pub use canary_v0::*; + +pub mod testnet_v0; +pub use testnet_v0::*; + pub mod v0; pub use v0::*; use snarkvm_circuit_collections::merkle_tree::MerklePath; -use snarkvm_circuit_types::{environment::Environment, Boolean, Field, Group, Scalar}; +use snarkvm_circuit_types::{Boolean, Field, Group, Scalar, environment::Environment}; +/// Attention: Do not use `Send + Sync` on this trait, as it is not thread-safe. pub trait Aleo: Environment { /// The maximum number of field elements in data (must not exceed u16::MAX). const MAX_DATA_SIZE_IN_FIELDS: u32 = ::MAX_DATA_SIZE_IN_FIELDS; + /// Initializes the global constants for the Aleo environment. + fn initialize_global_constants(); + /// Returns the encryption domain as a constant field element. fn encryption_domain() -> Field; diff --git a/circuit/network/src/testnet_v0.rs b/circuit/network/src/testnet_v0.rs new file mode 100644 index 0000000000..0bfcd7437c --- /dev/null +++ b/circuit/network/src/testnet_v0.rs @@ -0,0 +1,599 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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::Aleo; +use snarkvm_circuit_algorithms::{ + BHP256, + BHP512, + BHP768, + BHP1024, + Commit, + CommitUncompressed, + Hash, + HashMany, + HashToGroup, + HashToScalar, + HashUncompressed, + Keccak256, + Keccak384, + Keccak512, + Pedersen64, + Pedersen128, + Poseidon2, + Poseidon4, + Poseidon8, + Sha3_256, + Sha3_384, + Sha3_512, +}; +use snarkvm_circuit_collections::merkle_tree::MerklePath; +use snarkvm_circuit_types::{ + Boolean, + Field, + Group, + Scalar, + environment::{Assignment, R1CS, TestnetCircuit, prelude::*}, +}; + +use core::fmt; + +type E = TestnetCircuit; + +thread_local! { + /// The group bases for the Aleo signature and encryption schemes. + static GENERATOR_G: Vec> = Vec::constant(::g_powers().to_vec()); + + /// The encryption domain as a constant field element. + static ENCRYPTION_DOMAIN: Field = Field::constant(::encryption_domain()); + /// The graph key domain as a constant field element. + static GRAPH_KEY_DOMAIN: Field = Field::constant(::graph_key_domain()); + /// The serial number domain as a constant field element. + static SERIAL_NUMBER_DOMAIN: Field = Field::constant(::serial_number_domain()); + + /// The BHP hash function, which can take an input of up to 256 bits. + static BHP_256: BHP256 = BHP256::::constant(console::TESTNET_BHP_256.clone()); + /// The BHP hash function, which can take an input of up to 512 bits. + static BHP_512: BHP512 = BHP512::::constant(console::TESTNET_BHP_512.clone()); + /// The BHP hash function, which can take an input of up to 768 bits. + static BHP_768: BHP768 = BHP768::::constant(console::TESTNET_BHP_768.clone()); + /// The BHP hash function, which can take an input of up to 1024 bits. + static BHP_1024: BHP1024 = BHP1024::::constant(console::TESTNET_BHP_1024.clone()); + + /// The Keccak hash function, which outputs 256 bits. + static KECCAK_256: Keccak256 = Keccak256::::new(); + /// The Keccak hash function, which outputs 384 bits. + static KECCAK_384: Keccak384 = Keccak384::::new(); + /// The Keccak hash function, which outputs 512 bits. + static KECCAK_512: Keccak512 = Keccak512::::new(); + + /// The Pedersen hash function, which can take an input of up to 64 bits. + static PEDERSEN_64: Pedersen64 = Pedersen64::::constant(console::TESTNET_PEDERSEN_64.clone()); + /// The Pedersen hash function, which can take an input of up to 128 bits. + static PEDERSEN_128: Pedersen128 = Pedersen128::::constant(console::TESTNET_PEDERSEN_128.clone()); + + /// The Poseidon hash function, using a rate of 2. + static POSEIDON_2: Poseidon2 = Poseidon2::::constant(console::TESTNET_POSEIDON_2.clone()); + /// The Poseidon hash function, using a rate of 4. + static POSEIDON_4: Poseidon4 = Poseidon4::::constant(console::TESTNET_POSEIDON_4.clone()); + /// The Poseidon hash function, using a rate of 8. + static POSEIDON_8: Poseidon8 = Poseidon8::::constant(console::TESTNET_POSEIDON_8.clone()); + + /// The SHA-3 hash function, which outputs 256 bits. + static SHA3_256: Sha3_256 = Sha3_256::::new(); + /// The SHA-3 hash function, which outputs 384 bits. + static SHA3_384: Sha3_384 = Sha3_384::::new(); + /// The SHA-3 hash function, which outputs 512 bits. + static SHA3_512: Sha3_512 = Sha3_512::::new(); +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub struct AleoTestnetV0; + +impl Aleo for AleoTestnetV0 { + /// Initializes the global constants for the Aleo environment. + fn initialize_global_constants() { + GENERATOR_G.with(|_| ()); + ENCRYPTION_DOMAIN.with(|_| ()); + GRAPH_KEY_DOMAIN.with(|_| ()); + SERIAL_NUMBER_DOMAIN.with(|_| ()); + BHP_256.with(|_| ()); + BHP_512.with(|_| ()); + BHP_768.with(|_| ()); + BHP_1024.with(|_| ()); + KECCAK_256.with(|_| ()); + KECCAK_384.with(|_| ()); + KECCAK_512.with(|_| ()); + PEDERSEN_64.with(|_| ()); + PEDERSEN_128.with(|_| ()); + POSEIDON_2.with(|_| ()); + POSEIDON_4.with(|_| ()); + POSEIDON_8.with(|_| ()); + SHA3_256.with(|_| ()); + SHA3_384.with(|_| ()); + SHA3_512.with(|_| ()); + } + + /// Returns the encryption domain as a constant field element. + fn encryption_domain() -> Field { + ENCRYPTION_DOMAIN.with(|domain| domain.clone()) + } + + /// Returns the graph key domain as a constant field element. + fn graph_key_domain() -> Field { + GRAPH_KEY_DOMAIN.with(|domain| domain.clone()) + } + + /// Returns the serial number domain as a constant field element. + fn serial_number_domain() -> Field { + SERIAL_NUMBER_DOMAIN.with(|domain| domain.clone()) + } + + /// Returns the scalar multiplication on the generator `G`. + #[inline] + fn g_scalar_multiply(scalar: &Scalar) -> Group { + GENERATOR_G.with(|bases| { + bases + .iter() + .zip_eq(&scalar.to_bits_le()) + .fold(Group::zero(), |output, (base, bit)| Group::ternary(bit, &(&output + base), &output)) + }) + } + + /// Returns a BHP commitment with an input hasher of 256-bits. + fn commit_bhp256(input: &[Boolean], randomizer: &Scalar) -> Field { + BHP_256.with(|bhp| bhp.commit(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 512-bits. + fn commit_bhp512(input: &[Boolean], randomizer: &Scalar) -> Field { + BHP_512.with(|bhp| bhp.commit(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 768-bits. + fn commit_bhp768(input: &[Boolean], randomizer: &Scalar) -> Field { + BHP_768.with(|bhp| bhp.commit(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 1024-bits. + fn commit_bhp1024(input: &[Boolean], randomizer: &Scalar) -> Field { + BHP_1024.with(|bhp| bhp.commit(input, randomizer)) + } + + /// Returns a Pedersen commitment for the given (up to) 64-bit input and randomizer. + fn commit_ped64(input: &[Boolean], randomizer: &Scalar) -> Field { + PEDERSEN_64.with(|pedersen| pedersen.commit(input, randomizer)) + } + + /// Returns a Pedersen commitment for the given (up to) 128-bit input and randomizer. + fn commit_ped128(input: &[Boolean], randomizer: &Scalar) -> Field { + PEDERSEN_128.with(|pedersen| pedersen.commit(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 256-bits. + fn commit_to_group_bhp256(input: &[Boolean], randomizer: &Scalar) -> Group { + BHP_256.with(|bhp| bhp.commit_uncompressed(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 512-bits. + fn commit_to_group_bhp512(input: &[Boolean], randomizer: &Scalar) -> Group { + BHP_512.with(|bhp| bhp.commit_uncompressed(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 768-bits. + fn commit_to_group_bhp768(input: &[Boolean], randomizer: &Scalar) -> Group { + BHP_768.with(|bhp| bhp.commit_uncompressed(input, randomizer)) + } + + /// Returns a BHP commitment with an input hasher of 1024-bits. + fn commit_to_group_bhp1024(input: &[Boolean], randomizer: &Scalar) -> Group { + BHP_1024.with(|bhp| bhp.commit_uncompressed(input, randomizer)) + } + + /// Returns a Pedersen commitment for the given (up to) 64-bit input and randomizer. + fn commit_to_group_ped64(input: &[Boolean], randomizer: &Scalar) -> Group { + PEDERSEN_64.with(|pedersen| pedersen.commit_uncompressed(input, randomizer)) + } + + /// Returns a Pedersen commitment for the given (up to) 128-bit input and randomizer. + fn commit_to_group_ped128(input: &[Boolean], randomizer: &Scalar) -> Group { + PEDERSEN_128.with(|pedersen| pedersen.commit_uncompressed(input, randomizer)) + } + + /// Returns the BHP hash with an input hasher of 256-bits. + fn hash_bhp256(input: &[Boolean]) -> Field { + BHP_256.with(|bhp| bhp.hash(input)) + } + + /// Returns the BHP hash with an input hasher of 512-bits. + fn hash_bhp512(input: &[Boolean]) -> Field { + BHP_512.with(|bhp| bhp.hash(input)) + } + + /// Returns the BHP hash with an input hasher of 768-bits. + fn hash_bhp768(input: &[Boolean]) -> Field { + BHP_768.with(|bhp| bhp.hash(input)) + } + + /// Returns the BHP hash with an input hasher of 1024-bits. + fn hash_bhp1024(input: &[Boolean]) -> Field { + BHP_1024.with(|bhp| bhp.hash(input)) + } + + /// Returns the Keccak hash with a 256-bit output. + fn hash_keccak256(input: &[Boolean]) -> Vec> { + KECCAK_256.with(|keccak| keccak.hash(input)) + } + + /// Returns the Keccak hash with a 384-bit output. + fn hash_keccak384(input: &[Boolean]) -> Vec> { + KECCAK_384.with(|keccak| keccak.hash(input)) + } + + /// Returns the Keccak hash with a 512-bit output. + fn hash_keccak512(input: &[Boolean]) -> Vec> { + KECCAK_512.with(|keccak| keccak.hash(input)) + } + + /// Returns the Pedersen hash for a given (up to) 64-bit input. + fn hash_ped64(input: &[Boolean]) -> Field { + PEDERSEN_64.with(|pedersen| pedersen.hash(input)) + } + + /// Returns the Pedersen hash for a given (up to) 128-bit input. + fn hash_ped128(input: &[Boolean]) -> Field { + PEDERSEN_128.with(|pedersen| pedersen.hash(input)) + } + + /// Returns the Poseidon hash with an input rate of 2. + fn hash_psd2(input: &[Field]) -> Field { + POSEIDON_2.with(|poseidon| poseidon.hash(input)) + } + + /// Returns the Poseidon hash with an input rate of 4. + fn hash_psd4(input: &[Field]) -> Field { + POSEIDON_4.with(|poseidon| poseidon.hash(input)) + } + + /// Returns the Poseidon hash with an input rate of 8. + fn hash_psd8(input: &[Field]) -> Field { + POSEIDON_8.with(|poseidon| poseidon.hash(input)) + } + + /// Returns the SHA-3 hash with a 256-bit output. + fn hash_sha3_256(input: &[Boolean]) -> Vec> { + SHA3_256.with(|sha3| sha3.hash(input)) + } + + /// Returns the SHA-3 hash with a 384-bit output. + fn hash_sha3_384(input: &[Boolean]) -> Vec> { + SHA3_384.with(|sha3| sha3.hash(input)) + } + + /// Returns the SHA-3 hash with a 512-bit output. + fn hash_sha3_512(input: &[Boolean]) -> Vec> { + SHA3_512.with(|sha3| sha3.hash(input)) + } + + /// Returns the extended Poseidon hash with an input rate of 2. + fn hash_many_psd2(input: &[Field], num_outputs: u16) -> Vec> { + POSEIDON_2.with(|poseidon| poseidon.hash_many(input, num_outputs)) + } + + /// Returns the extended Poseidon hash with an input rate of 4. + fn hash_many_psd4(input: &[Field], num_outputs: u16) -> Vec> { + POSEIDON_4.with(|poseidon| poseidon.hash_many(input, num_outputs)) + } + + /// Returns the extended Poseidon hash with an input rate of 8. + fn hash_many_psd8(input: &[Field], num_outputs: u16) -> Vec> { + POSEIDON_8.with(|poseidon| poseidon.hash_many(input, num_outputs)) + } + + /// Returns the BHP hash with an input hasher of 256-bits. + fn hash_to_group_bhp256(input: &[Boolean]) -> Group { + BHP_256.with(|bhp| bhp.hash_uncompressed(input)) + } + + /// Returns the BHP hash with an input hasher of 512-bits. + fn hash_to_group_bhp512(input: &[Boolean]) -> Group { + BHP_512.with(|bhp| bhp.hash_uncompressed(input)) + } + + /// Returns the BHP hash with an input hasher of 768-bits. + fn hash_to_group_bhp768(input: &[Boolean]) -> Group { + BHP_768.with(|bhp| bhp.hash_uncompressed(input)) + } + + /// Returns the BHP hash with an input hasher of 1024-bits. + fn hash_to_group_bhp1024(input: &[Boolean]) -> Group { + BHP_1024.with(|bhp| bhp.hash_uncompressed(input)) + } + + /// Returns the Pedersen hash for a given (up to) 64-bit input. + fn hash_to_group_ped64(input: &[Boolean]) -> Group { + PEDERSEN_64.with(|pedersen| pedersen.hash_uncompressed(input)) + } + + /// Returns the Pedersen hash for a given (up to) 128-bit input. + fn hash_to_group_ped128(input: &[Boolean]) -> Group { + PEDERSEN_128.with(|pedersen| pedersen.hash_uncompressed(input)) + } + + /// Returns the Poseidon hash with an input rate of 2 on the affine curve. + fn hash_to_group_psd2(input: &[Field]) -> Group { + POSEIDON_2.with(|poseidon| poseidon.hash_to_group(input)) + } + + /// Returns the Poseidon hash with an input rate of 4 on the affine curve. + fn hash_to_group_psd4(input: &[Field]) -> Group { + POSEIDON_4.with(|poseidon| poseidon.hash_to_group(input)) + } + + /// Returns the Poseidon hash with an input rate of 8 on the affine curve. + fn hash_to_group_psd8(input: &[Field]) -> Group { + POSEIDON_8.with(|poseidon| poseidon.hash_to_group(input)) + } + + /// Returns the Poseidon hash with an input rate of 2 on the scalar field. + fn hash_to_scalar_psd2(input: &[Field]) -> Scalar { + POSEIDON_2.with(|poseidon| poseidon.hash_to_scalar(input)) + } + + /// Returns the Poseidon hash with an input rate of 4 on the scalar field. + fn hash_to_scalar_psd4(input: &[Field]) -> Scalar { + POSEIDON_4.with(|poseidon| poseidon.hash_to_scalar(input)) + } + + /// Returns the Poseidon hash with an input rate of 8 on the scalar field. + fn hash_to_scalar_psd8(input: &[Field]) -> Scalar { + POSEIDON_8.with(|poseidon| poseidon.hash_to_scalar(input)) + } + + /// Returns `true` if the given Merkle path is valid for the given root and leaf. + fn verify_merkle_path_bhp( + path: &MerklePath, + root: &Field, + leaf: &Vec>, + ) -> Boolean { + BHP_1024.with(|bhp1024| BHP_512.with(|bhp512| path.verify(bhp1024, bhp512, root, leaf))) + } + + /// Returns `true` if the given Merkle path is valid for the given root and leaf. + fn verify_merkle_path_psd( + path: &MerklePath, + root: &Field, + leaf: &Vec>, + ) -> Boolean { + POSEIDON_4.with(|psd4| POSEIDON_2.with(|psd2| path.verify(psd4, psd2, root, leaf))) + } +} + +impl Environment for AleoTestnetV0 { + type Affine = ::Affine; + type BaseField = ::BaseField; + type Network = ::Network; + type ScalarField = ::ScalarField; + + /// Returns the `zero` constant. + fn zero() -> LinearCombination { + E::zero() + } + + /// Returns the `one` constant. + fn one() -> LinearCombination { + E::one() + } + + /// Returns a new variable of the given mode and value. + fn new_variable(mode: Mode, value: Self::BaseField) -> Variable { + E::new_variable(mode, value) + } + + /// Returns a new witness of the given mode and value. + fn new_witness Output::Primitive, Output: Inject>(mode: Mode, logic: Fn) -> Output { + E::new_witness(mode, logic) + } + + /// Enters a new scope for the environment. + fn scope, Fn, Output>(name: S, logic: Fn) -> Output + where + Fn: FnOnce() -> Output, + { + E::scope(name, logic) + } + + /// Adds one constraint enforcing that `(A * B) == C`. + fn enforce(constraint: Fn) + where + Fn: FnOnce() -> (A, B, C), + A: Into>, + B: Into>, + C: Into>, + { + E::enforce(constraint) + } + + /// Returns `true` if all constraints in the environment are satisfied. + fn is_satisfied() -> bool { + E::is_satisfied() + } + + /// Returns `true` if all constraints in the current scope are satisfied. + fn is_satisfied_in_scope() -> bool { + E::is_satisfied_in_scope() + } + + /// Returns the number of constants in the entire circuit. + fn num_constants() -> u64 { + E::num_constants() + } + + /// Returns the number of public variables in the entire circuit. + fn num_public() -> u64 { + E::num_public() + } + + /// Returns the number of private variables in the entire circuit. + fn num_private() -> u64 { + E::num_private() + } + + /// Returns the number of constant, public, and private variables in the entire circuit. + fn num_variables() -> u64 { + E::num_variables() + } + + /// Returns the number of constraints in the entire circuit. + fn num_constraints() -> u64 { + E::num_constraints() + } + + /// Returns the number of nonzeros in the entire circuit. + fn num_nonzeros() -> (u64, u64, u64) { + E::num_nonzeros() + } + + /// Returns the number of constants for the current scope. + fn num_constants_in_scope() -> u64 { + E::num_constants_in_scope() + } + + /// Returns the number of public variables for the current scope. + fn num_public_in_scope() -> u64 { + E::num_public_in_scope() + } + + /// Returns the number of private variables for the current scope. + fn num_private_in_scope() -> u64 { + E::num_private_in_scope() + } + + /// Returns the number of constraints for the current scope. + fn num_constraints_in_scope() -> u64 { + E::num_constraints_in_scope() + } + + /// Returns the number of nonzeros for the current scope. + fn num_nonzeros_in_scope() -> (u64, u64, u64) { + E::num_nonzeros_in_scope() + } + + /// Returns the variable limit for the circuit, if one exists. + fn get_variable_limit() -> Option { + E::get_variable_limit() + } + + /// Sets the variable limit for the circuit. + fn set_variable_limit(limit: Option) { + E::set_variable_limit(limit) + } + + /// Returns the constraint limit for the circuit, if one exists. + fn get_constraint_limit() -> Option { + E::get_constraint_limit() + } + + /// Sets the constraint limit for the circuit. + fn set_constraint_limit(limit: Option) { + E::set_constraint_limit(limit) + } + + /// Halts the program from further synthesis, evaluation, and execution in the current environment. + fn halt, T>(message: S) -> T { + E::halt(message) + } + + /// Returns the R1CS circuit, resetting the circuit. + fn inject_r1cs(r1cs: R1CS) { + E::inject_r1cs(r1cs) + } + + /// Returns the R1CS circuit, resetting the circuit. + fn eject_r1cs_and_reset() -> R1CS { + E::eject_r1cs_and_reset() + } + + /// Returns the R1CS assignment of the circuit, resetting the circuit. + fn eject_assignment_and_reset() -> Assignment<::Field> { + E::eject_assignment_and_reset() + } + + /// Clears the circuit and initializes an empty environment. + fn reset() { + E::reset() + } +} + +impl Display for AleoTestnetV0 { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + // TODO (howardwu): Find a better way to print the circuit. + fmt::Display::fmt(&TestnetCircuit, f) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use snarkvm_circuit_types::Field; + + type CurrentAleo = AleoTestnetV0; + + /// Compute 2^EXPONENT - 1, in a purposefully constraint-inefficient manner for testing. + fn create_example_circuit() -> Field { + let one = snarkvm_console_types::Field::<::Network>::one(); + let two = one + one; + + const EXPONENT: u64 = 64; + + // Compute 2^EXPONENT - 1, in a purposefully constraint-inefficient manner for testing. + let mut candidate = Field::::new(Mode::Public, one); + let mut accumulator = Field::new(Mode::Private, two); + for _ in 0..EXPONENT { + candidate += &accumulator; + accumulator *= Field::new(Mode::Private, two); + } + + assert_eq!((accumulator - Field::one()).eject_value(), candidate.eject_value()); + assert_eq!(2, E::num_public()); + assert_eq!(2 * EXPONENT + 1, E::num_private()); + assert_eq!(EXPONENT, E::num_constraints()); + assert!(E::is_satisfied()); + + candidate + } + + #[test] + fn test_print_circuit() { + let circuit = CurrentAleo {}; + let _candidate = create_example_circuit::(); + let output = format!("{circuit}"); + println!("{output}"); + } + + #[test] + fn test_circuit_scope() { + CurrentAleo::scope("test_circuit_scope", || { + assert_eq!(0, CurrentAleo::num_constants()); + assert_eq!(1, CurrentAleo::num_public()); + assert_eq!(0, CurrentAleo::num_private()); + assert_eq!(0, CurrentAleo::num_constraints()); + + assert_eq!(0, CurrentAleo::num_constants_in_scope()); + assert_eq!(0, CurrentAleo::num_public_in_scope()); + assert_eq!(0, CurrentAleo::num_private_in_scope()); + assert_eq!(0, CurrentAleo::num_constraints_in_scope()); + }) + } +} diff --git a/circuit/network/src/v0.rs b/circuit/network/src/v0.rs index 9dc7a9d8da..5d595220b0 100644 --- a/circuit/network/src/v0.rs +++ b/circuit/network/src/v0.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,6 +15,10 @@ use crate::Aleo; use snarkvm_circuit_algorithms::{ + BHP256, + BHP512, + BHP768, + BHP1024, Commit, CommitUncompressed, Hash, @@ -24,26 +29,22 @@ use snarkvm_circuit_algorithms::{ Keccak256, Keccak384, Keccak512, - Pedersen128, Pedersen64, + Pedersen128, Poseidon2, Poseidon4, Poseidon8, Sha3_256, Sha3_384, Sha3_512, - BHP1024, - BHP256, - BHP512, - BHP768, }; use snarkvm_circuit_collections::merkle_tree::MerklePath; use snarkvm_circuit_types::{ - environment::{prelude::*, Assignment, Circuit, R1CS}, Boolean, Field, Group, Scalar, + environment::{Assignment, Circuit, R1CS, prelude::*}, }; use core::fmt; @@ -52,14 +53,14 @@ type E = Circuit; thread_local! { /// The group bases for the Aleo signature and encryption schemes. - static GENERATOR_G: Vec> = Vec::constant(::g_powers().to_vec()); + static GENERATOR_G: Vec> = Vec::constant(::g_powers().to_vec()); /// The encryption domain as a constant field element. - static ENCRYPTION_DOMAIN: Field = Field::constant(::encryption_domain()); + static ENCRYPTION_DOMAIN: Field = Field::constant(::encryption_domain()); /// The graph key domain as a constant field element. - static GRAPH_KEY_DOMAIN: Field = Field::constant(::graph_key_domain()); + static GRAPH_KEY_DOMAIN: Field = Field::constant(::graph_key_domain()); /// The serial number domain as a constant field element. - static SERIAL_NUMBER_DOMAIN: Field = Field::constant(::serial_number_domain()); + static SERIAL_NUMBER_DOMAIN: Field = Field::constant(::serial_number_domain()); /// The BHP hash function, which can take an input of up to 256 bits. static BHP_256: BHP256 = BHP256::::constant(console::BHP_256.clone()); @@ -101,6 +102,29 @@ thread_local! { pub struct AleoV0; impl Aleo for AleoV0 { + /// Initializes the global constants for the Aleo environment. + fn initialize_global_constants() { + GENERATOR_G.with(|_| ()); + ENCRYPTION_DOMAIN.with(|_| ()); + GRAPH_KEY_DOMAIN.with(|_| ()); + SERIAL_NUMBER_DOMAIN.with(|_| ()); + BHP_256.with(|_| ()); + BHP_512.with(|_| ()); + BHP_768.with(|_| ()); + BHP_1024.with(|_| ()); + KECCAK_256.with(|_| ()); + KECCAK_384.with(|_| ()); + KECCAK_512.with(|_| ()); + PEDERSEN_64.with(|_| ()); + PEDERSEN_128.with(|_| ()); + POSEIDON_2.with(|_| ()); + POSEIDON_4.with(|_| ()); + POSEIDON_8.with(|_| ()); + SHA3_256.with(|_| ()); + SHA3_384.with(|_| ()); + SHA3_512.with(|_| ()); + } + /// Returns the encryption domain as a constant field element. fn encryption_domain() -> Field { ENCRYPTION_DOMAIN.with(|domain| domain.clone()) @@ -426,6 +450,11 @@ impl Environment for AleoV0 { E::num_private() } + /// Returns the number of constant, public, and private variables in the entire circuit. + fn num_variables() -> u64 { + E::num_variables() + } + /// Returns the number of constraints in the entire circuit. fn num_constraints() -> u64 { E::num_constraints() @@ -461,6 +490,26 @@ impl Environment for AleoV0 { E::num_nonzeros_in_scope() } + /// Returns the variable limit for the circuit, if one exists. + fn get_variable_limit() -> Option { + E::get_variable_limit() + } + + /// Sets the variable limit for the circuit. + fn set_variable_limit(limit: Option) { + E::set_variable_limit(limit) + } + + /// Returns the constraint limit for the circuit, if one exists. + fn get_constraint_limit() -> Option { + E::get_constraint_limit() + } + + /// Sets the constraint limit for the circuit. + fn set_constraint_limit(limit: Option) { + E::set_constraint_limit(limit) + } + /// Halts the program from further synthesis, evaluation, and execution in the current environment. fn halt, T>(message: S) -> T { E::halt(message) diff --git a/circuit/program/Cargo.toml b/circuit/program/Cargo.toml index 2a222e0093..7201375106 100644 --- a/circuit/program/Cargo.toml +++ b/circuit/program/Cargo.toml @@ -1,40 +1,42 @@ [package] name = "snarkvm-circuit-program" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Program circuit library for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.console] package = "snarkvm-console-program" path = "../../console/program" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit-account] path = "../account" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-algorithms] path = "../algorithms" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-collections] path = "../collections" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-network] path = "../network" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types] path = "../types" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-utilities] path = "../../utilities" -version = "=0.16.19" +version = "=1.1.0" [dependencies.paste] version = "1.0" diff --git a/circuit/program/build.rs b/circuit/program/build.rs index ff14549b2c..1d0fe74e7c 100644 --- a/circuit/program/build.rs +++ b/circuit/program/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/access/mod.rs b/circuit/program/src/data/access/mod.rs index 04928f3e96..62f919dc54 100644 --- a/circuit/program/src/data/access/mod.rs +++ b/circuit/program/src/data/access/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use crate::Identifier; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, U32}; +use snarkvm_circuit_types::{U32, environment::prelude::*}; use std::{ fmt, @@ -31,7 +32,7 @@ pub enum Access { Index(U32), } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Access { type Primitive = console::Access; @@ -45,7 +46,7 @@ impl Inject for Access { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Access { type Primitive = console::Access; @@ -66,7 +67,7 @@ impl Eject for Access { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Parser for Access { /// Parses a UTF-8 string into an access. #[inline] @@ -78,7 +79,7 @@ impl Parser for Access { } } -#[cfg(console)] +#[cfg(feature = "console")] impl FromStr for Access { type Err = Error; @@ -97,14 +98,14 @@ impl FromStr for Access { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Debug for Access { fn fmt(&self, f: &mut Formatter) -> fmt::Result { Display::fmt(self, f) } } -#[cfg(console)] +#[cfg(feature = "console")] impl Display for Access { /// Prints the identifier as a string. fn fmt(&self, f: &mut Formatter) -> fmt::Result { diff --git a/circuit/program/src/data/ciphertext/decrypt.rs b/circuit/program/src/data/ciphertext/decrypt.rs index e734b56a9c..007dd1baaf 100644 --- a/circuit/program/src/data/ciphertext/decrypt.rs +++ b/circuit/program/src/data/ciphertext/decrypt.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -38,7 +39,7 @@ impl Ciphertext { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::{Circuit, Literal}; diff --git a/circuit/program/src/data/ciphertext/equal.rs b/circuit/program/src/data/ciphertext/equal.rs index b31007a190..3dcf7c18ce 100644 --- a/circuit/program/src/data/ciphertext/equal.rs +++ b/circuit/program/src/data/ciphertext/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/ciphertext/from_bits.rs b/circuit/program/src/data/ciphertext/from_bits.rs index 2e3ed21e1e..fc21034810 100644 --- a/circuit/program/src/data/ciphertext/from_bits.rs +++ b/circuit/program/src/data/ciphertext/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/ciphertext/from_fields.rs b/circuit/program/src/data/ciphertext/from_fields.rs index 0fa73cd0f6..b42125de83 100644 --- a/circuit/program/src/data/ciphertext/from_fields.rs +++ b/circuit/program/src/data/ciphertext/from_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/ciphertext/mod.rs b/circuit/program/src/data/ciphertext/mod.rs index 24b73dc65d..29b553e442 100644 --- a/circuit/program/src/data/ciphertext/mod.rs +++ b/circuit/program/src/data/ciphertext/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -23,14 +24,14 @@ mod to_fields; use crate::{Plaintext, Visibility}; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Boolean, Field}; +use snarkvm_circuit_types::{Boolean, Field, environment::prelude::*}; use core::ops::Deref; #[derive(Clone)] pub struct Ciphertext(Vec>); -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Ciphertext { type Primitive = console::Ciphertext; @@ -44,7 +45,7 @@ impl Inject for Ciphertext { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Ciphertext { type Primitive = console::Ciphertext; diff --git a/circuit/program/src/data/ciphertext/num_randomizers.rs b/circuit/program/src/data/ciphertext/num_randomizers.rs index 20370cff0d..af0faba0a6 100644 --- a/circuit/program/src/data/ciphertext/num_randomizers.rs +++ b/circuit/program/src/data/ciphertext/num_randomizers.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/ciphertext/size_in_fields.rs b/circuit/program/src/data/ciphertext/size_in_fields.rs index 1b98c6d428..0374a8e943 100644 --- a/circuit/program/src/data/ciphertext/size_in_fields.rs +++ b/circuit/program/src/data/ciphertext/size_in_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/ciphertext/to_bits.rs b/circuit/program/src/data/ciphertext/to_bits.rs index 6814096498..f263b3e36c 100644 --- a/circuit/program/src/data/ciphertext/to_bits.rs +++ b/circuit/program/src/data/ciphertext/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/ciphertext/to_fields.rs b/circuit/program/src/data/ciphertext/to_fields.rs index 0287585919..6d5763dbf8 100644 --- a/circuit/program/src/data/ciphertext/to_fields.rs +++ b/circuit/program/src/data/ciphertext/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/future/argument.rs b/circuit/program/src/data/future/argument.rs index 7037efbb08..47da91d032 100644 --- a/circuit/program/src/data/future/argument.rs +++ b/circuit/program/src/data/future/argument.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/future/equal.rs b/circuit/program/src/data/future/equal.rs index 91dd2badf8..e3cc06a0b9 100644 --- a/circuit/program/src/data/future/equal.rs +++ b/circuit/program/src/data/future/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/future/find.rs b/circuit/program/src/data/future/find.rs index 4f99a98673..d2d1c70a7b 100644 --- a/circuit/program/src/data/future/find.rs +++ b/circuit/program/src/data/future/find.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/future/mod.rs b/circuit/program/src/data/future/mod.rs index d9e74f3ba3..31d9bcc4c6 100644 --- a/circuit/program/src/data/future/mod.rs +++ b/circuit/program/src/data/future/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -22,7 +23,7 @@ mod to_fields; use crate::{Access, Identifier, Plaintext, ProgramID, Value}; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Boolean, Field, U16}; +use snarkvm_circuit_types::{Boolean, Field, U16, environment::prelude::*}; /// A future. #[derive(Clone)] diff --git a/circuit/program/src/data/future/to_bits.rs b/circuit/program/src/data/future/to_bits.rs index 3d5a86fdeb..92346fccb5 100644 --- a/circuit/program/src/data/future/to_bits.rs +++ b/circuit/program/src/data/future/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/future/to_fields.rs b/circuit/program/src/data/future/to_fields.rs index 3952031e1f..f45f66b12c 100644 --- a/circuit/program/src/data/future/to_fields.rs +++ b/circuit/program/src/data/future/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/identifier/equal.rs b/circuit/program/src/data/identifier/equal.rs index a3a3aa859a..378bf11485 100644 --- a/circuit/program/src/data/identifier/equal.rs +++ b/circuit/program/src/data/identifier/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/identifier/from_bits.rs b/circuit/program/src/data/identifier/from_bits.rs index f1b8d0fc8a..1ba41b149b 100644 --- a/circuit/program/src/data/identifier/from_bits.rs +++ b/circuit/program/src/data/identifier/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -48,10 +49,10 @@ impl FromBits for Identifier { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{data::identifier::tests::sample_console_identifier, Circuit}; + use crate::{Circuit, data::identifier::tests::sample_console_identifier}; use anyhow::Result; diff --git a/circuit/program/src/data/identifier/from_field.rs b/circuit/program/src/data/identifier/from_field.rs index a65a4cf445..4d9124e12b 100644 --- a/circuit/program/src/data/identifier/from_field.rs +++ b/circuit/program/src/data/identifier/from_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,10 +25,10 @@ impl FromField for Identifier { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{data::identifier::tests::sample_console_identifier, Circuit}; + use crate::{Circuit, data::identifier::tests::sample_console_identifier}; use anyhow::Result; diff --git a/circuit/program/src/data/identifier/mod.rs b/circuit/program/src/data/identifier/mod.rs index a2a75b0e18..8cff8d1009 100644 --- a/circuit/program/src/data/identifier/mod.rs +++ b/circuit/program/src/data/identifier/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -23,7 +24,7 @@ mod to_bits; mod to_field; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Boolean, Field, U8}; +use snarkvm_circuit_types::{Boolean, Field, U8, environment::prelude::*}; use snarkvm_utilities::ToBits as TB; /// An identifier is an **immutable** UTF-8 string, @@ -38,7 +39,7 @@ use snarkvm_utilities::ToBits as TB; #[derive(Clone)] pub struct Identifier(Field, u8); // Number of bytes in the identifier. -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Identifier { type Primitive = console::Identifier; @@ -57,7 +58,7 @@ impl Inject for Identifier { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Identifier { type Primitive = console::Identifier; @@ -76,7 +77,7 @@ impl Eject for Identifier { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Parser for Identifier { /// Parses a UTF-8 string into an identifier. #[inline] @@ -88,7 +89,7 @@ impl Parser for Identifier { } } -#[cfg(console)] +#[cfg(feature = "console")] impl FromStr for Identifier { type Err = Error; @@ -107,14 +108,14 @@ impl FromStr for Identifier { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Debug for Identifier { fn fmt(&self, f: &mut Formatter) -> fmt::Result { Display::fmt(self, f) } } -#[cfg(console)] +#[cfg(feature = "console")] impl Display for Identifier { /// Prints the identifier as a string. fn fmt(&self, f: &mut Formatter) -> fmt::Result { @@ -152,13 +153,13 @@ impl From<&Identifier> for LinearCombination { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] pub(crate) mod tests { use super::*; use crate::Circuit; use console::{Rng, TestRng}; - use anyhow::{bail, Result}; + use anyhow::{Result, bail}; use core::str::FromStr; use rand::distributions::Alphanumeric; diff --git a/circuit/program/src/data/identifier/size_in_bits.rs b/circuit/program/src/data/identifier/size_in_bits.rs index dc6f29dc5b..344c61dee9 100644 --- a/circuit/program/src/data/identifier/size_in_bits.rs +++ b/circuit/program/src/data/identifier/size_in_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/identifier/to_bits.rs b/circuit/program/src/data/identifier/to_bits.rs index 6bbaf91b4b..24094acfd7 100644 --- a/circuit/program/src/data/identifier/to_bits.rs +++ b/circuit/program/src/data/identifier/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -46,10 +47,10 @@ impl ToBits for &Identifier { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; - use crate::{data::identifier::tests::sample_console_identifier, Circuit}; + use crate::{Circuit, data::identifier::tests::sample_console_identifier}; use anyhow::Result; diff --git a/circuit/program/src/data/identifier/to_field.rs b/circuit/program/src/data/identifier/to_field.rs index 6e8e04814c..1bfe10444a 100644 --- a/circuit/program/src/data/identifier/to_field.rs +++ b/circuit/program/src/data/identifier/to_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/literal/cast/boolean.rs b/circuit/program/src/data/literal/cast/boolean.rs index 955df86b40..cfe01a9142 100644 --- a/circuit/program/src/data/literal/cast/boolean.rs +++ b/circuit/program/src/data/literal/cast/boolean.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -66,8 +67,8 @@ impl Cast> for Boolean { mod tests { use super::*; use console::Cast as _; - use console_root::{network::Testnet3, prelude::TestRng}; - use snarkvm_circuit_types::environment::{count_is, Circuit, Eject, Inject, Mode, UpdatableCount}; + use console_root::{network::MainnetV0, prelude::TestRng}; + use snarkvm_circuit_types::environment::{Circuit, Eject, Inject, Mode, UpdatableCount, count_is}; use std::fmt::Debug; @@ -77,114 +78,114 @@ mod tests { i: usize, mode: Mode, _: &mut TestRng, - ) -> (console_root::types::Boolean, Boolean) { + ) -> (console_root::types::Boolean, Boolean) { (console_root::types::Boolean::new(i % 2 == 0), Boolean::new(mode, i % 2 == 0)) } - impl_check_cast!(cast, Boolean, console_root::types::Boolean::); + impl_check_cast!(cast, Boolean, console_root::types::Boolean::); #[test] fn test_boolean_to_address() { - check_cast::, console_root::types::Address>(Mode::Constant, count_is!(10, 0, 0, 0)); - check_cast::, console_root::types::Address>(Mode::Public, count_is!(10, 0, 0, 0)); - check_cast::, console_root::types::Address>(Mode::Private, count_is!(10, 0, 0, 0)); + check_cast::, console_root::types::Address>(Mode::Constant, count_is!(10, 0, 0, 0)); + check_cast::, console_root::types::Address>(Mode::Public, count_is!(10, 0, 0, 0)); + check_cast::, console_root::types::Address>(Mode::Private, count_is!(10, 0, 0, 0)); } #[test] fn test_boolean_to_boolean() { - check_cast::, console_root::types::Boolean>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Boolean>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Boolean>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Boolean>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Boolean>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Boolean>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_boolean_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_boolean_to_group() { - check_cast::, console_root::types::Group>(Mode::Constant, count_is!(10, 0, 0, 0)); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(10, 0, 0, 0)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(10, 0, 0, 0)); + check_cast::, console_root::types::Group>(Mode::Constant, count_is!(10, 0, 0, 0)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(10, 0, 0, 0)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(10, 0, 0, 0)); } #[test] fn test_boolean_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(16, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(16, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(16, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(16, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(16, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(16, 0, 0, 0)); } #[test] fn test_boolean_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(32, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(32, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(32, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(32, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(32, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(32, 0, 0, 0)); } #[test] fn test_boolean_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(64, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(64, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(64, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(64, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(64, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(64, 0, 0, 0)); } #[test] fn test_boolean_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(128, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(128, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(128, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(128, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(128, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(128, 0, 0, 0)); } #[test] fn test_boolean_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(256, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(256, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(256, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(256, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(256, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(256, 0, 0, 0)); } #[test] fn test_boolean_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(2, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(2, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(2, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(2, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(2, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(2, 0, 0, 0)); } #[test] fn test_boolean_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(16, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(16, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(16, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(16, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(16, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(16, 0, 0, 0)); } #[test] fn test_boolean_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(32, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(32, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(32, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(32, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(32, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(32, 0, 0, 0)); } #[test] fn test_boolean_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(64, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(64, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(64, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(64, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(64, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(64, 0, 0, 0)); } #[test] fn test_boolean_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(128, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(128, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(128, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(128, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(128, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(128, 0, 0, 0)); } #[test] fn test_boolean_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(256, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(256, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(256, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(256, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(256, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(256, 0, 0, 0)); } } diff --git a/circuit/program/src/data/literal/cast/field.rs b/circuit/program/src/data/literal/cast/field.rs index 9c515ab930..bd9e712b9b 100644 --- a/circuit/program/src/data/literal/cast/field.rs +++ b/circuit/program/src/data/literal/cast/field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -85,10 +86,10 @@ mod tests { use super::*; use console::Cast as _; use console_root::{ - network::Testnet3, + network::MainnetV0, prelude::{One, TestRng, Uniform, Zero}, }; - use snarkvm_circuit_types::environment::{count_is, count_less_than, Circuit, Eject, Inject, Mode, UpdatableCount}; + use snarkvm_circuit_types::environment::{Circuit, Eject, Inject, Mode, UpdatableCount, count_is, count_less_than}; use std::fmt::Debug; @@ -98,126 +99,126 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::Field, Field) { + ) -> (console_root::types::Field, Field) { let console_value = match i { - 0 => console_root::types::Field::::zero(), - 1 => console_root::types::Field::::one(), + 0 => console_root::types::Field::::zero(), + 1 => console_root::types::Field::::one(), _ => Uniform::rand(rng), }; let circuit_value = Field::::new(mode, console_value); (console_value, circuit_value) } - impl_check_cast!(cast, Field, console_root::types::Field::); + impl_check_cast!(cast, Field, console_root::types::Field::); #[test] fn test_field_to_address() { - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Address>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Address>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Address>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Address>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_field_to_boolean() { - check_cast::, console_root::types::Boolean>(Mode::Constant, count_is!(2, 0, 0, 0)); - check_cast::, console_root::types::Boolean>(Mode::Public, count_is!(0, 0, 5, 6)); - check_cast::, console_root::types::Boolean>(Mode::Private, count_is!(0, 0, 5, 6)); + check_cast::, console_root::types::Boolean>(Mode::Constant, count_is!(2, 0, 0, 0)); + check_cast::, console_root::types::Boolean>(Mode::Public, count_is!(0, 0, 5, 6)); + check_cast::, console_root::types::Boolean>(Mode::Private, count_is!(0, 0, 5, 6)); } #[test] fn test_field_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_field_to_group() { - check_cast::, console_root::types::Group>( + check_cast::, console_root::types::Group>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_field_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(8, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 8, 9)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 8, 9)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(8, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 8, 9)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 8, 9)); } #[test] fn test_field_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(16, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 16, 17)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 16, 17)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(16, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 16, 17)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 16, 17)); } #[test] fn test_field_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(32, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 32, 33)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 32, 33)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(32, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 32, 33)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 32, 33)); } #[test] fn test_field_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(64, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 64, 65)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 64, 65)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(64, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 64, 65)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 64, 65)); } #[test] fn test_field_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(128, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 128, 129)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 128, 129)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(128, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 128, 129)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 128, 129)); } #[test] fn test_field_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(253, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 755, 759)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 755, 759)); + check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(253, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 755, 759)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 755, 759)); } #[test] fn test_field_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(8, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 8, 9)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 8, 9)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(8, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 8, 9)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 8, 9)); } #[test] fn test_field_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(16, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 16, 17)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 16, 17)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(16, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 16, 17)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 16, 17)); } #[test] fn test_field_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(32, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 32, 33)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 32, 33)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(32, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 32, 33)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 32, 33)); } #[test] fn test_field_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(64, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 64, 65)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 64, 65)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(64, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 64, 65)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 64, 65)); } #[test] fn test_field_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(128, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 128, 129)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 128, 129)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(128, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 128, 129)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 128, 129)); } } diff --git a/circuit/program/src/data/literal/cast/integer.rs b/circuit/program/src/data/literal/cast/integer.rs index 6c5aae4e5b..aad1cc56f0 100644 --- a/circuit/program/src/data/literal/cast/integer.rs +++ b/circuit/program/src/data/literal/cast/integer.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -79,7 +80,7 @@ impl Cast> for // Then instantiate the new integer from the lower bits. false => { Boolean::assert_bits_are_zero(&bits_le[(I1::BITS.saturating_sub(1) as usize)..]); - Integer::::from_bits_le(&bits_le[..(I1::BITS.saturating_sub(1) as usize)]) + Integer::::from_bits_le(&bits_le[..(I1::BITS as usize)]) } }, // If the source type is signed and the destination type is unsigned, perform the required checks. @@ -88,7 +89,7 @@ impl Cast> for // Then instantiate the new integer from the lower bits. true => { E::assert(!&bits_le[I0::BITS.saturating_sub(1) as usize]); - Integer::::from_bits_le(&bits_le[..(I0::BITS.saturating_sub(1) as usize)]) + Integer::::from_bits_le(&bits_le) } // If the source type is larger than the destination type, check that the upper bits are zero. // Then instantiate the new integer from the lower bits. @@ -143,10 +144,10 @@ mod tests { use super::*; use console::Cast as _; use console_root::{ - network::Testnet3, + network::MainnetV0, prelude::{One, TestRng, Uniform, Zero}, }; - use snarkvm_circuit_types::environment::{count_is, count_less_than, Circuit, Eject, Inject, Mode, UpdatableCount}; + use snarkvm_circuit_types::environment::{Circuit, Eject, Inject, Mode, UpdatableCount, count_is, count_less_than}; use std::fmt::Debug; @@ -156,13 +157,13 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::integers::Integer, Integer) { + ) -> (console_root::types::integers::Integer, Integer) { let console_value = match i { - 0 => console_root::types::integers::Integer::::zero(), - 1 => console_root::types::integers::Integer::::one(), - 2 => console_root::types::integers::Integer::::new(I::MAX), - 3 => console_root::types::integers::Integer::::new(I::MIN), - 4 if I::is_signed() => -console_root::types::integers::Integer::::one(), + 0 => console_root::types::integers::Integer::::zero(), + 1 => console_root::types::integers::Integer::::one(), + 2 => console_root::types::integers::Integer::::new(I::MAX), + 3 => console_root::types::integers::Integer::::new(I::MIN), + 4 if I::is_signed() => -console_root::types::integers::Integer::::one(), _ => Uniform::rand(rng), }; let circuit_value = Integer::::new(mode, console_value); @@ -172,23 +173,23 @@ mod tests { mod i8 { use super::*; - fn sample_values(i: usize, mode: Mode, rng: &mut TestRng) -> (console_root::types::I8, I8) { + fn sample_values(i: usize, mode: Mode, rng: &mut TestRng) -> (console_root::types::I8, I8) { super::sample_values(i, mode, rng) } - impl_check_cast!(cast, I8, console_root::types::I8); + impl_check_cast!(cast, I8, console_root::types::I8); #[test] fn test_i8_to_address() { - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Public, count_is!(4, 0, 13, 13), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Private, count_is!(4, 0, 13, 13), ); @@ -196,15 +197,15 @@ mod tests { #[test] fn test_i8_to_boolean() { - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Constant, count_is!(16, 0, 0, 0), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Public, count_is!(16, 0, 5, 6), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Private, count_is!(16, 0, 5, 6), ); @@ -212,96 +213,99 @@ mod tests { #[test] fn test_i8_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_group() { - check_cast::, console_root::types::Group>( + check_cast::, console_root::types::Group>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_i8_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i8_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i8_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i8_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i8_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 1)); } } @@ -312,23 +316,23 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::I16, I16) { + ) -> (console_root::types::I16, I16) { super::sample_values(i, mode, rng) } - impl_check_cast!(cast, I16, console_root::types::I16); + impl_check_cast!(cast, I16, console_root::types::I16); #[test] fn test_i16_to_address() { - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Public, count_is!(4, 0, 13, 13), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Private, count_is!(4, 0, 13, 13), ); @@ -336,15 +340,15 @@ mod tests { #[test] fn test_i16_to_boolean() { - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Constant, count_is!(32, 0, 0, 0), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Public, count_is!(32, 0, 5, 6), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Private, count_is!(32, 0, 5, 6), ); @@ -352,96 +356,99 @@ mod tests { #[test] fn test_i16_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_group() { - check_cast::, console_root::types::Group>( + check_cast::, console_root::types::Group>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_i16_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 8)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 8)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 8)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 8)); } #[test] fn test_i16_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i16_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i16_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i16_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i16_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 1)); } } @@ -452,23 +459,23 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::I32, I32) { + ) -> (console_root::types::I32, I32) { super::sample_values(i, mode, rng) } - impl_check_cast!(cast, I32, console_root::types::I32); + impl_check_cast!(cast, I32, console_root::types::I32); #[test] fn test_i32_to_address() { - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Public, count_is!(4, 0, 13, 13), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Private, count_is!(4, 0, 13, 13), ); @@ -476,15 +483,15 @@ mod tests { #[test] fn test_i32_to_boolean() { - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Constant, count_is!(64, 0, 0, 0), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Public, count_is!(64, 0, 5, 6), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Private, count_is!(64, 0, 5, 6), ); @@ -492,96 +499,99 @@ mod tests { #[test] fn test_i32_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_group() { - check_cast::, console_root::types::Group>( + check_cast::, console_root::types::Group>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_i32_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 24)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 24)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 24)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 24)); } #[test] fn test_i32_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 16)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 16)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 16)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 16)); } #[test] fn test_i32_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i32_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i32_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i32_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i32_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 1)); } } @@ -592,23 +602,23 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::I64, I64) { + ) -> (console_root::types::I64, I64) { super::sample_values(i, mode, rng) } - impl_check_cast!(cast, I64, console_root::types::I64); + impl_check_cast!(cast, I64, console_root::types::I64); #[test] fn test_i64_to_address() { - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Public, count_is!(4, 0, 13, 13), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Private, count_is!(4, 0, 13, 13), ); @@ -616,15 +626,15 @@ mod tests { #[test] fn test_i64_to_boolean() { - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Constant, count_is!(128, 0, 0, 0), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Public, count_is!(128, 0, 5, 6), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Private, count_is!(128, 0, 5, 6), ); @@ -632,96 +642,99 @@ mod tests { #[test] fn test_i64_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i64_to_group() { - check_cast::, console_root::types::Group>( + check_cast::, console_root::types::Group>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_i64_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 56)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 56)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 56)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 56)); } #[test] fn test_i64_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 48)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 48)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 48)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 48)); } #[test] fn test_i64_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 32)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 32)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 32)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 32)); } #[test] fn test_i64_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i64_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i64_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i64_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i64_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i64_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i64_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i64_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 1)); } } @@ -732,23 +745,23 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::I128, I128) { + ) -> (console_root::types::I128, I128) { super::sample_values(i, mode, rng) } - impl_check_cast!(cast, I128, console_root::types::I128); + impl_check_cast!(cast, I128, console_root::types::I128); #[test] fn test_i128_to_address() { - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Public, count_is!(4, 0, 13, 13), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Private, count_is!(4, 0, 13, 13), ); @@ -756,15 +769,15 @@ mod tests { #[test] fn test_i128_to_boolean() { - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Constant, count_is!(256, 0, 0, 0), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Public, count_is!(256, 0, 5, 6), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Private, count_is!(256, 0, 5, 6), ); @@ -772,119 +785,122 @@ mod tests { #[test] fn test_i128_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i128_to_group() { - check_cast::, console_root::types::Group>( + check_cast::, console_root::types::Group>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_i128_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 120)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 120)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 120)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 120)); } #[test] fn test_i128_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 112)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 112)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 112)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 112)); } #[test] fn test_i128_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 96)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 96)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 96)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 96)); } #[test] fn test_i128_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 64)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 64)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 64)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 64)); } #[test] fn test_i128_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i128_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i128_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i128_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i128_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i128_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_i128_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 1)); } } mod u8 { use super::*; - fn sample_values(i: usize, mode: Mode, rng: &mut TestRng) -> (console_root::types::U8, U8) { + fn sample_values(i: usize, mode: Mode, rng: &mut TestRng) -> (console_root::types::U8, U8) { super::sample_values(i, mode, rng) } - impl_check_cast!(cast, U8, console_root::types::U8); + impl_check_cast!(cast, U8, console_root::types::U8); #[test] fn test_u8_to_address() { - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Public, count_is!(4, 0, 13, 13), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Private, count_is!(4, 0, 13, 13), ); @@ -892,15 +908,15 @@ mod tests { #[test] fn test_u8_to_boolean() { - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Constant, count_is!(16, 0, 0, 0), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Public, count_is!(16, 0, 5, 6), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Private, count_is!(16, 0, 5, 6), ); @@ -908,96 +924,99 @@ mod tests { #[test] fn test_u8_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_group() { - check_cast::, console_root::types::Group>( + check_cast::, console_root::types::Group>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_u8_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u8_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 0)); } } @@ -1008,23 +1027,23 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::U16, U16) { + ) -> (console_root::types::U16, U16) { super::sample_values(i, mode, rng) } - impl_check_cast!(cast, U16, console_root::types::U16); + impl_check_cast!(cast, U16, console_root::types::U16); #[test] fn test_u16_to_address() { - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Public, count_is!(4, 0, 13, 13), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Private, count_is!(4, 0, 13, 13), ); @@ -1032,15 +1051,15 @@ mod tests { #[test] fn test_u16_to_boolean() { - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Constant, count_is!(32, 0, 0, 0), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Public, count_is!(32, 0, 5, 6), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Private, count_is!(32, 0, 5, 6), ); @@ -1048,96 +1067,99 @@ mod tests { #[test] fn test_u16_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_group() { - check_cast::, console_root::types::Group>( + check_cast::, console_root::types::Group>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_u16_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u16_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u16_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u16_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 0)); } } @@ -1148,23 +1170,23 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::U32, U32) { + ) -> (console_root::types::U32, U32) { super::sample_values(i, mode, rng) } - impl_check_cast!(cast, U32, console_root::types::U32); + impl_check_cast!(cast, U32, console_root::types::U32); #[test] fn test_u32_to_address() { - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Public, count_is!(4, 0, 13, 13), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Private, count_is!(4, 0, 13, 13), ); @@ -1172,15 +1194,15 @@ mod tests { #[test] fn test_u32_to_boolean() { - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Constant, count_is!(64, 0, 0, 0), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Public, count_is!(64, 0, 5, 6), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Private, count_is!(64, 0, 5, 6), ); @@ -1188,96 +1210,99 @@ mod tests { #[test] fn test_u32_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_group() { - check_cast::, console_root::types::Group>( + check_cast::, console_root::types::Group>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_u32_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u32_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u32_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u32_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u32_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u32_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 0)); } } @@ -1288,23 +1313,23 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::U64, U64) { + ) -> (console_root::types::U64, U64) { super::sample_values(i, mode, rng) } - impl_check_cast!(cast, U64, console_root::types::U64); + impl_check_cast!(cast, U64, console_root::types::U64); #[test] fn test_u64_to_address() { - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Public, count_is!(4, 0, 13, 13), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Private, count_is!(4, 0, 13, 13), ); @@ -1312,15 +1337,15 @@ mod tests { #[test] fn test_u64_to_boolean() { - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Constant, count_is!(128, 0, 0, 0), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Public, count_is!(128, 0, 5, 6), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Private, count_is!(128, 0, 5, 6), ); @@ -1328,96 +1353,99 @@ mod tests { #[test] fn test_u64_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u64_to_group() { - check_cast::, console_root::types::Group>( + check_cast::, console_root::types::Group>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_u64_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u64_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u64_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u64_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u64_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u64_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u64_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u64_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u64_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u64_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u64_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 0)); } } @@ -1428,23 +1456,23 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::U128, U128) { + ) -> (console_root::types::U128, U128) { super::sample_values(i, mode, rng) } - impl_check_cast!(cast, U128, console_root::types::U128); + impl_check_cast!(cast, U128, console_root::types::U128); #[test] fn test_u128_to_address() { - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Public, count_is!(4, 0, 13, 13), ); - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Private, count_is!(4, 0, 13, 13), ); @@ -1452,15 +1480,15 @@ mod tests { #[test] fn test_u128_to_boolean() { - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Constant, count_is!(256, 0, 0, 0), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Public, count_is!(256, 0, 5, 6), ); - check_cast::, console_root::types::Boolean>( + check_cast::, console_root::types::Boolean>( Mode::Private, count_is!(256, 0, 5, 6), ); @@ -1468,96 +1496,99 @@ mod tests { #[test] fn test_u128_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u128_to_group() { - check_cast::, console_root::types::Group>( + check_cast::, console_root::types::Group>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_u128_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u128_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u128_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u128_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u128_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u128_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u128_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u128_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u128_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u128_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 1)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 1)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 1)); } #[test] fn test_u128_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 0, 0)); } } } diff --git a/circuit/program/src/data/literal/cast/mod.rs b/circuit/program/src/data/literal/cast/mod.rs index 2c2010f16e..8b08c2bf97 100644 --- a/circuit/program/src/data/literal/cast/mod.rs +++ b/circuit/program/src/data/literal/cast/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,8 +22,6 @@ use crate::data::{CastLossy, Literal}; use console::LiteralType; use snarkvm_circuit_network::Aleo; use snarkvm_circuit_types::prelude::{ - bail, - integers::Integer, Address, BitOr, Boolean, @@ -33,6 +32,7 @@ use snarkvm_circuit_types::prelude::{ FromGroup, Group, IntegerType, + MSB, One, Result, Scalar, @@ -40,11 +40,12 @@ use snarkvm_circuit_types::prelude::{ ToField, ToGroup, Zero, - MSB, + bail, + integers::Integer, }; #[cfg(test)] -use snarkvm_circuit_types::prelude::{I128, I16, I32, I64, I8, U128, U16, U32, U64, U8}; +use snarkvm_circuit_types::prelude::{I8, I16, I32, I64, I128, U8, U16, U32, U64, U128}; /// Unary operator for casting values of one type to another. pub trait Cast { @@ -64,6 +65,7 @@ impl Literal { /// - (`Address`, `Group`) <-> `Field` <-> `Scalar` <-> `Integer` <-> `Boolean` /// - `Signature` (not supported) /// - `String` (not supported) + /// /// Note that casting to left along the hierarchy always preserves information. pub fn cast(&self, to_type: LiteralType) -> Result { match self { diff --git a/circuit/program/src/data/literal/cast/scalar.rs b/circuit/program/src/data/literal/cast/scalar.rs index 39e3b440b9..93e4df7b81 100644 --- a/circuit/program/src/data/literal/cast/scalar.rs +++ b/circuit/program/src/data/literal/cast/scalar.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -87,10 +88,10 @@ mod tests { use super::*; use console::Cast as _; use console_root::{ - network::Testnet3, + network::MainnetV0, prelude::{One, TestRng, Uniform, Zero}, }; - use snarkvm_circuit_types::environment::{count_is, count_less_than, Circuit, Eject, Inject, Mode, UpdatableCount}; + use snarkvm_circuit_types::environment::{Circuit, Eject, Inject, Mode, UpdatableCount, count_is, count_less_than}; use std::fmt::Debug; @@ -100,126 +101,126 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::Scalar, Scalar) { + ) -> (console_root::types::Scalar, Scalar) { let console_value = match i { - 0 => console_root::types::Scalar::::zero(), - 1 => console_root::types::Scalar::::one(), + 0 => console_root::types::Scalar::::zero(), + 1 => console_root::types::Scalar::::one(), _ => Uniform::rand(rng), }; let circuit_value = Scalar::::new(mode, console_value); (console_value, circuit_value) } - impl_check_cast!(cast, Scalar, console_root::types::Scalar::); + impl_check_cast!(cast, Scalar, console_root::types::Scalar::); #[test] fn test_scalar_to_address() { - check_cast::, console_root::types::Address>( + check_cast::, console_root::types::Address>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Address>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Address>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Address>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Address>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_scalar_to_boolean() { - check_cast::, console_root::types::Boolean>(Mode::Constant, count_is!(4, 0, 0, 0)); - check_cast::, console_root::types::Boolean>(Mode::Public, count_is!(2, 0, 5, 6)); - check_cast::, console_root::types::Boolean>(Mode::Private, count_is!(2, 0, 5, 6)); + check_cast::, console_root::types::Boolean>(Mode::Constant, count_is!(4, 0, 0, 0)); + check_cast::, console_root::types::Boolean>(Mode::Public, count_is!(2, 0, 5, 6)); + check_cast::, console_root::types::Boolean>(Mode::Private, count_is!(2, 0, 5, 6)); } #[test] fn test_scalar_to_field() { - check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_scalar_to_group() { - check_cast::, console_root::types::Group>( + check_cast::, console_root::types::Group>( Mode::Constant, count_less_than!(11, 0, 0, 0), ); - check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); - check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Public, count_is!(4, 0, 13, 13)); + check_cast::, console_root::types::Group>(Mode::Private, count_is!(4, 0, 13, 13)); } #[test] fn test_scalar_to_i8() { - check_cast::, console_root::types::I8>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 501, 504)); - check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::I8>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 501, 504)); } #[test] fn test_scalar_to_i16() { - check_cast::, console_root::types::I16>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 501, 504)); - check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::I16>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 501, 504)); } #[test] fn test_scalar_to_i32() { - check_cast::, console_root::types::I32>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 501, 504)); - check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::I32>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 501, 504)); } #[test] fn test_scalar_to_i64() { - check_cast::, console_root::types::I64>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 501, 504)); - check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::I64>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 501, 504)); } #[test] fn test_scalar_to_i128() { - check_cast::, console_root::types::I128>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 501, 504)); - check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::I128>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::I128>(Mode::Private, count_is!(0, 0, 501, 504)); } #[test] fn test_scalar_to_scalar() { - check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast::, console_root::types::Scalar>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_scalar_to_u8() { - check_cast::, console_root::types::U8>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 501, 504)); - check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::U8>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 501, 504)); } #[test] fn test_scalar_to_u16() { - check_cast::, console_root::types::U16>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 501, 504)); - check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::U16>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 501, 504)); } #[test] fn test_scalar_to_u32() { - check_cast::, console_root::types::U32>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 501, 504)); - check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::U32>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 501, 504)); } #[test] fn test_scalar_to_u64() { - check_cast::, console_root::types::U64>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 501, 504)); - check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::U64>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 501, 504)); } #[test] fn test_scalar_to_u128() { - check_cast::, console_root::types::U128>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 501, 504)); - check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::U128>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 501, 504)); + check_cast::, console_root::types::U128>(Mode::Private, count_is!(0, 0, 501, 504)); } } diff --git a/circuit/program/src/data/literal/cast_lossy/boolean.rs b/circuit/program/src/data/literal/cast_lossy/boolean.rs index f2017d9857..b371082c7b 100644 --- a/circuit/program/src/data/literal/cast_lossy/boolean.rs +++ b/circuit/program/src/data/literal/cast_lossy/boolean.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -77,8 +78,8 @@ impl CastLossy> for Boolean { mod tests { use super::*; use console::CastLossy as _; - use console_root::{network::Testnet3, prelude::TestRng}; - use snarkvm_circuit_types::environment::{count_is, Circuit, Eject, Inject, Mode, UpdatableCount}; + use console_root::{network::MainnetV0, prelude::TestRng}; + use snarkvm_circuit_types::environment::{Circuit, Eject, Inject, Mode, UpdatableCount, count_is}; use std::fmt::Debug; @@ -88,23 +89,23 @@ mod tests { i: usize, mode: Mode, _: &mut TestRng, - ) -> (console_root::types::Boolean, Boolean) { + ) -> (console_root::types::Boolean, Boolean) { (console_root::types::Boolean::new(i % 2 == 0), Boolean::new(mode, i % 2 == 0)) } - check_cast_lossy!(cast_lossy, Boolean, console_root::types::Boolean::); + check_cast_lossy!(cast_lossy, Boolean, console_root::types::Boolean::); #[test] fn test_boolean_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, count_is!(10, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, count_is!(10, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, count_is!(10, 0, 0, 0), ); @@ -112,15 +113,15 @@ mod tests { #[test] fn test_boolean_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -128,64 +129,76 @@ mod tests { #[test] fn test_boolean_to_field() { - check_cast_lossy::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::Field>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_boolean_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, count_is!(10, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>(Mode::Public, count_is!(10, 0, 0, 0)); - check_cast_lossy::, console_root::types::Group>(Mode::Private, count_is!(10, 0, 0, 0)); + check_cast_lossy::, console_root::types::Group>(Mode::Public, count_is!(10, 0, 0, 0)); + check_cast_lossy::, console_root::types::Group>( + Mode::Private, + count_is!(10, 0, 0, 0), + ); } #[test] fn test_boolean_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(16, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(16, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(16, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(16, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(16, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(16, 0, 0, 0)); } #[test] fn test_boolean_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(32, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(32, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(32, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(32, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(32, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(32, 0, 0, 0)); } #[test] fn test_boolean_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(64, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(64, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(64, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(64, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(64, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(64, 0, 0, 0)); } #[test] fn test_boolean_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(128, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(128, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(128, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(128, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(128, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(128, 0, 0, 0)); } #[test] fn test_boolean_to_i128() { - check_cast_lossy::, console_root::types::I128>(Mode::Constant, count_is!(256, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(256, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>(Mode::Private, count_is!(256, 0, 0, 0)); + check_cast_lossy::, console_root::types::I128>( + Mode::Constant, + count_is!(256, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(256, 0, 0, 0)); + check_cast_lossy::, console_root::types::I128>(Mode::Private, count_is!(256, 0, 0, 0)); } #[test] fn test_boolean_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(2, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>(Mode::Public, count_is!(2, 0, 0, 0)); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( + Mode::Public, + count_is!(2, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(2, 0, 0, 0), ); @@ -193,36 +206,39 @@ mod tests { #[test] fn test_boolean_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(16, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(16, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(16, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(16, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(16, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(16, 0, 0, 0)); } #[test] fn test_boolean_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(32, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(32, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(32, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(32, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(32, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(32, 0, 0, 0)); } #[test] fn test_boolean_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(64, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(64, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(64, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(64, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(64, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(64, 0, 0, 0)); } #[test] fn test_boolean_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(128, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(128, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(128, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(128, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(128, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(128, 0, 0, 0)); } #[test] fn test_boolean_to_u128() { - check_cast_lossy::, console_root::types::U128>(Mode::Constant, count_is!(256, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(256, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>(Mode::Private, count_is!(256, 0, 0, 0)); + check_cast_lossy::, console_root::types::U128>( + Mode::Constant, + count_is!(256, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(256, 0, 0, 0)); + check_cast_lossy::, console_root::types::U128>(Mode::Private, count_is!(256, 0, 0, 0)); } } diff --git a/circuit/program/src/data/literal/cast_lossy/field.rs b/circuit/program/src/data/literal/cast_lossy/field.rs index b2be939819..f865d70e8e 100644 --- a/circuit/program/src/data/literal/cast_lossy/field.rs +++ b/circuit/program/src/data/literal/cast_lossy/field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -61,9 +62,12 @@ impl CastLossy> for Field { #[inline] fn cast_lossy(&self) -> Group { // This method requires that an `x-coordinate` of 1 is an invalid group element. - // This is used by the ternary below, which uses 'is_one' to determine whether to return the generator. + // This is used by the ternary below, which uses 'is_x_one' to determine whether to return the generator. debug_assert!(console::Group::from_x_coordinate( as console::One>::one()).is_err()); + // Attempt to find a group element with self as the x-coordinate. + let (point_with_x, x_is_not_in_group) = Group::from_x_coordinate_flagged(self.clone()); + // Determine if the field element is zero. let is_x_zero = self.is_zero(); // Determine if the field element is one. @@ -73,35 +77,20 @@ impl CastLossy> for Field { let generator = Group::generator(); // Determine the input to Elligator-2, based on the x-coordinate. + // If self is 0, we pass 1 to Elligator-2 instead. + // Note that, in this case, we won't use the result of Elligator-2, + // because the point (0, 1) is in the subgroup, and that is what we return. let elligator_input = Field::ternary(&is_x_zero, &Field::one(), self); // Perform Elligator-2 on the field element, to recover a group element. - let elligator = Elligator2::encode(&elligator_input); - - // Determine the initial x-coordinate, if the given field element is one. - let initial_x = Field::ternary(&is_x_one, &generator.to_x_coordinate(), &elligator.to_x_coordinate()); - // Determine the initial y-coordinate, if the given field element is one. - let initial_y = Field::ternary(&is_x_one, &generator.to_y_coordinate(), &elligator.to_y_coordinate()); - - // Determine the y-coordinate, if the x-coordinate is valid. - let possible_y: Field = { - // Set the x-coordinate. - let x = self.clone(); - // Derive the y-coordinate. - witness!(|x| match console::Group::from_x_coordinate(x) { - Ok(point) => point.to_y_coordinate(), - Err(_) => console::Zero::zero(), - }) - }; - // Determine if the recovered y-coordinate is zero. - let is_y_zero = possible_y.is_zero(); + let elligator_point = Elligator2::encode(&elligator_input); - // Determine the final x-coordinate, based on whether the possible y-coordinate is zero. - let final_x = Field::ternary(&is_y_zero, &initial_x, self); - // Determine the final y-coordinate, based on whether the possible y-coordinate is zero. - let final_y = Field::ternary(&is_y_zero, &initial_y, &possible_y); + // Select either the generator or the result of Elligator-2, depending on whether x is 1 or not. + // This is only used when x is not in the group, see below. + let generator_or_elligator_point = Group::ternary(&is_x_one, &generator, &elligator_point); - // Return the result. - Group::from_xy_coordinates(final_x, final_y) + // Select either the group point with x or the generator or the result of Elligator-2, + // depending on whether x is in the group or not, and, if it is not, based on whether it is 1 or not. + Group::ternary(&x_is_not_in_group, &generator_or_elligator_point, &point_with_x) } } @@ -128,10 +117,10 @@ mod tests { use super::*; use console::CastLossy as _; use console_root::{ - network::Testnet3, + network::MainnetV0, prelude::{One, TestRng, Uniform, Zero}, }; - use snarkvm_circuit_types::environment::{count_is, count_less_than, Circuit, Eject, Inject, Mode, UpdatableCount}; + use snarkvm_circuit_types::environment::{Circuit, Eject, Inject, Mode, UpdatableCount, count_is, count_less_than}; use std::fmt::Debug; @@ -141,45 +130,45 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::Field, Field) { + ) -> (console_root::types::Field, Field) { let console_value = match i { - 0 => console_root::types::Field::::zero(), - 1 => console_root::types::Field::::one(), + 0 => console_root::types::Field::::zero(), + 1 => console_root::types::Field::::one(), _ => Uniform::rand(rng), }; let circuit_value = Field::::new(mode, console_value); (console_value, circuit_value) } - check_cast_lossy!(cast_lossy, Field, console_root::types::Field::); + check_cast_lossy!(cast_lossy, Field, console_root::types::Field::); #[test] fn test_field_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_field_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(253, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 505, 507), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 505, 507), ); @@ -187,60 +176,69 @@ mod tests { #[test] fn test_field_to_field() { - check_cast_lossy::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::Field>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_field_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_field_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(253, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 505, 507)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(253, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 505, 507)); } #[test] fn test_field_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(253, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 505, 507)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(253, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 505, 507)); } #[test] fn test_field_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(253, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 505, 507)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(253, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 505, 507)); } #[test] fn test_field_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(253, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 505, 507)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(253, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 505, 507)); } #[test] fn test_field_to_i128() { - check_cast_lossy::, console_root::types::I128>(Mode::Constant, count_is!(253, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 505, 507)); - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( + Mode::Constant, + count_is!(253, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>( + Mode::Public, + count_is!(0, 0, 505, 507), + ); + check_cast_lossy::, console_root::types::I128>( Mode::Private, count_is!(0, 0, 505, 507), ); @@ -248,15 +246,15 @@ mod tests { #[test] fn test_field_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(253, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Public, count_is!(0, 0, 505, 507), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(0, 0, 505, 507), ); @@ -264,37 +262,43 @@ mod tests { #[test] fn test_field_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(253, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 505, 507)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(253, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 505, 507)); } #[test] fn test_field_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(253, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 505, 507)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(253, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 505, 507)); } #[test] fn test_field_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(253, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 505, 507)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(253, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 505, 507)); } #[test] fn test_field_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(253, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 505, 507)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(253, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 505, 507)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 505, 507)); } #[test] fn test_field_to_u128() { - check_cast_lossy::, console_root::types::U128>(Mode::Constant, count_is!(253, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 505, 507)); - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( + Mode::Constant, + count_is!(253, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>( + Mode::Public, + count_is!(0, 0, 505, 507), + ); + check_cast_lossy::, console_root::types::U128>( Mode::Private, count_is!(0, 0, 505, 507), ); diff --git a/circuit/program/src/data/literal/cast_lossy/integer.rs b/circuit/program/src/data/literal/cast_lossy/integer.rs index 4531e0e504..f93ed065b7 100644 --- a/circuit/program/src/data/literal/cast_lossy/integer.rs +++ b/circuit/program/src/data/literal/cast_lossy/integer.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -91,10 +92,10 @@ mod tests { use super::*; use console::CastLossy as _; use console_root::{ - network::Testnet3, + network::MainnetV0, prelude::{One, TestRng, Uniform, Zero}, }; - use snarkvm_circuit_types::environment::{count_is, count_less_than, Circuit, Eject, Inject, Mode, UpdatableCount}; + use snarkvm_circuit_types::environment::{Circuit, Eject, Inject, Mode, UpdatableCount, count_is, count_less_than}; use std::fmt::Debug; @@ -104,13 +105,13 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::integers::Integer, Integer) { + ) -> (console_root::types::integers::Integer, Integer) { let console_value = match i { - 0 => console_root::types::integers::Integer::::zero(), - 1 => console_root::types::integers::Integer::::one(), - 2 => console_root::types::integers::Integer::::new(I::MAX), - 3 => console_root::types::integers::Integer::::new(I::MIN), - 4 if I::is_signed() => -console_root::types::integers::Integer::::one(), + 0 => console_root::types::integers::Integer::::zero(), + 1 => console_root::types::integers::Integer::::one(), + 2 => console_root::types::integers::Integer::::new(I::MAX), + 3 => console_root::types::integers::Integer::::new(I::MIN), + 4 if I::is_signed() => -console_root::types::integers::Integer::::one(), _ => Uniform::rand(rng), }; let circuit_value = Integer::::new(mode, console_value); @@ -120,39 +121,39 @@ mod tests { mod i8 { use super::*; - fn sample_values(i: usize, mode: Mode, rng: &mut TestRng) -> (console_root::types::I8, I8) { + fn sample_values(i: usize, mode: Mode, rng: &mut TestRng) -> (console_root::types::I8, I8) { super::sample_values(i, mode, rng) } - check_cast_lossy!(cast_lossy, I8, console_root::types::I8); + check_cast_lossy!(cast_lossy, I8, console_root::types::I8); #[test] fn test_i8_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_i8_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -160,15 +161,15 @@ mod tests { #[test] fn test_i8_to_field() { - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -176,56 +177,68 @@ mod tests { #[test] fn test_i8_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_i8_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_i128() { - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -233,15 +246,15 @@ mod tests { #[test] fn test_i8_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -249,40 +262,52 @@ mod tests { #[test] fn test_i8_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i8_to_u128() { - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -296,39 +321,39 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::I16, I16) { + ) -> (console_root::types::I16, I16) { super::sample_values(i, mode, rng) } - check_cast_lossy!(cast_lossy, I16, console_root::types::I16); + check_cast_lossy!(cast_lossy, I16, console_root::types::I16); #[test] fn test_i16_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_i16_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -336,15 +361,15 @@ mod tests { #[test] fn test_i16_to_field() { - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -352,56 +377,68 @@ mod tests { #[test] fn test_i16_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_i16_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_i128() { - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -409,15 +446,15 @@ mod tests { #[test] fn test_i16_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -425,40 +462,52 @@ mod tests { #[test] fn test_i16_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i16_to_u128() { - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -472,39 +521,39 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::I32, I32) { + ) -> (console_root::types::I32, I32) { super::sample_values(i, mode, rng) } - check_cast_lossy!(cast_lossy, I32, console_root::types::I32); + check_cast_lossy!(cast_lossy, I32, console_root::types::I32); #[test] fn test_i32_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_i32_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -512,15 +561,15 @@ mod tests { #[test] fn test_i32_to_field() { - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -528,56 +577,68 @@ mod tests { #[test] fn test_i32_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_i32_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_i128() { - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -585,15 +646,15 @@ mod tests { #[test] fn test_i32_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -601,40 +662,52 @@ mod tests { #[test] fn test_i32_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i32_to_u128() { - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -648,39 +721,39 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::I64, I64) { + ) -> (console_root::types::I64, I64) { super::sample_values(i, mode, rng) } - check_cast_lossy!(cast_lossy, I64, console_root::types::I64); + check_cast_lossy!(cast_lossy, I64, console_root::types::I64); #[test] fn test_i64_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_i64_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -688,15 +761,15 @@ mod tests { #[test] fn test_i64_to_field() { - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -704,56 +777,68 @@ mod tests { #[test] fn test_i64_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_i64_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i64_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i64_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i64_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i64_to_i128() { - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -761,15 +846,15 @@ mod tests { #[test] fn test_i64_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -777,40 +862,52 @@ mod tests { #[test] fn test_i64_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i64_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i64_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i64_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i64_to_u128() { - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -824,39 +921,39 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::I128, I128) { + ) -> (console_root::types::I128, I128) { super::sample_values(i, mode, rng) } - check_cast_lossy!(cast_lossy, I128, console_root::types::I128); + check_cast_lossy!(cast_lossy, I128, console_root::types::I128); #[test] fn test_i128_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_i128_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -864,15 +961,15 @@ mod tests { #[test] fn test_i128_to_field() { - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -880,56 +977,68 @@ mod tests { #[test] fn test_i128_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_i128_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i128_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i128_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i128_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i128_to_i128() { - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -937,15 +1046,15 @@ mod tests { #[test] fn test_i128_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -953,40 +1062,52 @@ mod tests { #[test] fn test_i128_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i128_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i128_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i128_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_i128_to_u128() { - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -996,39 +1117,39 @@ mod tests { mod u8 { use super::*; - fn sample_values(i: usize, mode: Mode, rng: &mut TestRng) -> (console_root::types::U8, U8) { + fn sample_values(i: usize, mode: Mode, rng: &mut TestRng) -> (console_root::types::U8, U8) { super::sample_values(i, mode, rng) } - check_cast_lossy!(cast_lossy, U8, console_root::types::U8); + check_cast_lossy!(cast_lossy, U8, console_root::types::U8); #[test] fn test_u8_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_u8_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1036,15 +1157,15 @@ mod tests { #[test] fn test_u8_to_field() { - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1052,56 +1173,68 @@ mod tests { #[test] fn test_u8_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_u8_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_i128() { - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1109,15 +1242,15 @@ mod tests { #[test] fn test_u8_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1125,40 +1258,52 @@ mod tests { #[test] fn test_u8_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u8_to_u128() { - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1172,39 +1317,39 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::U16, U16) { + ) -> (console_root::types::U16, U16) { super::sample_values(i, mode, rng) } - check_cast_lossy!(cast_lossy, U16, console_root::types::U16); + check_cast_lossy!(cast_lossy, U16, console_root::types::U16); #[test] fn test_u16_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_u16_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1212,15 +1357,15 @@ mod tests { #[test] fn test_u16_to_field() { - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1228,56 +1373,68 @@ mod tests { #[test] fn test_u16_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_u16_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_i128() { - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1285,15 +1442,15 @@ mod tests { #[test] fn test_u16_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1301,40 +1458,52 @@ mod tests { #[test] fn test_u16_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u16_to_u128() { - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1348,39 +1517,39 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::U32, U32) { + ) -> (console_root::types::U32, U32) { super::sample_values(i, mode, rng) } - check_cast_lossy!(cast_lossy, U32, console_root::types::U32); + check_cast_lossy!(cast_lossy, U32, console_root::types::U32); #[test] fn test_u32_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_u32_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1388,15 +1557,15 @@ mod tests { #[test] fn test_u32_to_field() { - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1404,56 +1573,68 @@ mod tests { #[test] fn test_u32_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_u32_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_i128() { - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1461,15 +1642,15 @@ mod tests { #[test] fn test_u32_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1477,40 +1658,52 @@ mod tests { #[test] fn test_u32_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u32_to_u128() { - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1524,39 +1717,39 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::U64, U64) { + ) -> (console_root::types::U64, U64) { super::sample_values(i, mode, rng) } - check_cast_lossy!(cast_lossy, U64, console_root::types::U64); + check_cast_lossy!(cast_lossy, U64, console_root::types::U64); #[test] fn test_u64_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_u64_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1564,15 +1757,15 @@ mod tests { #[test] fn test_u64_to_field() { - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1580,56 +1773,68 @@ mod tests { #[test] fn test_u64_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_u64_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u64_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u64_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u64_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u64_to_i128() { - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1637,15 +1842,15 @@ mod tests { #[test] fn test_u64_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1653,40 +1858,52 @@ mod tests { #[test] fn test_u64_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u64_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u64_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u64_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u64_to_u128() { - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1700,39 +1917,39 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::U128, U128) { + ) -> (console_root::types::U128, U128) { super::sample_values(i, mode, rng) } - check_cast_lossy!(cast_lossy, U128, console_root::types::U128); + check_cast_lossy!(cast_lossy, U128, console_root::types::U128); #[test] fn test_u128_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_u128_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1740,15 +1957,15 @@ mod tests { #[test] fn test_u128_to_field() { - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Field>( + check_cast_lossy::, console_root::types::Field>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1756,56 +1973,68 @@ mod tests { #[test] fn test_u128_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_u128_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u128_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u128_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u128_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u128_to_i128() { - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1813,15 +2042,15 @@ mod tests { #[test] fn test_u128_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Public, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -1829,40 +2058,52 @@ mod tests { #[test] fn test_u128_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u128_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u128_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u128_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_u128_to_u128() { - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>( Mode::Private, count_is!(0, 0, 0, 0), ); diff --git a/circuit/program/src/data/literal/cast_lossy/mod.rs b/circuit/program/src/data/literal/cast_lossy/mod.rs index eae6120f6f..764763a665 100644 --- a/circuit/program/src/data/literal/cast_lossy/mod.rs +++ b/circuit/program/src/data/literal/cast_lossy/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -22,14 +23,8 @@ use console::LiteralType; use snarkvm_circuit_algorithms::Elligator2; use snarkvm_circuit_network::Aleo; use snarkvm_circuit_types::prelude::{ - bail, - integers::Integer, - rename_selfs, - witness, - witness_mode, Address, Boolean, - Eject, Environment, Field, FromBits, @@ -38,7 +33,7 @@ use snarkvm_circuit_types::prelude::{ Group, Inject, IntegerType, - Mode, + MSB, One, Result, Scalar, @@ -47,11 +42,12 @@ use snarkvm_circuit_types::prelude::{ ToField, ToGroup, Zero, - MSB, + bail, + integers::Integer, }; #[cfg(test)] -use snarkvm_circuit_types::prelude::{I128, I16, I32, I64, I8, U128, U16, U32, U64, U8}; +use snarkvm_circuit_types::prelude::{I8, I16, I32, I64, I128, U8, U16, U32, U64, U128}; /// Unary operator for casting values of one type to another, with lossy truncation. pub trait CastLossy { @@ -72,6 +68,7 @@ impl Literal { /// - (`Address`, `Group`) <-> `Field` <-> `Scalar` <-> `Integer` <-> `Boolean` /// - `Signature` (not supported) /// - `String` (not supported) + /// /// Note that casting to left along the hierarchy always preserves information. pub fn cast_lossy(&self, to_type: LiteralType) -> Result { match self { diff --git a/circuit/program/src/data/literal/cast_lossy/scalar.rs b/circuit/program/src/data/literal/cast_lossy/scalar.rs index 95fddba50b..aa02eb8ded 100644 --- a/circuit/program/src/data/literal/cast_lossy/scalar.rs +++ b/circuit/program/src/data/literal/cast_lossy/scalar.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -89,10 +90,10 @@ mod tests { use super::*; use console::CastLossy as _; use console_root::{ - network::Testnet3, + network::MainnetV0, prelude::{One, TestRng, Uniform, Zero}, }; - use snarkvm_circuit_types::environment::{count_is, count_less_than, Circuit, Eject, Inject, Mode, UpdatableCount}; + use snarkvm_circuit_types::environment::{Circuit, Eject, Inject, Mode, UpdatableCount, count_is, count_less_than}; use std::fmt::Debug; @@ -102,45 +103,45 @@ mod tests { i: usize, mode: Mode, rng: &mut TestRng, - ) -> (console_root::types::Scalar, Scalar) { + ) -> (console_root::types::Scalar, Scalar) { let console_value = match i { - 0 => console_root::types::Scalar::::zero(), - 1 => console_root::types::Scalar::::one(), + 0 => console_root::types::Scalar::::zero(), + 1 => console_root::types::Scalar::::one(), _ => Uniform::rand(rng), }; let circuit_value = Scalar::::new(mode, console_value); (console_value, circuit_value) } - check_cast_lossy!(cast_lossy, Scalar, console_root::types::Scalar::); + check_cast_lossy!(cast_lossy, Scalar, console_root::types::Scalar::); #[test] fn test_scalar_to_address() { - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Address>( + check_cast_lossy::, console_root::types::Address>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_scalar_to_boolean() { - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Constant, count_is!(251, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Public, count_is!(0, 0, 501, 503), ); - check_cast_lossy::, console_root::types::Boolean>( + check_cast_lossy::, console_root::types::Boolean>( Mode::Private, count_is!(0, 0, 501, 503), ); @@ -148,60 +149,69 @@ mod tests { #[test] fn test_scalar_to_field() { - check_cast_lossy::, console_root::types::Field>(Mode::Constant, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::Field>( + Mode::Constant, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::Field>(Mode::Public, count_is!(0, 0, 0, 0)); + check_cast_lossy::, console_root::types::Field>(Mode::Private, count_is!(0, 0, 0, 0)); } #[test] fn test_scalar_to_group() { - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Constant, - count_less_than!(551, 0, 0, 0), + count_less_than!(4303, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Public, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); - check_cast_lossy::, console_root::types::Group>( + check_cast_lossy::, console_root::types::Group>( Mode::Private, - count_is!(277, 0, 899, 904), + count_is!(2029, 0, 6745, 6750), ); } #[test] fn test_scalar_to_i8() { - check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 501, 503)); - check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::I8>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast_lossy::, console_root::types::I8>(Mode::Public, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::I8>(Mode::Private, count_is!(0, 0, 501, 503)); } #[test] fn test_scalar_to_i16() { - check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 501, 503)); - check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::I16>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast_lossy::, console_root::types::I16>(Mode::Public, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::I16>(Mode::Private, count_is!(0, 0, 501, 503)); } #[test] fn test_scalar_to_i32() { - check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 501, 503)); - check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::I32>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast_lossy::, console_root::types::I32>(Mode::Public, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::I32>(Mode::Private, count_is!(0, 0, 501, 503)); } #[test] fn test_scalar_to_i64() { - check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 501, 503)); - check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::I64>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast_lossy::, console_root::types::I64>(Mode::Public, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::I64>(Mode::Private, count_is!(0, 0, 501, 503)); } #[test] fn test_scalar_to_i128() { - check_cast_lossy::, console_root::types::I128>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast_lossy::, console_root::types::I128>(Mode::Public, count_is!(0, 0, 501, 503)); - check_cast_lossy::, console_root::types::I128>( + check_cast_lossy::, console_root::types::I128>( + Mode::Constant, + count_is!(251, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::I128>( + Mode::Public, + count_is!(0, 0, 501, 503), + ); + check_cast_lossy::, console_root::types::I128>( Mode::Private, count_is!(0, 0, 501, 503), ); @@ -209,12 +219,15 @@ mod tests { #[test] fn test_scalar_to_scalar() { - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( Mode::Constant, count_is!(0, 0, 0, 0), ); - check_cast_lossy::, console_root::types::Scalar>(Mode::Public, count_is!(0, 0, 0, 0)); - check_cast_lossy::, console_root::types::Scalar>( + check_cast_lossy::, console_root::types::Scalar>( + Mode::Public, + count_is!(0, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::Scalar>( Mode::Private, count_is!(0, 0, 0, 0), ); @@ -222,37 +235,43 @@ mod tests { #[test] fn test_scalar_to_u8() { - check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 501, 503)); - check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::U8>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast_lossy::, console_root::types::U8>(Mode::Public, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::U8>(Mode::Private, count_is!(0, 0, 501, 503)); } #[test] fn test_scalar_to_u16() { - check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 501, 503)); - check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::U16>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast_lossy::, console_root::types::U16>(Mode::Public, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::U16>(Mode::Private, count_is!(0, 0, 501, 503)); } #[test] fn test_scalar_to_u32() { - check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 501, 503)); - check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::U32>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast_lossy::, console_root::types::U32>(Mode::Public, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::U32>(Mode::Private, count_is!(0, 0, 501, 503)); } #[test] fn test_scalar_to_u64() { - check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 501, 503)); - check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::U64>(Mode::Constant, count_is!(251, 0, 0, 0)); + check_cast_lossy::, console_root::types::U64>(Mode::Public, count_is!(0, 0, 501, 503)); + check_cast_lossy::, console_root::types::U64>(Mode::Private, count_is!(0, 0, 501, 503)); } #[test] fn test_scalar_to_u128() { - check_cast_lossy::, console_root::types::U128>(Mode::Constant, count_is!(251, 0, 0, 0)); - check_cast_lossy::, console_root::types::U128>(Mode::Public, count_is!(0, 0, 501, 503)); - check_cast_lossy::, console_root::types::U128>( + check_cast_lossy::, console_root::types::U128>( + Mode::Constant, + count_is!(251, 0, 0, 0), + ); + check_cast_lossy::, console_root::types::U128>( + Mode::Public, + count_is!(0, 0, 501, 503), + ); + check_cast_lossy::, console_root::types::U128>( Mode::Private, count_is!(0, 0, 501, 503), ); diff --git a/circuit/program/src/data/literal/equal.rs b/circuit/program/src/data/literal/equal.rs index f72c3bd4b8..5ab0fd9681 100644 --- a/circuit/program/src/data/literal/equal.rs +++ b/circuit/program/src/data/literal/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/literal/from_bits.rs b/circuit/program/src/data/literal/from_bits.rs index fbb5a2f5d7..cfc59dbfbd 100644 --- a/circuit/program/src/data/literal/from_bits.rs +++ b/circuit/program/src/data/literal/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -66,7 +67,7 @@ impl Literal { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; diff --git a/circuit/program/src/data/literal/mod.rs b/circuit/program/src/data/literal/mod.rs index e5fdd94e52..89df765a19 100644 --- a/circuit/program/src/data/literal/mod.rs +++ b/circuit/program/src/data/literal/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -71,7 +72,7 @@ pub enum Literal { String(StringType), } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Literal { type Primitive = console::Literal; @@ -99,7 +100,7 @@ impl Inject for Literal { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Literal { type Primitive = console::Literal; @@ -150,7 +151,7 @@ impl Eject for Literal { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Parser for Literal { /// Parses a string into a literal. #[inline] @@ -177,7 +178,7 @@ impl Parser for Literal { } } -#[cfg(console)] +#[cfg(feature = "console")] impl FromStr for Literal { type Err = Error; @@ -196,7 +197,7 @@ impl FromStr for Literal { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Literal { /// Returns the type name of the literal. pub fn type_name(&self) -> &str { @@ -222,14 +223,14 @@ impl Literal { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Debug for Literal { fn fmt(&self, f: &mut Formatter) -> fmt::Result { Display::fmt(self, f) } } -#[cfg(console)] +#[cfg(feature = "console")] impl Display for Literal { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { diff --git a/circuit/program/src/data/literal/size_in_bits.rs b/circuit/program/src/data/literal/size_in_bits.rs index 4f68ac652d..09805b12b7 100644 --- a/circuit/program/src/data/literal/size_in_bits.rs +++ b/circuit/program/src/data/literal/size_in_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/literal/to_bits.rs b/circuit/program/src/data/literal/to_bits.rs index 8457b4e08d..f5063bf36f 100644 --- a/circuit/program/src/data/literal/to_bits.rs +++ b/circuit/program/src/data/literal/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/literal/to_fields.rs b/circuit/program/src/data/literal/to_fields.rs index 758346e463..3d59b1fe4f 100644 --- a/circuit/program/src/data/literal/to_fields.rs +++ b/circuit/program/src/data/literal/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/literal/to_type.rs b/circuit/program/src/data/literal/to_type.rs index b83d0efecd..299aad2c06 100644 --- a/circuit/program/src/data/literal/to_type.rs +++ b/circuit/program/src/data/literal/to_type.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use super::*; -#[cfg(console)] +#[cfg(feature = "console")] impl Literal { /// Returns the type name of the literal. pub fn to_type(&self) -> console::LiteralType { diff --git a/circuit/program/src/data/literal/variant.rs b/circuit/program/src/data/literal/variant.rs index e268d5808c..5e7b107958 100644 --- a/circuit/program/src/data/literal/variant.rs +++ b/circuit/program/src/data/literal/variant.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/mod.rs b/circuit/program/src/data/mod.rs index e6e5ad4157..8cad02f72f 100644 --- a/circuit/program/src/data/mod.rs +++ b/circuit/program/src/data/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/plaintext/encrypt.rs b/circuit/program/src/data/plaintext/encrypt.rs index e70de87059..774395258e 100644 --- a/circuit/program/src/data/plaintext/encrypt.rs +++ b/circuit/program/src/data/plaintext/encrypt.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/plaintext/equal.rs b/circuit/program/src/data/plaintext/equal.rs index 92eaa21ff5..d5711b23be 100644 --- a/circuit/program/src/data/plaintext/equal.rs +++ b/circuit/program/src/data/plaintext/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/plaintext/find.rs b/circuit/program/src/data/plaintext/find.rs index 7fc7e9ceaa..b41e8ccf9f 100644 --- a/circuit/program/src/data/plaintext/find.rs +++ b/circuit/program/src/data/plaintext/find.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/plaintext/from_bits.rs b/circuit/program/src/data/plaintext/from_bits.rs index b4c92164d3..4d9f3e4a64 100644 --- a/circuit/program/src/data/plaintext/from_bits.rs +++ b/circuit/program/src/data/plaintext/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/plaintext/from_fields.rs b/circuit/program/src/data/plaintext/from_fields.rs index e812e86e10..aac5ed9506 100644 --- a/circuit/program/src/data/plaintext/from_fields.rs +++ b/circuit/program/src/data/plaintext/from_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/plaintext/mod.rs b/circuit/program/src/data/plaintext/mod.rs index 8f717c34ea..af772d60cd 100644 --- a/circuit/program/src/data/plaintext/mod.rs +++ b/circuit/program/src/data/plaintext/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -27,7 +28,7 @@ mod to_fields; use crate::{Access, Ciphertext, Identifier, Literal, Visibility}; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Address, Boolean, Field, Scalar, U16, U32, U8}; +use snarkvm_circuit_types::{Address, Boolean, Field, Scalar, U8, U16, U32, environment::prelude::*}; #[derive(Clone)] pub enum Plaintext { @@ -39,7 +40,7 @@ pub enum Plaintext { Array(Vec>, OnceCell>>), } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Plaintext { type Primitive = console::Plaintext; @@ -53,7 +54,7 @@ impl Inject for Plaintext { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Plaintext { type Primitive = console::Plaintext; @@ -98,7 +99,7 @@ impl From<&Literal> for Plaintext { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; diff --git a/circuit/program/src/data/plaintext/num_randomizers.rs b/circuit/program/src/data/plaintext/num_randomizers.rs index 086feca1b7..a1e58f3d42 100644 --- a/circuit/program/src/data/plaintext/num_randomizers.rs +++ b/circuit/program/src/data/plaintext/num_randomizers.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/plaintext/size_in_fields.rs b/circuit/program/src/data/plaintext/size_in_fields.rs index c7603a81ad..401daf414f 100644 --- a/circuit/program/src/data/plaintext/size_in_fields.rs +++ b/circuit/program/src/data/plaintext/size_in_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/plaintext/to_bits.rs b/circuit/program/src/data/plaintext/to_bits.rs index c2bea90341..06f9a814cf 100644 --- a/circuit/program/src/data/plaintext/to_bits.rs +++ b/circuit/program/src/data/plaintext/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -23,10 +24,12 @@ impl ToBits for Plaintext { Self::Literal(literal, bits_le) => { // Compute the bits of the literal. let bits = bits_le.get_or_init(|| { - let mut bits_le = vec![Boolean::constant(false), Boolean::constant(false)]; // Variant bit. + let mut bits_le = Vec::new(); + bits_le.extend([Boolean::constant(false), Boolean::constant(false)]); // Variant bit. literal.variant().write_bits_le(&mut bits_le); literal.size_in_bits().write_bits_le(&mut bits_le); literal.write_bits_le(&mut bits_le); + bits_le.shrink_to_fit(); bits_le }); // Extend the vector with the bits of the literal. @@ -35,15 +38,17 @@ impl ToBits for Plaintext { Self::Struct(members, bits_le) => { // Compute the bits of the struct. let bits = bits_le.get_or_init(|| { - let mut bits_le = vec![Boolean::constant(false), Boolean::constant(true)]; // Variant bit. + let mut bits_le = Vec::new(); + bits_le.extend([Boolean::constant(false), Boolean::constant(true)]); // Variant bit. U8::constant(console::U8::new(members.len() as u8)).write_bits_le(&mut bits_le); for (identifier, value) in members { let value_bits = value.to_bits_le(); identifier.size_in_bits().write_bits_le(&mut bits_le); identifier.write_bits_le(&mut bits_le); U16::constant(console::U16::new(value_bits.len() as u16)).write_bits_le(&mut bits_le); - bits_le.extend_from_slice(&value_bits); + bits_le.extend(value_bits); } + bits_le.shrink_to_fit(); bits_le }); // Extend the vector with the bits of the struct. @@ -52,13 +57,15 @@ impl ToBits for Plaintext { Self::Array(elements, bits_le) => { // Compute the bits of the array. let bits = bits_le.get_or_init(|| { - let mut bits_le = vec![Boolean::constant(true), Boolean::constant(false)]; // Variant bit. + let mut bits_le = Vec::new(); + bits_le.extend([Boolean::constant(true), Boolean::constant(false)]); // Variant bit. U32::constant(console::U32::new(elements.len() as u32)).write_bits_le(&mut bits_le); for value in elements { let value_bits = value.to_bits_le(); U16::constant(console::U16::new(value_bits.len() as u16)).write_bits_le(&mut bits_le); bits_le.extend(value_bits); } + bits_le.shrink_to_fit(); bits_le }); // Extend the vector with the bits of the array. @@ -73,10 +80,12 @@ impl ToBits for Plaintext { Self::Literal(literal, bits_be) => { // Compute the bits of the literal. let bits = bits_be.get_or_init(|| { - let mut bits_be = vec![Boolean::constant(false), Boolean::constant(false)]; // Variant bit. + let mut bits_be = Vec::new(); + bits_be.extend([Boolean::constant(false), Boolean::constant(false)]); // Variant bit. literal.variant().write_bits_be(&mut bits_be); literal.size_in_bits().write_bits_be(&mut bits_be); literal.write_bits_be(&mut bits_be); + bits_be.shrink_to_fit(); bits_be }); // Extend the vector with the bits of the literal. @@ -85,15 +94,17 @@ impl ToBits for Plaintext { Self::Struct(members, bits_be) => { // Compute the bits of the struct. let bits = bits_be.get_or_init(|| { - let mut bits_be = vec![Boolean::constant(false), Boolean::constant(true)]; // Variant bit. + let mut bits_be = Vec::new(); + bits_be.extend([Boolean::constant(false), Boolean::constant(true)]); // Variant bit. U8::constant(console::U8::new(members.len() as u8)).write_bits_be(&mut bits_be); for (identifier, value) in members { let value_bits = value.to_bits_be(); identifier.size_in_bits().write_bits_be(&mut bits_be); identifier.write_bits_be(&mut bits_be); U16::constant(console::U16::new(value_bits.len() as u16)).write_bits_be(&mut bits_be); - bits_be.extend_from_slice(&value_bits); + bits_be.extend(value_bits); } + bits_be.shrink_to_fit(); bits_be }); // Extend the vector with the bits of the struct. @@ -102,13 +113,15 @@ impl ToBits for Plaintext { Self::Array(elements, bits_be) => { // Compute the bits of the array. let bits = bits_be.get_or_init(|| { - let mut bits_be = vec![Boolean::constant(true), Boolean::constant(false)]; // Variant bit. + let mut bits_be = Vec::new(); + bits_be.extend([Boolean::constant(true), Boolean::constant(false)]); // Variant bit. U32::constant(console::U32::new(elements.len() as u32)).write_bits_be(&mut bits_be); for value in elements { let value_bits = value.to_bits_be(); U16::constant(console::U16::new(value_bits.len() as u16)).write_bits_be(&mut bits_be); bits_be.extend(value_bits); } + bits_be.shrink_to_fit(); bits_be }); // Extend the vector with the bits of the array. diff --git a/circuit/program/src/data/plaintext/to_fields.rs b/circuit/program/src/data/plaintext/to_fields.rs index f3b11ef1b0..23e468e3d1 100644 --- a/circuit/program/src/data/plaintext/to_fields.rs +++ b/circuit/program/src/data/plaintext/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/decrypt.rs b/circuit/program/src/data/record/decrypt.rs index b7f9d1a0bd..5474423bf5 100644 --- a/circuit/program/src/data/record/decrypt.rs +++ b/circuit/program/src/data/record/decrypt.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -82,7 +83,7 @@ impl Record> { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::{Circuit, Literal}; diff --git a/circuit/program/src/data/record/encrypt.rs b/circuit/program/src/data/record/encrypt.rs index 6b5b7250b0..f1ebdee8e9 100644 --- a/circuit/program/src/data/record/encrypt.rs +++ b/circuit/program/src/data/record/encrypt.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/entry/equal.rs b/circuit/program/src/data/record/entry/equal.rs index 41944b49f1..6c6e4c0b5b 100644 --- a/circuit/program/src/data/record/entry/equal.rs +++ b/circuit/program/src/data/record/entry/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/entry/find.rs b/circuit/program/src/data/record/entry/find.rs index c11d6b9044..7b9d8963f7 100644 --- a/circuit/program/src/data/record/entry/find.rs +++ b/circuit/program/src/data/record/entry/find.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/entry/mod.rs b/circuit/program/src/data/record/entry/mod.rs index d622921958..95c958681e 100644 --- a/circuit/program/src/data/record/entry/mod.rs +++ b/circuit/program/src/data/record/entry/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,7 +20,7 @@ mod to_bits; use crate::{Access, Ciphertext, Plaintext, Visibility}; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Boolean}; +use snarkvm_circuit_types::{Boolean, environment::prelude::*}; /// An entry stored in program data. #[derive(Clone)] @@ -32,7 +33,7 @@ pub enum Entry> { Private(Private), } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Entry> { type Primitive = console::Entry>; @@ -46,7 +47,7 @@ impl Inject for Entry> { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Entry> { type Primitive = console::Entry>; @@ -60,7 +61,7 @@ impl Inject for Entry> { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Entry> { type Primitive = console::Entry>; @@ -83,7 +84,7 @@ impl Eject for Entry> { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Entry> { type Primitive = console::Entry>; diff --git a/circuit/program/src/data/record/entry/num_randomizers.rs b/circuit/program/src/data/record/entry/num_randomizers.rs index c1817982d7..ecb0d44484 100644 --- a/circuit/program/src/data/record/entry/num_randomizers.rs +++ b/circuit/program/src/data/record/entry/num_randomizers.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/entry/to_bits.rs b/circuit/program/src/data/record/entry/to_bits.rs index f7a7576a26..121740d034 100644 --- a/circuit/program/src/data/record/entry/to_bits.rs +++ b/circuit/program/src/data/record/entry/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/equal.rs b/circuit/program/src/data/record/equal.rs index cf55bf5ab7..560ccef0e4 100644 --- a/circuit/program/src/data/record/equal.rs +++ b/circuit/program/src/data/record/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/find.rs b/circuit/program/src/data/record/find.rs index 577a7025cb..e382cb7738 100644 --- a/circuit/program/src/data/record/find.rs +++ b/circuit/program/src/data/record/find.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/helpers/mod.rs b/circuit/program/src/data/record/helpers/mod.rs index 1770e4373a..16918fea74 100644 --- a/circuit/program/src/data/record/helpers/mod.rs +++ b/circuit/program/src/data/record/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/helpers/owner.rs b/circuit/program/src/data/record/helpers/owner.rs index 93cfb9ac21..351e163745 100644 --- a/circuit/program/src/data/record/helpers/owner.rs +++ b/circuit/program/src/data/record/helpers/owner.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use crate::{Ciphertext, Entry, Literal, Plaintext, Visibility}; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Address, Boolean, Field}; +use snarkvm_circuit_types::{Address, Boolean, Field, environment::prelude::*}; /// A value stored in program data. #[derive(Clone)] @@ -25,7 +26,7 @@ pub enum Owner> { Private(Private), } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Owner> { type Primitive = console::Owner>; @@ -44,7 +45,7 @@ impl Inject for Owner> { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Owner> { type Primitive = console::Owner>; diff --git a/circuit/program/src/data/record/mod.rs b/circuit/program/src/data/record/mod.rs index cd1fdc47e5..7d92025424 100644 --- a/circuit/program/src/data/record/mod.rs +++ b/circuit/program/src/data/record/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -35,7 +36,7 @@ mod to_fields; use crate::{Access, Ciphertext, Identifier, Plaintext, ProgramID, Visibility}; use snarkvm_circuit_account::{PrivateKey, ViewKey}; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Boolean, Field, Group, Scalar, U32}; +use snarkvm_circuit_types::{Boolean, Field, Group, Scalar, U32, environment::prelude::*}; #[derive(Clone)] pub struct Record> { @@ -47,7 +48,7 @@ pub struct Record> { nonce: Group, } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Record> { type Primitive = console::Record>; @@ -61,7 +62,7 @@ impl Inject for Record> { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Record> { type Primitive = console::Record>; @@ -75,7 +76,7 @@ impl Inject for Record> { } } -#[cfg(console)] +#[cfg(feature = "console")] impl> Record { /// Initializes a new record plaintext. pub fn from_plaintext( @@ -131,7 +132,7 @@ impl> Record { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Record> { type Primitive = console::Record>; @@ -172,7 +173,7 @@ impl Eject for Record> { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Record> { type Primitive = console::Record>; @@ -213,7 +214,7 @@ impl Eject for Record> { } } -#[cfg(console)] +#[cfg(feature = "console")] impl> TypeName for Record { fn type_name() -> &'static str { "record" diff --git a/circuit/program/src/data/record/num_randomizers.rs b/circuit/program/src/data/record/num_randomizers.rs index 7c0fd9e51a..12e6f8419f 100644 --- a/circuit/program/src/data/record/num_randomizers.rs +++ b/circuit/program/src/data/record/num_randomizers.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/serial_number.rs b/circuit/program/src/data/record/serial_number.rs index 746b9b1bc3..3b76769b91 100644 --- a/circuit/program/src/data/record/serial_number.rs +++ b/circuit/program/src/data/record/serial_number.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/tag.rs b/circuit/program/src/data/record/tag.rs index d62d66b12b..3273aae525 100644 --- a/circuit/program/src/data/record/tag.rs +++ b/circuit/program/src/data/record/tag.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/to_bits.rs b/circuit/program/src/data/record/to_bits.rs index f49a8757f5..8cb1d5b148 100644 --- a/circuit/program/src/data/record/to_bits.rs +++ b/circuit/program/src/data/record/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/to_commitment.rs b/circuit/program/src/data/record/to_commitment.rs index ced6f5dbf4..22a5936447 100644 --- a/circuit/program/src/data/record/to_commitment.rs +++ b/circuit/program/src/data/record/to_commitment.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/record/to_fields.rs b/circuit/program/src/data/record/to_fields.rs index d05627178a..3d745e56b5 100644 --- a/circuit/program/src/data/record/to_fields.rs +++ b/circuit/program/src/data/record/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/value/equal.rs b/circuit/program/src/data/value/equal.rs index 719de326ab..e83a2e7681 100644 --- a/circuit/program/src/data/value/equal.rs +++ b/circuit/program/src/data/value/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/value/find.rs b/circuit/program/src/data/value/find.rs index 487a69eb67..0d4a3efd78 100644 --- a/circuit/program/src/data/value/find.rs +++ b/circuit/program/src/data/value/find.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/value/mod.rs b/circuit/program/src/data/value/mod.rs index 5d7dd965ae..4f0f862acd 100644 --- a/circuit/program/src/data/value/mod.rs +++ b/circuit/program/src/data/value/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,7 +20,7 @@ mod to_fields; use crate::{Access, Entry, Future, Plaintext, Record}; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Boolean, Field}; +use snarkvm_circuit_types::{Boolean, Field, environment::prelude::*}; #[derive(Clone)] pub enum Value { diff --git a/circuit/program/src/data/value/to_bits.rs b/circuit/program/src/data/value/to_bits.rs index 67765029fc..ac3c385cb4 100644 --- a/circuit/program/src/data/value/to_bits.rs +++ b/circuit/program/src/data/value/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/data/value/to_fields.rs b/circuit/program/src/data/value/to_fields.rs index fad34f0c1d..518d4d2917 100644 --- a/circuit/program/src/data/value/to_fields.rs +++ b/circuit/program/src/data/value/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/function_id/mod.rs b/circuit/program/src/function_id/mod.rs new file mode 100644 index 0000000000..14e6c37777 --- /dev/null +++ b/circuit/program/src/function_id/mod.rs @@ -0,0 +1,38 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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::{Identifier, ProgramID}; +use snarkvm_circuit_network::Aleo; +use snarkvm_circuit_types::{Field, U16, environment::prelude::*}; + +/// Compute the function ID as `Hash(network_id, program_id.len(), program_id, function_name.len(), function_name)`. +pub fn compute_function_id( + network_id: &U16, + program_id: &ProgramID, + function_name: &Identifier, +) -> Field { + A::hash_bhp1024( + &( + network_id, + program_id.name().size_in_bits(), + program_id.name(), + program_id.network().size_in_bits(), + program_id.network(), + function_name.size_in_bits(), + function_name, + ) + .to_bits_le(), + ) +} diff --git a/circuit/program/src/id/mod.rs b/circuit/program/src/id/mod.rs index 623480f6c8..9028322ade 100644 --- a/circuit/program/src/id/mod.rs +++ b/circuit/program/src/id/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,7 +22,7 @@ mod to_fields; use crate::Identifier; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Address, Boolean, Field}; +use snarkvm_circuit_types::{Address, Boolean, Field, environment::prelude::*}; /// A program ID is of the form `{name}.{network}`. /// If no `network`-level domain is specified, the default network is used. @@ -33,7 +34,7 @@ pub struct ProgramID { network: Identifier, } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for ProgramID { type Primitive = console::ProgramID; @@ -60,7 +61,7 @@ impl ProgramID { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for ProgramID { type Primitive = console::ProgramID; diff --git a/circuit/program/src/id/to_address.rs b/circuit/program/src/id/to_address.rs index dc1ee1c5a9..81c14f6ea9 100644 --- a/circuit/program/src/id/to_address.rs +++ b/circuit/program/src/id/to_address.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -27,7 +28,7 @@ impl ProgramID { #[cfg(test)] mod tests { use super::*; - use crate::{data::identifier::tests::sample_lowercase_console_identifier_as_string, Circuit}; + use crate::{Circuit, data::identifier::tests::sample_lowercase_console_identifier_as_string}; use anyhow::Result; diff --git a/circuit/program/src/id/to_bits.rs b/circuit/program/src/id/to_bits.rs index ca35033269..5d6867bb24 100644 --- a/circuit/program/src/id/to_bits.rs +++ b/circuit/program/src/id/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -47,7 +48,7 @@ impl ToBits for &ProgramID { #[cfg(test)] mod tests { use super::*; - use crate::{data::identifier::tests::sample_lowercase_console_identifier_as_string, Circuit}; + use crate::{Circuit, data::identifier::tests::sample_lowercase_console_identifier_as_string}; use anyhow::Result; diff --git a/circuit/program/src/id/to_fields.rs b/circuit/program/src/id/to_fields.rs index c30e6f8988..eb12fe1d02 100644 --- a/circuit/program/src/id/to_fields.rs +++ b/circuit/program/src/id/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/lib.rs b/circuit/program/src/lib.rs index cf9be261cd..450a5c42a1 100644 --- a/circuit/program/src/lib.rs +++ b/circuit/program/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -22,6 +23,9 @@ use snarkvm_circuit_network::AleoV0 as Circuit; mod data; pub use data::*; +mod function_id; +pub use function_id::*; + mod id; pub use id::*; @@ -35,7 +39,7 @@ mod state_path; pub use state_path::*; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Boolean}; +use snarkvm_circuit_types::{Boolean, environment::prelude::*}; pub trait Visibility: Equal::Boolean> + ToBits> + FromBits + ToFields + FromFields diff --git a/circuit/program/src/request/mod.rs b/circuit/program/src/request/mod.rs index 0a7424667a..a388909d37 100644 --- a/circuit/program/src/request/mod.rs +++ b/circuit/program/src/request/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,10 +19,10 @@ use snarkvm_circuit_types::environment::assert_scope; mod to_tpk; mod verify; -use crate::{Identifier, Plaintext, ProgramID, Record, Value}; +use crate::{Identifier, Plaintext, ProgramID, Record, Value, compute_function_id}; use snarkvm_circuit_account::Signature; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Address, Boolean, Field, Group, U16}; +use snarkvm_circuit_types::{Address, Boolean, Field, Group, U16, environment::prelude::*}; pub enum InputID { /// The hash of the constant input. @@ -36,7 +37,7 @@ pub enum InputID { ExternalRecord(Field), } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for InputID { type Primitive = console::InputID; @@ -62,7 +63,7 @@ impl Inject for InputID { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for InputID { type Primitive = console::InputID; @@ -136,9 +137,11 @@ pub struct Request { tvk: Field, /// The transition commitment. tcm: Field, + /// The signer commitment. + scm: Field, } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Request { type Primitive = console::Request; @@ -147,6 +150,9 @@ impl Inject for Request { // Inject the transition commitment `tcm` as `Mode::Public`. let tcm = Field::new(Mode::Public, *request.tcm()); + // Inject the signer commitment `scm` as `Mode::Public`. + let scm = Field::new(Mode::Public, *request.scm()); + // Inject the inputs. let inputs = match request .input_ids() @@ -218,6 +224,7 @@ impl Inject for Request { sk_tag: Field::new(mode, *request.sk_tag()), tvk: Field::new(mode, *request.tvk()), tcm, + scm, } } } @@ -272,9 +279,14 @@ impl Request { pub const fn tcm(&self) -> &Field { &self.tcm } + + /// Returns the signer commitment. + pub const fn scm(&self) -> &Field { + &self.scm + } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Request { type Primitive = console::Request; @@ -290,6 +302,7 @@ impl Eject for Request { self.sk_tag.eject_mode(), self.tvk.eject_mode(), self.tcm.eject_mode(), + self.scm.eject_mode(), ]) } @@ -306,6 +319,7 @@ impl Eject for Request { self.sk_tag.eject_value(), self.tvk.eject_value(), self.tcm.eject_value(), + self.scm.eject_value(), )) } } diff --git a/circuit/program/src/request/to_tpk.rs b/circuit/program/src/request/to_tpk.rs index 122bef71f8..59e51833fb 100644 --- a/circuit/program/src/request/to_tpk.rs +++ b/circuit/program/src/request/to_tpk.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/request/verify.rs b/circuit/program/src/request/verify.rs index 86dd773a28..fa42a83521 100644 --- a/circuit/program/src/request/verify.rs +++ b/circuit/program/src/request/verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,21 +17,29 @@ use super::*; impl Request { /// Returns `true` if the input IDs are derived correctly, the input records all belong to the signer, - /// and the signature is valid. tpk is passed separately so it can have a Mode different from Self. + /// and the signature is valid. /// /// Verifies (challenge == challenge') && (address == address') && (serial_numbers == serial_numbers') where: /// challenge' := HashToScalar(r * G, pk_sig, pr_sig, signer, \[tvk, tcm, function ID, input IDs\]) - pub fn verify(&self, input_types: &[console::ValueType], tpk: &Group) -> Boolean { - // Compute the function ID as `Hash(network_id, program_id, function_name)`. - let function_id = A::hash_bhp1024( - &(&self.network_id, self.program_id.name(), self.program_id.network(), &self.function_name).to_bits_le(), - ); + pub fn verify( + &self, + input_types: &[console::ValueType], + tpk: &Group, + root_tvk: Option>, + is_root: Boolean, + ) -> Boolean { + // Compute the function ID. + let function_id = compute_function_id(&self.network_id, &self.program_id, &self.function_name); + + // Compute 'is_root' as a field element. + let is_root = Ternary::ternary(&is_root, &Field::::one(), &Field::::zero()); // Construct the signature message as `[tvk, tcm, function ID, input IDs]`. let mut message = Vec::with_capacity(3 + 4 * self.input_ids.len()); message.push(self.tvk.clone()); message.push(self.tcm.clone()); message.push(function_id); + message.push(is_root); // Check the input IDs and construct the rest of the signature message. let (input_checks, append_to_message) = Self::check_input_ids::( @@ -52,15 +61,21 @@ impl Request { None => A::halt("Missing input elements in request verification"), } - // Verify the transition public key and commitment are well-formed. + let root_tvk = root_tvk.unwrap_or(Field::::new(Mode::Private, self.tvk.eject_value())); + + // Verify the transition public key and commitments are well-formed. let tpk_checks = { // Compute the transition commitment as `Hash(tvk)`. let tcm = A::hash_psd2(&[self.tvk.clone()]); + // Compute the signer commitment as `Hash(signer || root_tvk)`. + let scm = A::hash_psd2(&[self.signer.to_field(), root_tvk]); // Ensure the transition public key matches with the saved one from the signature. tpk.is_equal(&self.to_tpk()) // Ensure the computed transition commitment matches. & tcm.is_equal(&self.tcm) + // Ensure the computed signer commitment matches. + & scm.is_equal(&self.scm) }; // Verify the signature. @@ -111,9 +126,8 @@ impl Request { false => assert!(signature.is_none()), } - // Compute the function ID as `Hash(network_id, program_id, function_name)`. - let function_id = - A::hash_bhp1024(&(network_id, program_id.name(), program_id.network(), function_name).to_bits_le()); + // Compute the function ID. + let function_id = compute_function_id(network_id, program_id, function_name); // Initialize a vector for a message. let mut message = Vec::new(); @@ -294,7 +308,7 @@ impl Request { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; @@ -350,17 +364,33 @@ mod tests { console::ValueType::from_str("token.aleo/token.record").unwrap(), ]; + // Sample 'root_tvk'. + let root_tvk = None; + + // Sample 'is_root'. + let is_root = true; + // Compute the signed request. - let request = - console::Request::sign(&private_key, program_id, function_name, inputs.iter(), &input_types, rng)?; - assert!(request.verify(&input_types)); + let request = console::Request::sign( + &private_key, + program_id, + function_name, + inputs.iter(), + &input_types, + root_tvk, + is_root, + rng, + )?; + assert!(request.verify(&input_types, is_root)); // Inject the request into a circuit. let tpk = Group::::new(mode, request.to_tpk()); let request = Request::::new(mode, request); + let is_root = Boolean::new(mode, is_root); Circuit::scope(format!("Request {i}"), || { - let candidate = request.verify(&input_types, &tpk); + let root_tvk = None; + let candidate = request.verify(&input_types, &tpk, root_tvk, is_root); assert!(candidate.eject_value()); match mode.is_constant() { true => assert_scope!(<=num_constants, <=num_public, <=num_private, <=num_constraints), @@ -394,16 +424,16 @@ mod tests { // Note: This is correct. At this (high) level of a program, we override the default mode in the `Record` case, // based on the user-defined visibility in the record type. Thus, we have nonzero private and constraint values. // These bounds are determined experimentally. - check_verify(Mode::Constant, 42520, 0, 17494, 17518) + check_verify(Mode::Constant, 43000, 0, 18000, 18000) } #[test] fn test_sign_and_verify_public() -> Result<()> { - check_verify(Mode::Public, 40018, 0, 26401, 26429) + check_verify(Mode::Public, 40131, 0, 26675, 26702) } #[test] fn test_sign_and_verify_private() -> Result<()> { - check_verify(Mode::Private, 40018, 0, 26401, 26429) + check_verify(Mode::Private, 40131, 0, 26675, 26702) } } diff --git a/circuit/program/src/response/from_outputs.rs b/circuit/program/src/response/from_outputs.rs index 5618e8702d..efff43271c 100644 --- a/circuit/program/src/response/from_outputs.rs +++ b/circuit/program/src/response/from_outputs.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -27,9 +28,8 @@ impl Response { output_types: &[console::ValueType], // Note: Console type output_registers: &[Option>], // Note: Console type ) -> Self { - // Compute the function ID as `Hash(network_id, program_id, function_name)`. - let function_id = - A::hash_bhp1024(&(network_id, program_id.name(), program_id.network(), function_name).to_bits_le()); + // Compute the function ID. + let function_id = compute_function_id(network_id, program_id, function_name); // Compute the output IDs. let output_ids = outputs @@ -175,7 +175,7 @@ impl Response { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; @@ -302,11 +302,11 @@ mod tests { #[test] fn test_from_outputs_public() -> Result<()> { - check_from_outputs(Mode::Public, 24793, 6, 13962, 13983) + check_from_outputs(Mode::Public, 24849, 6, 13962, 13983) } #[test] fn test_from_outputs_private() -> Result<()> { - check_from_outputs(Mode::Private, 24793, 6, 13962, 13983) + check_from_outputs(Mode::Private, 24849, 6, 13962, 13983) } } diff --git a/circuit/program/src/response/mod.rs b/circuit/program/src/response/mod.rs index 897f1c09a9..b61f6cbabf 100644 --- a/circuit/program/src/response/mod.rs +++ b/circuit/program/src/response/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,9 +19,9 @@ use snarkvm_circuit_types::environment::assert_scope; mod from_outputs; mod process_outputs_from_callback; -use crate::{Identifier, ProgramID, Value}; +use crate::{Identifier, ProgramID, Value, compute_function_id}; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Field, U16}; +use snarkvm_circuit_types::{Field, U16, environment::prelude::*}; pub enum OutputID { /// The hash of the constant output. @@ -37,7 +38,7 @@ pub enum OutputID { Future(Field), } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for OutputID { type Primitive = console::OutputID; @@ -126,7 +127,7 @@ impl OutputID { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for OutputID { type Primitive = console::OutputID; @@ -176,7 +177,7 @@ impl Response { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Response { type Primitive = console::Response; diff --git a/circuit/program/src/response/process_outputs_from_callback.rs b/circuit/program/src/response/process_outputs_from_callback.rs index 287c8fd549..1a985d2f8b 100644 --- a/circuit/program/src/response/process_outputs_from_callback.rs +++ b/circuit/program/src/response/process_outputs_from_callback.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -26,9 +27,8 @@ impl Response { outputs: Vec>, // Note: Console type output_types: &[console::ValueType], // Note: Console type ) -> Vec> { - // Compute the function ID as `Hash(network_id, program_id, function_name)`. - let function_id = - A::hash_bhp1024(&(network_id, program_id.name(), program_id.network(), function_name).to_bits_le()); + // Compute the function ID. + let function_id = compute_function_id(network_id, program_id, function_name); match outputs .iter() @@ -190,7 +190,7 @@ impl Response { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; @@ -326,16 +326,16 @@ mod tests { #[test] fn test_from_callback_constant() -> Result<()> { - check_from_callback(Mode::Constant, 20788, 5, 4922, 4931) + check_from_callback(Mode::Constant, 20844, 5, 4922, 4931) } #[test] fn test_from_callback_public() -> Result<()> { - check_from_callback(Mode::Public, 20788, 5, 6217, 6226) + check_from_callback(Mode::Public, 20844, 5, 6217, 6226) } #[test] fn test_from_callback_private() -> Result<()> { - check_from_callback(Mode::Private, 20788, 5, 6217, 6226) + check_from_callback(Mode::Private, 20844, 5, 6217, 6226) } } diff --git a/circuit/program/src/state_path/helpers/header_leaf.rs b/circuit/program/src/state_path/helpers/header_leaf.rs index 9f3f0903d3..fd32096809 100644 --- a/circuit/program/src/state_path/helpers/header_leaf.rs +++ b/circuit/program/src/state_path/helpers/header_leaf.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Boolean, Field, U8}; +use snarkvm_circuit_types::{Boolean, Field, U8, environment::prelude::*}; #[derive(Clone)] pub struct HeaderLeaf { diff --git a/circuit/program/src/state_path/helpers/mod.rs b/circuit/program/src/state_path/helpers/mod.rs index f2fbeff848..8a19668c44 100644 --- a/circuit/program/src/state_path/helpers/mod.rs +++ b/circuit/program/src/state_path/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/program/src/state_path/helpers/transaction_leaf.rs b/circuit/program/src/state_path/helpers/transaction_leaf.rs index 8248cd6683..564033d9df 100644 --- a/circuit/program/src/state_path/helpers/transaction_leaf.rs +++ b/circuit/program/src/state_path/helpers/transaction_leaf.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Boolean, Field, U16, U8}; +use snarkvm_circuit_types::{Boolean, Field, U8, U16, environment::prelude::*}; #[derive(Clone)] pub struct TransactionLeaf { diff --git a/circuit/program/src/state_path/helpers/transition_leaf.rs b/circuit/program/src/state_path/helpers/transition_leaf.rs index 2ec99163de..b2ffb4c243 100644 --- a/circuit/program/src/state_path/helpers/transition_leaf.rs +++ b/circuit/program/src/state_path/helpers/transition_leaf.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Boolean, Field, U8}; +use snarkvm_circuit_types::{Boolean, Field, U8, environment::prelude::*}; #[derive(Clone)] pub struct TransitionLeaf { diff --git a/circuit/program/src/state_path/mod.rs b/circuit/program/src/state_path/mod.rs index d8cf025aa6..66a1fc5b49 100644 --- a/circuit/program/src/state_path/mod.rs +++ b/circuit/program/src/state_path/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -22,7 +23,7 @@ use snarkvm_circuit_types::environment::assert_scope; use snarkvm_circuit_collections::merkle_tree::MerklePath; use snarkvm_circuit_network::Aleo; -use snarkvm_circuit_types::{environment::prelude::*, Boolean, Field, U8}; +use snarkvm_circuit_types::{Boolean, Field, U8, environment::prelude::*}; /// The depth of the Merkle tree for the blocks. const BLOCKS_DEPTH: u8 = console::BLOCKS_DEPTH; @@ -152,7 +153,7 @@ impl Eject for StatePath { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use crate::Circuit; @@ -191,16 +192,16 @@ mod tests { #[test] fn test_state_path_new_constant() -> Result<()> { - check_new(Mode::Constant, 446, 1, 0, 0) + check_new(Mode::Constant, 450, 1, 0, 0) } #[test] fn test_state_path_new_public() -> Result<()> { - check_new(Mode::Public, 0, 447, 0, 376) + check_new(Mode::Public, 0, 451, 0, 376) } #[test] fn test_state_path_new_private() -> Result<()> { - check_new(Mode::Private, 0, 1, 446, 376) + check_new(Mode::Private, 0, 1, 450, 376) } } diff --git a/circuit/program/src/state_path/verify.rs b/circuit/program/src/state_path/verify.rs index f4c6e624cc..d94dc49bd1 100644 --- a/circuit/program/src/state_path/verify.rs +++ b/circuit/program/src/state_path/verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -225,43 +226,43 @@ mod tests { #[test] fn test_state_path_verify_global_constant() -> Result<()> { - check_verify_global(Mode::Constant, true, 106309, 1, 2, 2)?; - check_verify_global(Mode::Constant, false, 106309, 1, 2, 2) + check_verify_global(Mode::Constant, true, 112709, 1, 2, 2)?; + check_verify_global(Mode::Constant, false, 112709, 1, 2, 2) } #[test] fn test_state_path_verify_global_public() -> Result<()> { - check_verify_global(Mode::Public, true, 27814, 449, 123343, 123982)?; - check_verify_global(Mode::Public, false, 27814, 449, 123343, 123982) + check_verify_global(Mode::Public, true, 29450, 453, 130867, 131522)?; + check_verify_global(Mode::Public, false, 29450, 453, 130867, 131522) } #[test] fn test_state_path_verify_global_private() -> Result<()> { - check_verify_global(Mode::Private, true, 27814, 1, 123791, 123982)?; - check_verify_global(Mode::Private, false, 27814, 1, 123791, 123982) + check_verify_global(Mode::Private, true, 29450, 1, 131319, 131522)?; + check_verify_global(Mode::Private, false, 29450, 1, 131319, 131522) } #[test] fn test_state_path_verify_local_constant() -> Result<()> { - check_verify_local(Mode::Constant, false, true, 106309, 1, 2, 2)?; - check_verify_local(Mode::Constant, false, false, 106309, 1, 2, 2)?; - check_verify_local(Mode::Constant, true, true, 106309, 1, 2, 2)?; - check_verify_local(Mode::Constant, true, false, 106309, 1, 2, 2) + check_verify_local(Mode::Constant, false, true, 112709, 1, 2, 2)?; + check_verify_local(Mode::Constant, false, false, 112709, 1, 2, 2)?; + check_verify_local(Mode::Constant, true, true, 112709, 1, 2, 2)?; + check_verify_local(Mode::Constant, true, false, 112709, 1, 2, 2) } #[test] fn test_state_path_verify_local_public() -> Result<()> { - check_verify_local(Mode::Public, false, true, 27814, 449, 123343, 123982)?; - check_verify_local(Mode::Public, false, false, 27814, 449, 123343, 123982)?; - check_verify_local(Mode::Public, true, true, 27814, 449, 123343, 123982)?; - check_verify_local(Mode::Public, true, false, 27814, 449, 123343, 123982) + check_verify_local(Mode::Public, false, true, 29450, 453, 130867, 131522)?; + check_verify_local(Mode::Public, false, false, 29450, 453, 130867, 131522)?; + check_verify_local(Mode::Public, true, true, 29450, 453, 130867, 131522)?; + check_verify_local(Mode::Public, true, false, 29450, 453, 130867, 131522) } #[test] fn test_state_path_verify_local_private() -> Result<()> { - check_verify_local(Mode::Private, false, true, 27814, 1, 123791, 123982)?; - check_verify_local(Mode::Private, false, false, 27814, 1, 123791, 123982)?; - check_verify_local(Mode::Private, true, true, 27814, 1, 123791, 123982)?; - check_verify_local(Mode::Private, true, false, 27814, 1, 123791, 123982) + check_verify_local(Mode::Private, false, true, 29450, 1, 131319, 131522)?; + check_verify_local(Mode::Private, false, false, 29450, 1, 131319, 131522)?; + check_verify_local(Mode::Private, true, true, 29450, 1, 131319, 131522)?; + check_verify_local(Mode::Private, true, false, 29450, 1, 131319, 131522) } } diff --git a/circuit/src/lib.rs b/circuit/src/lib.rs index 785026670e..c5ee310244 100644 --- a/circuit/src/lib.rs +++ b/circuit/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -27,7 +28,16 @@ pub mod modules { pub use snarkvm_circuit_collections::*; pub use snarkvm_circuit_environment as environment; - pub use snarkvm_circuit_environment::{Assignment, Circuit, Eject, Environment, Inject, Mode}; + pub use snarkvm_circuit_environment::{ + Assignment, + CanaryCircuit, + Circuit, + Eject, + Environment, + Inject, + Mode, + TestnetCircuit, + }; pub use snarkvm_circuit_network as network; pub use snarkvm_circuit_network::*; diff --git a/circuit/types/Cargo.toml b/circuit/types/Cargo.toml index b2448c60b3..4929309e69 100644 --- a/circuit/types/Cargo.toml +++ b/circuit/types/Cargo.toml @@ -1,42 +1,44 @@ [package] name = "snarkvm-circuit-types" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Primitive circuit for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.snarkvm-circuit-environment] path = "../environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-address] path = "./address" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-boolean] path = "./boolean" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-field] path = "./field" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-group] path = "./group" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-integers] path = "./integers" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-scalar] path = "./scalar" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-string] path = "./string" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.console] package = "snarkvm-console" diff --git a/circuit/types/address/Cargo.toml b/circuit/types/address/Cargo.toml index d859d594f7..63c5bfd9aa 100644 --- a/circuit/types/address/Cargo.toml +++ b/circuit/types/address/Cargo.toml @@ -1,36 +1,38 @@ [package] name = "snarkvm-circuit-types-address" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Address circuit for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.console] package = "snarkvm-console-types-address" path = "../../../console/types/address" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit-environment] path = "../../environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-boolean] path = "../boolean" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-field] path = "../field" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-group] path = "../group" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-scalar] path = "../scalar" -version = "=0.16.19" +version = "=1.1.0" [features] default = [ "enable_console" ] diff --git a/circuit/types/address/build.rs b/circuit/types/address/build.rs index ff14549b2c..1d0fe74e7c 100644 --- a/circuit/types/address/build.rs +++ b/circuit/types/address/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/address/src/compare.rs b/circuit/types/address/src/compare.rs index 078bb3365d..a17747f633 100644 --- a/circuit/types/address/src/compare.rs +++ b/circuit/types/address/src/compare.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/address/src/equal.rs b/circuit/types/address/src/equal.rs index a173a7d73c..1902464f77 100644 --- a/circuit/types/address/src/equal.rs +++ b/circuit/types/address/src/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -28,7 +29,7 @@ impl Equal for Address { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_environment::Circuit; @@ -49,12 +50,12 @@ mod tests { let a = Address::::from_group(Group::new(mode_a, Uniform::rand(rng))); let b = Address::::from_group(Group::new(mode_b, Uniform::rand(rng))); - Circuit::scope(&format!("{mode_a} {mode_a} {i}"), || { + Circuit::scope(format!("{mode_a} {mode_a} {i}"), || { let equals = a.is_equal(&a); assert!(equals.eject_value()); }); - Circuit::scope(&format!("{mode_a} {mode_b} {i}"), || { + Circuit::scope(format!("{mode_a} {mode_b} {i}"), || { let equals = a.is_equal(&b); assert!(!equals.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); @@ -76,12 +77,12 @@ mod tests { let a = Address::::from_group(Group::new(mode_a, Uniform::rand(rng))); let b = Address::::from_group(Group::new(mode_b, Uniform::rand(rng))); - Circuit::scope(&format!("{mode_a} {mode_a} {i}"), || { + Circuit::scope(format!("{mode_a} {mode_a} {i}"), || { let equals = a.is_not_equal(&a); assert!(!equals.eject_value()); }); - Circuit::scope(&format!("{mode_a} {mode_b} {i}"), || { + Circuit::scope(format!("{mode_a} {mode_b} {i}"), || { let equals = a.is_not_equal(&b); assert!(equals.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); diff --git a/circuit/types/address/src/helpers/from_bits.rs b/circuit/types/address/src/helpers/from_bits.rs index 712068da2b..0cfc1c8600 100644 --- a/circuit/types/address/src/helpers/from_bits.rs +++ b/circuit/types/address/src/helpers/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -28,7 +29,7 @@ impl FromBits for Address { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_environment::Circuit; @@ -43,7 +44,7 @@ mod tests { let expected: console::Group<::Network> = Uniform::rand(&mut rng); let candidate = Group::::new(mode, expected).to_bits_le(); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = Address::::from_bits_le(&candidate); assert_eq!(expected, *candidate.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); @@ -60,7 +61,7 @@ mod tests { let expected: console::Group<::Network> = Uniform::rand(&mut rng); let candidate = Group::::new(mode, expected).to_bits_be(); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = Address::::from_bits_be(&candidate); assert_eq!(expected, *candidate.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); diff --git a/circuit/types/address/src/helpers/from_field.rs b/circuit/types/address/src/helpers/from_field.rs index 74aaf1459f..ae73fa5c5b 100644 --- a/circuit/types/address/src/helpers/from_field.rs +++ b/circuit/types/address/src/helpers/from_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,7 +38,7 @@ impl FromField for Address { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_environment::Circuit; @@ -52,7 +53,7 @@ mod tests { let expected: console::Group<::Network> = Uniform::rand(&mut rng); let candidate = Group::::new(mode, expected).to_x_coordinate(); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = Address::from_field(candidate); assert_eq!(expected.to_x_coordinate(), candidate.eject_value().to_x_coordinate()); assert_scope!(num_constants, num_public, num_private, num_constraints); diff --git a/circuit/types/address/src/helpers/from_group.rs b/circuit/types/address/src/helpers/from_group.rs index 8ce7398f23..bc60ea526e 100644 --- a/circuit/types/address/src/helpers/from_group.rs +++ b/circuit/types/address/src/helpers/from_group.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -38,7 +39,7 @@ impl FromGroup for Address { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_environment::Circuit; diff --git a/circuit/types/address/src/helpers/mod.rs b/circuit/types/address/src/helpers/mod.rs index b8274b53e2..fe505fc1c7 100644 --- a/circuit/types/address/src/helpers/mod.rs +++ b/circuit/types/address/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/address/src/helpers/to_bits.rs b/circuit/types/address/src/helpers/to_bits.rs index f13850cb66..bfe4170d54 100644 --- a/circuit/types/address/src/helpers/to_bits.rs +++ b/circuit/types/address/src/helpers/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -42,7 +43,7 @@ impl ToBits for &Address { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_environment::Circuit; @@ -59,7 +60,7 @@ mod tests { let expected = Uniform::rand(&mut rng); let candidate = Address::::from_group(Group::new(mode, expected)); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_bits_le(); assert_eq!(expected_number_of_bits, candidate.len()); for (expected_bit, candidate_bit) in @@ -82,7 +83,7 @@ mod tests { let expected = Uniform::rand(&mut rng); let candidate = Address::::from_group(Group::new(mode, expected)); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_bits_be(); assert_eq!(expected_number_of_bits, candidate.len()); for (expected_bit, candidate_bit) in diff --git a/circuit/types/address/src/helpers/to_field.rs b/circuit/types/address/src/helpers/to_field.rs index c73d427945..e8664ba2dc 100644 --- a/circuit/types/address/src/helpers/to_field.rs +++ b/circuit/types/address/src/helpers/to_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,7 +38,7 @@ impl ToField for Address { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_environment::Circuit; @@ -52,7 +53,7 @@ mod tests { let expected = Uniform::rand(&mut rng); let candidate = Address::::from_group(Group::new(mode, expected)); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_field(); assert_eq!(expected.to_x_coordinate(), candidate.eject_value()); assert_scope!(0, 0, 0, 0); diff --git a/circuit/types/address/src/helpers/to_group.rs b/circuit/types/address/src/helpers/to_group.rs index 66bee8f575..b2a30bcb3c 100644 --- a/circuit/types/address/src/helpers/to_group.rs +++ b/circuit/types/address/src/helpers/to_group.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -38,7 +39,7 @@ impl ToGroup for Address { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_environment::Circuit; diff --git a/circuit/types/address/src/lib.rs b/circuit/types/address/src/lib.rs index 0e4dec4b5d..6d5cffb295 100644 --- a/circuit/types/address/src/lib.rs +++ b/circuit/types/address/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -47,7 +48,7 @@ impl Address { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Address { type Primitive = console::Address; @@ -57,7 +58,7 @@ impl Inject for Address { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Address { type Primitive = console::Address; @@ -72,7 +73,7 @@ impl Eject for Address { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Parser for Address { /// Parses a string into an address circuit. #[inline] @@ -89,7 +90,7 @@ impl Parser for Address { } } -#[cfg(console)] +#[cfg(feature = "console")] impl FromStr for Address { type Err = Error; @@ -108,7 +109,7 @@ impl FromStr for Address { } } -#[cfg(console)] +#[cfg(feature = "console")] impl TypeName for Address { /// Returns the type name of the circuit as a string. #[inline] @@ -117,14 +118,14 @@ impl TypeName for Address { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Debug for Address { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(self, f) } } -#[cfg(console)] +#[cfg(feature = "console")] impl Display for Address { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}.{}", self.eject_value(), self.eject_mode()) @@ -143,7 +144,7 @@ impl From<&Address> for LinearCombination { } } -#[cfg(all(test, console))] +#[cfg(all(test, feature = "console"))] mod tests { use super::*; use snarkvm_circuit_environment::Circuit; diff --git a/circuit/types/address/src/ternary.rs b/circuit/types/address/src/ternary.rs index 67298d8865..b807ed9ff2 100644 --- a/circuit/types/address/src/ternary.rs +++ b/circuit/types/address/src/ternary.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/Cargo.toml b/circuit/types/boolean/Cargo.toml index 6f9e9f2e3b..7d13450c56 100644 --- a/circuit/types/boolean/Cargo.toml +++ b/circuit/types/boolean/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "snarkvm-circuit-types-boolean" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Boolean circuit for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" @@ -14,12 +16,12 @@ harness = false [dependencies.console] package = "snarkvm-console-types-boolean" path = "../../../console/types/boolean" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit-environment] path = "../../environment" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.criterion] version = "0.5" diff --git a/circuit/types/boolean/benches/and.rs b/circuit/types/boolean/benches/and.rs index 53beb519da..ea8d23c2e9 100644 --- a/circuit/types/boolean/benches/and.rs +++ b/circuit/types/boolean/benches/and.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/build.rs b/circuit/types/boolean/build.rs index ff14549b2c..1d0fe74e7c 100644 --- a/circuit/types/boolean/build.rs +++ b/circuit/types/boolean/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/and.rs b/circuit/types/boolean/src/and.rs index 07db5e2cb4..f11c315ed8 100644 --- a/circuit/types/boolean/src/and.rs +++ b/circuit/types/boolean/src/and.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/equal.rs b/circuit/types/boolean/src/equal.rs index 7d5e732f21..30f9eac5d6 100644 --- a/circuit/types/boolean/src/equal.rs +++ b/circuit/types/boolean/src/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/helpers/adder.rs b/circuit/types/boolean/src/helpers/adder.rs index eb9d6064f5..c7598557ed 100644 --- a/circuit/types/boolean/src/helpers/adder.rs +++ b/circuit/types/boolean/src/helpers/adder.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -256,7 +257,8 @@ mod tests { check_true_add_false_with_false(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 0, 0); check_true_add_false_with_true(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 1, 1); // <- Differs check_true_add_true_with_false(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 0, 0); - check_true_add_true_with_true(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 1, 1); // <- Differs + check_true_add_true_with_true(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 1, 1); + // <- Differs } #[test] @@ -268,7 +270,8 @@ mod tests { check_true_add_false_with_false(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 3, 3); // <- Differs check_true_add_false_with_true(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 3, 3); // <- Differs check_true_add_true_with_false(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 3, 3); // <- Differs - check_true_add_true_with_true(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 3, 3); // <- Differs + check_true_add_true_with_true(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 3, 3); + // <- Differs } #[test] @@ -280,7 +283,8 @@ mod tests { check_true_add_false_with_false(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 3, 3); // <- Differs check_true_add_false_with_true(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 3, 3); // <- Differs check_true_add_true_with_false(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 3, 3); // <- Differs - check_true_add_true_with_true(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 3, 3); // <- Differs + check_true_add_true_with_true(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 3, 3); + // <- Differs } #[test] @@ -292,7 +296,8 @@ mod tests { check_true_add_false_with_false(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 0, 0); check_true_add_false_with_true(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 1, 1); // <- Differs check_true_add_true_with_false(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 0, 0); - check_true_add_true_with_true(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 1, 1); // <- Differs + check_true_add_true_with_true(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 1, 1); + // <- Differs } #[test] @@ -304,7 +309,8 @@ mod tests { check_true_add_false_with_false(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 3, 3); // <- Differs check_true_add_false_with_true(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 3, 3); // <- Differs check_true_add_true_with_false(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 3, 3); // <- Differs - check_true_add_true_with_true(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 3, 3); // <- Differs + check_true_add_true_with_true(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 3, 3); + // <- Differs } #[test] @@ -316,7 +322,8 @@ mod tests { check_true_add_false_with_false(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 3, 3); // <- Differs check_true_add_false_with_true(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 3, 3); // <- Differs check_true_add_true_with_false(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 3, 3); // <- Differs - check_true_add_true_with_true(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 3, 3); // <- Differs + check_true_add_true_with_true(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 3, 3); + // <- Differs } #[test] @@ -328,7 +335,8 @@ mod tests { check_true_add_false_with_false(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 0, 0); check_true_add_false_with_true(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 0, 0); check_true_add_true_with_false(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 0, 0); - check_true_add_true_with_true(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 1, 1); // <- Differs + check_true_add_true_with_true(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 1, 1); + // <- Differs } #[test] @@ -340,7 +348,8 @@ mod tests { check_true_add_false_with_false(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 2, 2); check_true_add_false_with_true(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 2, 2); check_true_add_true_with_false(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 3, 3); // <- Differs - check_true_add_true_with_true(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 3, 3); // <- Differs + check_true_add_true_with_true(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 3, 3); + // <- Differs } #[test] @@ -352,7 +361,8 @@ mod tests { check_true_add_false_with_false(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 2, 2); check_true_add_false_with_true(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 2, 2); check_true_add_true_with_false(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 3, 3); // <- Differs - check_true_add_true_with_true(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 3, 3); // <- Differs + check_true_add_true_with_true(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 3, 3); + // <- Differs } #[test] @@ -364,7 +374,8 @@ mod tests { check_true_add_false_with_false(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 2, 2); check_true_add_false_with_true(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 3, 3); // <- Differs check_true_add_true_with_false(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 2, 2); - check_true_add_true_with_true(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 3, 3); // <- Differs + check_true_add_true_with_true(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 3, 3); + // <- Differs } #[test] @@ -400,7 +411,8 @@ mod tests { check_true_add_false_with_false(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 2, 2); check_true_add_false_with_true(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 3, 3); // <- Differs check_true_add_true_with_false(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 2, 2); - check_true_add_true_with_true(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 3, 3); // <- Differs + check_true_add_true_with_true(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 3, 3); + // <- Differs } #[test] diff --git a/circuit/types/boolean/src/helpers/bits_are_zero.rs b/circuit/types/boolean/src/helpers/bits_are_zero.rs index 1ade4290e1..307ed0e43c 100644 --- a/circuit/types/boolean/src/helpers/bits_are_zero.rs +++ b/circuit/types/boolean/src/helpers/bits_are_zero.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/helpers/comparator.rs b/circuit/types/boolean/src/helpers/comparator.rs index 974a21912e..38efb3e6eb 100644 --- a/circuit/types/boolean/src/helpers/comparator.rs +++ b/circuit/types/boolean/src/helpers/comparator.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/helpers/from_bits.rs b/circuit/types/boolean/src/helpers/from_bits.rs index 3a77ad8783..0ce682c41f 100644 --- a/circuit/types/boolean/src/helpers/from_bits.rs +++ b/circuit/types/boolean/src/helpers/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/helpers/mod.rs b/circuit/types/boolean/src/helpers/mod.rs index 2ddc308466..74c2aa5bd7 100644 --- a/circuit/types/boolean/src/helpers/mod.rs +++ b/circuit/types/boolean/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/helpers/subtractor.rs b/circuit/types/boolean/src/helpers/subtractor.rs index 6981d2058c..349ccffb55 100644 --- a/circuit/types/boolean/src/helpers/subtractor.rs +++ b/circuit/types/boolean/src/helpers/subtractor.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -328,7 +329,8 @@ mod tests { check_true_sub_false_with_false(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 0, 0); check_true_sub_false_with_true(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 0, 0); check_true_sub_true_with_false(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 0, 0); - check_true_sub_true_with_true(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 1, 1); // <- Differs + check_true_sub_true_with_true(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 1, 1); + // <- Differs } #[test] @@ -340,7 +342,8 @@ mod tests { check_true_sub_false_with_false(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 2, 2); check_true_sub_false_with_true(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 2, 2); check_true_sub_true_with_false(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 3, 3); // <- Differs - check_true_sub_true_with_true(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 3, 3); // <- Differs + check_true_sub_true_with_true(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 3, 3); + // <- Differs } #[test] @@ -352,7 +355,8 @@ mod tests { check_true_sub_false_with_false(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 2, 2); check_true_sub_false_with_true(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 2, 2); check_true_sub_true_with_false(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 3, 3); // <- Differs - check_true_sub_true_with_true(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 3, 3); // <- Differs + check_true_sub_true_with_true(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 3, 3); + // <- Differs } #[test] @@ -364,7 +368,8 @@ mod tests { check_true_sub_false_with_false(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 2, 2); check_true_sub_false_with_true(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 3, 3); // <- Differs check_true_sub_true_with_false(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 2, 2); - check_true_sub_true_with_true(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 3, 3); // <- Differs + check_true_sub_true_with_true(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 3, 3); + // <- Differs } #[test] @@ -400,7 +405,8 @@ mod tests { check_true_sub_false_with_false(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 2, 2); check_true_sub_false_with_true(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 3, 3); // <- Differs check_true_sub_true_with_false(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 2, 2); - check_true_sub_true_with_true(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 3, 3); // <- Differs + check_true_sub_true_with_true(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 3, 3); + // <- Differs } #[test] diff --git a/circuit/types/boolean/src/helpers/to_bits.rs b/circuit/types/boolean/src/helpers/to_bits.rs index 35adfacaf3..e95a1c60b7 100644 --- a/circuit/types/boolean/src/helpers/to_bits.rs +++ b/circuit/types/boolean/src/helpers/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/lib.rs b/circuit/types/boolean/src/lib.rs index 77013c3e75..a34eea4d1f 100644 --- a/circuit/types/boolean/src/lib.rs +++ b/circuit/types/boolean/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -51,7 +52,7 @@ impl Boolean { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Boolean { type Primitive = bool; @@ -78,7 +79,7 @@ impl Inject for Boolean { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Boolean { type Primitive = bool; @@ -99,7 +100,7 @@ impl Eject for Boolean { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Parser for Boolean { /// Parses a string into a boolean circuit. #[inline] @@ -116,7 +117,7 @@ impl Parser for Boolean { } } -#[cfg(console)] +#[cfg(feature = "console")] impl FromStr for Boolean { type Err = Error; @@ -135,7 +136,7 @@ impl FromStr for Boolean { } } -#[cfg(console)] +#[cfg(feature = "console")] impl TypeName for Boolean { /// Returns the type name of the circuit as a string. #[inline] @@ -144,14 +145,14 @@ impl TypeName for Boolean { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Debug for Boolean { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(self, f) } } -#[cfg(console)] +#[cfg(feature = "console")] impl Display for Boolean { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}.{}", self.eject_value(), self.eject_mode()) diff --git a/circuit/types/boolean/src/nand.rs b/circuit/types/boolean/src/nand.rs index 3af34de703..f547814c5a 100644 --- a/circuit/types/boolean/src/nand.rs +++ b/circuit/types/boolean/src/nand.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/nor.rs b/circuit/types/boolean/src/nor.rs index f93b1d49bb..83dbed4611 100644 --- a/circuit/types/boolean/src/nor.rs +++ b/circuit/types/boolean/src/nor.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/not.rs b/circuit/types/boolean/src/not.rs index b4aec24f37..fa755483ca 100644 --- a/circuit/types/boolean/src/not.rs +++ b/circuit/types/boolean/src/not.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/or.rs b/circuit/types/boolean/src/or.rs index ec6d0a0eac..ed447edc32 100644 --- a/circuit/types/boolean/src/or.rs +++ b/circuit/types/boolean/src/or.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/ternary.rs b/circuit/types/boolean/src/ternary.rs index 237b0d00bd..dbe30d3e38 100644 --- a/circuit/types/boolean/src/ternary.rs +++ b/circuit/types/boolean/src/ternary.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/boolean/src/xor.rs b/circuit/types/boolean/src/xor.rs index 591b30b68a..c6840dd038 100644 --- a/circuit/types/boolean/src/xor.rs +++ b/circuit/types/boolean/src/xor.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/Cargo.toml b/circuit/types/field/Cargo.toml index acc1367886..3e6b83c941 100644 --- a/circuit/types/field/Cargo.toml +++ b/circuit/types/field/Cargo.toml @@ -1,24 +1,26 @@ [package] name = "snarkvm-circuit-types-field" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Field circuit for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.console] package = "snarkvm-console-types-field" path = "../../../console/types/field" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit-environment] path = "../../environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-boolean] path = "../boolean" -version = "=0.16.19" +version = "=1.1.0" [features] default = [ "enable_console" ] diff --git a/circuit/types/field/build.rs b/circuit/types/field/build.rs index ff14549b2c..1d0fe74e7c 100644 --- a/circuit/types/field/build.rs +++ b/circuit/types/field/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/add.rs b/circuit/types/field/src/add.rs index 2e5a5a7714..8206d01d25 100644 --- a/circuit/types/field/src/add.rs +++ b/circuit/types/field/src/add.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/compare.rs b/circuit/types/field/src/compare.rs index 40bbe811ec..870af6579d 100644 --- a/circuit/types/field/src/compare.rs +++ b/circuit/types/field/src/compare.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/div.rs b/circuit/types/field/src/div.rs index dc420d2c59..f59b691ecb 100644 --- a/circuit/types/field/src/div.rs +++ b/circuit/types/field/src/div.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -101,7 +102,7 @@ impl OutputMode, Output = Field>> for Field< #[cfg(test)] mod tests { use super::*; - use snarkvm_circuit_environment::{assert_count_fails, Circuit}; + use snarkvm_circuit_environment::{Circuit, assert_count_fails}; const ITERATIONS: u64 = 1000; diff --git a/circuit/types/field/src/div_unchecked.rs b/circuit/types/field/src/div_unchecked.rs index 4e819f5981..97b6e16837 100644 --- a/circuit/types/field/src/div_unchecked.rs +++ b/circuit/types/field/src/div_unchecked.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -81,7 +82,7 @@ impl OutputMode, Output = Field>> f #[cfg(test)] mod tests { use super::*; - use snarkvm_circuit_environment::{assert_count_fails, Circuit}; + use snarkvm_circuit_environment::{Circuit, assert_count_fails}; const ITERATIONS: u64 = 1000; diff --git a/circuit/types/field/src/double.rs b/circuit/types/field/src/double.rs index bf77a3c5ad..f64dde9c04 100644 --- a/circuit/types/field/src/double.rs +++ b/circuit/types/field/src/double.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/equal.rs b/circuit/types/field/src/equal.rs index 05df630115..92d1e2c145 100644 --- a/circuit/types/field/src/equal.rs +++ b/circuit/types/field/src/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/helpers/from_bits.rs b/circuit/types/field/src/helpers/from_bits.rs index 3376cfa199..9e5bdc5e4e 100644 --- a/circuit/types/field/src/helpers/from_bits.rs +++ b/circuit/types/field/src/helpers/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -128,7 +129,7 @@ mod tests { // Add excess zero bits. let candidate = [given_bits, vec![Boolean::new(mode, false); i as usize]].concat(); - Circuit::scope(&format!("Excess {mode} {i}"), || { + Circuit::scope(format!("Excess {mode} {i}"), || { let candidate = Field::::from_bits_le(&candidate); assert_eq!(expected, candidate.eject_value()); assert_eq!(expected_size_in_bits, candidate.bits_le.get().expect("Caching failed").len()); @@ -173,7 +174,7 @@ mod tests { // Add excess zero bits. let candidate = [vec![Boolean::new(mode, false); i as usize], given_bits].concat(); - Circuit::scope(&format!("Excess {mode} {i}"), || { + Circuit::scope(format!("Excess {mode} {i}"), || { let candidate = Field::::from_bits_be(&candidate); assert_eq!(expected, candidate.eject_value()); assert_eq!(expected_size_in_bits, candidate.bits_le.get().expect("Caching failed").len()); diff --git a/circuit/types/field/src/helpers/from_boolean.rs b/circuit/types/field/src/helpers/from_boolean.rs index 84975991d4..33a06b4f19 100644 --- a/circuit/types/field/src/helpers/from_boolean.rs +++ b/circuit/types/field/src/helpers/from_boolean.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/helpers/mod.rs b/circuit/types/field/src/helpers/mod.rs index c3873b2b82..ac05a44587 100644 --- a/circuit/types/field/src/helpers/mod.rs +++ b/circuit/types/field/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/helpers/one.rs b/circuit/types/field/src/helpers/one.rs index 10786f33e4..b79cd50243 100644 --- a/circuit/types/field/src/helpers/one.rs +++ b/circuit/types/field/src/helpers/one.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/helpers/to_bits.rs b/circuit/types/field/src/helpers/to_bits.rs index e58952e47d..0eeb16cede 100644 --- a/circuit/types/field/src/helpers/to_bits.rs +++ b/circuit/types/field/src/helpers/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -122,7 +123,7 @@ mod tests { let expected = Uniform::rand(&mut rng); let candidate = Field::::new(mode, expected); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate_bits = candidate.to_bits_le(); assert_eq!(expected_number_of_bits, candidate_bits.len()); for (expected_bit, candidate_bit) in expected.to_bits_le().iter().zip_eq(&candidate_bits) { @@ -150,7 +151,7 @@ mod tests { let expected = Uniform::rand(&mut rng); let candidate = Field::::new(mode, expected); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate_bits = candidate.to_bits_be(); assert_eq!(expected_number_of_bits, candidate_bits.len()); for (expected_bit, candidate_bit) in expected.to_bits_be().iter().zip_eq(&candidate_bits) { diff --git a/circuit/types/field/src/helpers/to_lower_bits.rs b/circuit/types/field/src/helpers/to_lower_bits.rs index c94f43c01b..00522b326f 100644 --- a/circuit/types/field/src/helpers/to_lower_bits.rs +++ b/circuit/types/field/src/helpers/to_lower_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -102,7 +103,7 @@ mod tests { // Construct the unsigned integer as a field element. let candidate = Field::::new(mode, console::Field::from_bits_le(&expected).unwrap()); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_lower_bits_le(I::BITS as usize); assert_eq!(I::BITS, candidate.len() as u64); for (i, (expected_bit, candidate_bit)) in expected.iter().zip_eq(candidate.iter()).enumerate() { diff --git a/circuit/types/field/src/helpers/to_upper_bits.rs b/circuit/types/field/src/helpers/to_upper_bits.rs index bd7112a229..46af42f528 100644 --- a/circuit/types/field/src/helpers/to_upper_bits.rs +++ b/circuit/types/field/src/helpers/to_upper_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -129,7 +130,7 @@ mod tests { Field::::new(mode, console::Field::from_bits_be(&bits_be).unwrap()) }; - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let num_bits_with_capacity = I::BITS + 1; let candidate = candidate.to_upper_bits_be(num_bits_with_capacity as usize); assert_eq!(num_bits_with_capacity, candidate.len() as u64); diff --git a/circuit/types/field/src/helpers/zero.rs b/circuit/types/field/src/helpers/zero.rs index 73a56ba1b9..5608c30402 100644 --- a/circuit/types/field/src/helpers/zero.rs +++ b/circuit/types/field/src/helpers/zero.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/inverse.rs b/circuit/types/field/src/inverse.rs index a5ced6ce18..bbb432b515 100644 --- a/circuit/types/field/src/inverse.rs +++ b/circuit/types/field/src/inverse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/lib.rs b/circuit/types/field/src/lib.rs index 1c29b437ee..82711ef158 100644 --- a/circuit/types/field/src/lib.rs +++ b/circuit/types/field/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -59,7 +60,7 @@ impl Default for Field { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Field { type Primitive = console::Field; @@ -69,7 +70,7 @@ impl Inject for Field { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Field { type Primitive = console::Field; @@ -84,7 +85,7 @@ impl Eject for Field { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Parser for Field { /// Parses a string into a field circuit. #[inline] @@ -101,7 +102,7 @@ impl Parser for Field { } } -#[cfg(console)] +#[cfg(feature = "console")] impl FromStr for Field { type Err = Error; @@ -120,7 +121,7 @@ impl FromStr for Field { } } -#[cfg(console)] +#[cfg(feature = "console")] impl TypeName for Field { /// Returns the type name of the circuit as a string. #[inline] @@ -129,14 +130,14 @@ impl TypeName for Field { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Debug for Field { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(self, f) } } -#[cfg(console)] +#[cfg(feature = "console")] impl Display for Field { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}.{}", self.eject_value(), self.eject_mode()) diff --git a/circuit/types/field/src/mul.rs b/circuit/types/field/src/mul.rs index 8a0e9baba8..bcfcd52c56 100644 --- a/circuit/types/field/src/mul.rs +++ b/circuit/types/field/src/mul.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/neg.rs b/circuit/types/field/src/neg.rs index c7b8387b0c..20d189e595 100644 --- a/circuit/types/field/src/neg.rs +++ b/circuit/types/field/src/neg.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/pow.rs b/circuit/types/field/src/pow.rs index 7cbd84f551..015105759a 100644 --- a/circuit/types/field/src/pow.rs +++ b/circuit/types/field/src/pow.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/square.rs b/circuit/types/field/src/square.rs index 0e5193e809..2e92c3e3ad 100644 --- a/circuit/types/field/src/square.rs +++ b/circuit/types/field/src/square.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/square_root.rs b/circuit/types/field/src/square_root.rs index 8430d0ae29..67743b3519 100644 --- a/circuit/types/field/src/square_root.rs +++ b/circuit/types/field/src/square_root.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -63,6 +64,65 @@ impl Field { } } +impl Field { + /// Returns both square roots of `self` and a `Boolean` flag, which is set iff `self` is not a square. + /// + /// If `self` is a non-zero square, + /// - the first field result is the positive root (i.e. closer to 0) + /// - the second field result is the negative root (i.e. closer to the prime) + /// - the flag is 0 + /// + /// If `self` is 0, + /// - both field results are 0 + /// - the flag is 0 + /// + /// If `self` is not a square, + /// - both field results are 0 + /// - the flag is 1 + /// + /// Note that the constraints do **not** impose an ordering on the two roots returned by this function; + /// this is what the `nondeterministic` part of this function name refers to. + pub fn square_roots_flagged_nondeterministic(&self) -> (Self, Self, Boolean) { + // Obtain (p-1)/2, as a constant field element. + let modulus_minus_one_div_two = match E::BaseField::from_bigint(E::BaseField::modulus_minus_one_div_two()) { + Some(modulus_minus_one_div_two) => Field::constant(console::Field::new(modulus_minus_one_div_two)), + None => E::halt("Failed to initialize (modulus - 1) / 2"), + }; + + // Use Euler's criterion: self is a non-zero square iff self^((p-1)/2) is 1. + let euler = self.pow(modulus_minus_one_div_two); + let is_nonzero_square = euler.is_one(); + + // Calculate the witness for the first square result. + // Note that the **console** function `square_root` returns the square root closer to 0. + let root_witness = match self.eject_value().square_root() { + Ok(root) => root, + Err(_) => console::Field::zero(), + }; + + // Initialize the square element, which is either `self` or 0, depending on whether `self` is a square. + // This is done to ensure that the below constraint is satisfied even if `self` is not a square. + let square = Self::ternary(&is_nonzero_square, self, &Field::zero()); + + // Initialize a new variable for the first root. + let mode = if self.eject_mode() == Mode::Constant { Mode::Constant } else { Mode::Private }; + let first_root = Field::new(mode, root_witness); + + // Enforce that the first root squared is equal to the square. + // Note that if `self` is not a square, then `first_root` and `square` are both zero and the constraint is satisfied. + E::enforce(|| (&first_root, &first_root, &square)); + + // Initialize the second root as the negation of the first root. + let second_root = first_root.clone().neg(); + + // The error flag is set iff self is a non-square, i.e. it is neither zero nor a non-zero square. + let is_nonzero = !self.is_zero(); + let error_flag = is_nonzero.bitand(is_nonzero_square.not()); + + (first_root, second_root, error_flag) + } +} + impl Metrics>> for Field { type Case = Mode; @@ -96,7 +156,7 @@ mod tests { for _ in 0..ITERATIONS { // Sample a random element. let given: console::Field<::Network> = Uniform::rand(rng); - // Compute it's square root, or skip this iteration if it does not natively exist. + // Compute its square root, or skip this iteration if it does not natively exist. if let Ok(expected) = given.square_root() { let input = Field::::new(mode, given); @@ -123,7 +183,7 @@ mod tests { for _ in 0..ITERATIONS { // Sample a random element. let given: console::Field<::Network> = Uniform::rand(rng); - // Compute it's square root, or skip this iteration if it does not natively exist. + // Compute its square root, or skip this iteration if it does not natively exist. if let Ok(expected) = given.even_square_root() { let input = Field::::new(mode, given); @@ -137,6 +197,39 @@ mod tests { } } + fn check_square_roots_flagged_nondeterministic( + name: &str, + mode: Mode, + rng: &mut TestRng, + num_constants: u64, + num_public: u64, + num_private: u64, + num_constraints: u64, + ) { + for _ in 0..ITERATIONS { + // Sample a random element. + let given: console::Field<::Network> = Uniform::rand(rng); + // Compute square roots and error flag in console-land. + let (expected_error_flag, expected_positive_root, expected_negative_root) = match given.square_root() { + Ok(root) => (false, root, -root), + Err(_) => (true, console::Field::zero(), console::Field::zero()), + }; + // Compute square roots and error flag in circuit-land. + let input = Field::::new(mode, given); + Circuit::scope(name, || { + let (candidate_first_root, candidate_second_root, candidate_error_flag) = + input.square_roots_flagged_nondeterministic(); + // Although the order of the roots is unspecified in the circuit, + // the witness values are in a fixed order (first positive, then negative). + assert_eq!(expected_error_flag, candidate_error_flag.eject_value()); + assert_eq!(expected_positive_root, candidate_first_root.eject_value()); + assert_eq!(expected_negative_root, candidate_second_root.eject_value()); + assert_scope!(num_constants, num_public, num_private, num_constraints); + }); + Circuit::reset(); + } + } + #[test] fn test_square_root() { let mut rng = TestRng::default(); @@ -154,4 +247,13 @@ mod tests { check_even_square_root("Public", &mut rng, Mode::Public, 0, 0, 506, 509); check_even_square_root("Private", &mut rng, Mode::Private, 0, 0, 506, 509); } + + #[test] + fn test_square_roots_flagged_nondeterministic() { + let mut rng = TestRng::default(); + + check_square_roots_flagged_nondeterministic("Constant", Mode::Constant, &mut rng, 257, 0, 0, 0); + check_square_roots_flagged_nondeterministic("Public", Mode::Public, &mut rng, 254, 0, 344, 344); + check_square_roots_flagged_nondeterministic("Private", Mode::Private, &mut rng, 254, 0, 344, 344); + } } diff --git a/circuit/types/field/src/sub.rs b/circuit/types/field/src/sub.rs index a5293a90d3..c4d579901c 100644 --- a/circuit/types/field/src/sub.rs +++ b/circuit/types/field/src/sub.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/field/src/ternary.rs b/circuit/types/field/src/ternary.rs index cc3673cdf9..94247c9d63 100644 --- a/circuit/types/field/src/ternary.rs +++ b/circuit/types/field/src/ternary.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/group/Cargo.toml b/circuit/types/group/Cargo.toml index c633da70d9..22fbc0bf06 100644 --- a/circuit/types/group/Cargo.toml +++ b/circuit/types/group/Cargo.toml @@ -1,32 +1,34 @@ [package] name = "snarkvm-circuit-types-group" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Group circuit for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.console] package = "snarkvm-console-types-group" path = "../../../console/types/group" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit-environment] path = "../../environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-boolean] path = "../boolean" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-field] path = "../field" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-scalar] path = "../scalar" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.snarkvm-utilities] path = "../../../utilities" diff --git a/circuit/types/group/build.rs b/circuit/types/group/build.rs index ff14549b2c..1d0fe74e7c 100644 --- a/circuit/types/group/build.rs +++ b/circuit/types/group/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/group/src/add.rs b/circuit/types/group/src/add.rs index 7e2cc0b0db..57c73ff090 100644 --- a/circuit/types/group/src/add.rs +++ b/circuit/types/group/src/add.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/group/src/double.rs b/circuit/types/group/src/double.rs index b565c607ca..e3c210255b 100644 --- a/circuit/types/group/src/double.rs +++ b/circuit/types/group/src/double.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -105,7 +106,7 @@ mod tests { // Constant variable let affine = Group::::new(Mode::Constant, point); - Circuit::scope(&format!("Constant {i}"), || { + Circuit::scope(format!("Constant {i}"), || { let candidate = affine.double(); assert_eq!(expected, candidate.eject_value()); assert_scope!(3, 0, 0, 0); @@ -115,7 +116,7 @@ mod tests { // Public variable let affine = Group::::new(Mode::Public, point); - Circuit::scope(&format!("Public {i}"), || { + Circuit::scope(format!("Public {i}"), || { let candidate = affine.double(); assert_eq!(expected, candidate.eject_value()); assert_scope!(1, 0, 5, 5); @@ -125,7 +126,7 @@ mod tests { // Private variable let affine = Group::::new(Mode::Private, point); - Circuit::scope(&format!("Private {i}"), || { + Circuit::scope(format!("Private {i}"), || { let candidate = affine.double(); assert_eq!(expected, candidate.eject_value()); assert_scope!(1, 0, 5, 5); diff --git a/circuit/types/group/src/equal.rs b/circuit/types/group/src/equal.rs index a0fb4b81c0..3c685a2f6f 100644 --- a/circuit/types/group/src/equal.rs +++ b/circuit/types/group/src/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -61,14 +62,14 @@ mod tests { let a = Group::::new(Mode::Constant, a); let b = Group::::new(Mode::Constant, b); - Circuit::scope(&format!("Constant Equals {i}"), || { + Circuit::scope(format!("Constant Equals {i}"), || { let equals = a.is_equal(&b); assert!(!equals.eject_value()); assert_scope!(2, 0, 0, 0); }); Circuit::reset(); - Circuit::scope(&format!("Constant Not Equals {i}"), || { + Circuit::scope(format!("Constant Not Equals {i}"), || { let equals = a.is_not_equal(&b); assert!(equals.eject_value()); assert_scope!(2, 0, 0, 0); @@ -85,14 +86,14 @@ mod tests { let a = Group::::new(Mode::Constant, a); let b = Group::::new(Mode::Public, b); - Circuit::scope(&format!("Constant and Public Equals {i}"), || { + Circuit::scope(format!("Constant and Public Equals {i}"), || { let equals = a.is_equal(&b); assert!(!equals.eject_value()); assert_scope!(0, 0, 5, 5); }); Circuit::reset(); - Circuit::scope(&format!("Constant and Public Not Equals {i}"), || { + Circuit::scope(format!("Constant and Public Not Equals {i}"), || { let equals = a.is_not_equal(&b); assert!(equals.eject_value()); assert_scope!(0, 0, 5, 5); @@ -109,14 +110,14 @@ mod tests { let a = Group::::new(Mode::Public, a); let b = Group::::new(Mode::Constant, b); - Circuit::scope(&format!("Public and Constant Equals {i}"), || { + Circuit::scope(format!("Public and Constant Equals {i}"), || { let equals = a.is_equal(&b); assert!(!equals.eject_value()); assert_scope!(0, 0, 5, 5); }); Circuit::reset(); - Circuit::scope(&format!("Public and Constant Not Equals {i}"), || { + Circuit::scope(format!("Public and Constant Not Equals {i}"), || { let equals = a.is_not_equal(&b); assert!(equals.eject_value()); assert_scope!(0, 0, 5, 5); @@ -133,14 +134,14 @@ mod tests { let a = Group::::new(Mode::Public, a); let b = Group::::new(Mode::Public, b); - Circuit::scope(&format!("Public Equals {i}"), || { + Circuit::scope(format!("Public Equals {i}"), || { let equals = a.is_equal(&b); assert!(!equals.eject_value()); assert_scope!(0, 0, 5, 5); }); Circuit::reset(); - Circuit::scope(&format!("Public Not Equals {i}"), || { + Circuit::scope(format!("Public Not Equals {i}"), || { let equals = a.is_not_equal(&b); assert!(equals.eject_value()); assert_scope!(0, 0, 5, 5); @@ -157,14 +158,14 @@ mod tests { let a = Group::::new(Mode::Private, a); let b = Group::::new(Mode::Private, b); - Circuit::scope(&format!("Private Equals {i}"), || { + Circuit::scope(format!("Private Equals {i}"), || { let equals = a.is_equal(&b); assert!(!equals.eject_value()); assert_scope!(0, 0, 5, 5); }); Circuit::reset(); - Circuit::scope(&format!("Private Not Equals {i}"), || { + Circuit::scope(format!("Private Not Equals {i}"), || { let equals = a.is_not_equal(&b); assert!(equals.eject_value()); assert_scope!(0, 0, 5, 5); diff --git a/circuit/types/group/src/helpers/from_bits.rs b/circuit/types/group/src/helpers/from_bits.rs index 7cd06656e2..f6991ffbd6 100644 --- a/circuit/types/group/src/helpers/from_bits.rs +++ b/circuit/types/group/src/helpers/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -49,7 +50,7 @@ mod tests { let expected = Uniform::rand(&mut rng); let candidate = Group::::new(mode, expected).to_bits_le(); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = Group::::from_bits_le(&candidate); assert_eq!(expected, candidate.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); @@ -66,7 +67,7 @@ mod tests { let expected = Uniform::rand(&mut rng); let candidate = Group::::new(mode, expected).to_bits_be(); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = Group::::from_bits_be(&candidate); assert_eq!(expected, candidate.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); diff --git a/circuit/types/group/src/helpers/from_x_coordinate.rs b/circuit/types/group/src/helpers/from_x_coordinate.rs index acf87bf2f9..f819d5f5ea 100644 --- a/circuit/types/group/src/helpers/from_x_coordinate.rs +++ b/circuit/types/group/src/helpers/from_x_coordinate.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -26,6 +27,58 @@ impl Group { Self::from_xy_coordinates(x, y) } + + /// Initializes an affine group element from a given x-coordinate field element. + /// Additionally, returns an error flag. + /// If the error flag is set, there is **no** group element with the given x-coordinate. + /// If the error flag is set, the returned point is `(0, 0)`. + pub fn from_x_coordinate_flagged(x: Field) -> (Self, Boolean) { + // Obtain the A and D coefficients of the elliptic curve. + let a = Field::constant(console::Field::new(E::EDWARDS_A)); + let d = Field::constant(console::Field::new(E::EDWARDS_D)); + + // Compute x^2. + let xx = &x * &x; + + // Compute a * x^2 - 1. + let a_xx_minus_1 = a * &xx - Field::one(); + + // Compute d * x^2 - 1. + let d_xx_minus_1 = d * &xx - Field::one(); + + // Compute y^2 = (a * x^2 - 1) / (d * x^2 - 1), i.e. solve the curve equation for y^2. + let yy: Field = witness!(|a_xx_minus_1, d_xx_minus_1| { a_xx_minus_1 / d_xx_minus_1 }); + E::enforce(|| (&yy, &d_xx_minus_1, &a_xx_minus_1)); + + // Compute both square roots of y^2, with a flag indicating whether y^2 is a square or not. + // Note that there is **no** ordering on the square roots in the circuit computation. + // Note that if the x-coordinate line does not intersect the elliptic curve, this returns (0, 0, true). + let (y1, y2, yy_is_not_square) = yy.square_roots_flagged_nondeterministic(); + + // Construct the two points. + // Note that if `yy_is_not_square` is `false`, the points are guaranteed to be on the curve. + // Note that the two points are **not** necessarily in the subgroup. + let point1 = Self { x: x.clone(), y: y1.clone() }; + let point2 = Self { x: x.clone(), y: y2.clone() }; + + // Determine if either of the two points is in the subgroup. + // Note that at most **one** of the points can be in the subgroup. + let point1_is_in_group = point1.is_in_group(); + let point2_is_in_group = point2.is_in_group(); + + // Select y1 if (x, y1) is in the subgroup. + // Otherwise, select y2 if (x, y2) is in the subgroup. + // Otherwise, use the zero field element. + let y2_or_zero = Field::ternary(&point2_is_in_group, &y2, &Field::zero()); + let y1_or_y2_or_zero = Field::ternary(&point1_is_in_group, &y1, &y2_or_zero); + let y = Field::ternary(&yy_is_not_square, &Field::zero(), &y1_or_y2_or_zero); + + // The error flag is set iff x does not intersect the elliptic curve or neither intersection point is in the subgroup. + let neither_in_subgroup = point1_is_in_group.not().bitand(point2_is_in_group.not()); + let error_flag = yy_is_not_square.bitor(&neither_in_subgroup); + + (Self { x, y }, error_flag) + } } #[cfg(test)] @@ -60,6 +113,35 @@ mod tests { } } + fn check_from_x_coordinate_flagged( + mode: Mode, + num_constants: u64, + num_public: u64, + num_private: u64, + num_constraints: u64, + ) { + let mut rng = TestRng::default(); + + for i in 0..ITERATIONS { + // Sample a random x coordinate. + let x: console::Field<::Network> = Uniform::rand(&mut rng); + // Compute error flag and point in console-land. + let (expected_error_flag, expected_point) = match console::Group::from_x_coordinate(x) { + Ok(point) => (false, point), + Err(_) => (true, console::Group::from_xy_coordinates_unchecked(x, console::Field::zero())), + }; + // Compute error flag and point in circuit-land. + let input = Field::::new(mode, x); + Circuit::scope(format!("{mode} {i}"), || { + let (candidate_point, candidate_error_flag) = Group::from_x_coordinate_flagged(input); + assert_eq!(expected_error_flag, candidate_error_flag.eject_value()); + assert_eq!(expected_point, candidate_point.eject_value()); + assert_scope!(num_constants, num_public, num_private, num_constraints); + }); + Circuit::reset(); + } + } + #[test] fn test_from_x_coordinate_constant() { check_from_x_coordinate(Mode::Constant, 9, 0, 0, 0); @@ -74,4 +156,19 @@ mod tests { fn test_from_x_coordinate_private() { check_from_x_coordinate(Mode::Private, 4, 0, 13, 13); } + + #[test] + fn test_from_x_coordinate_flagged_constant() { + check_from_x_coordinate_flagged(Mode::Constant, 3764, 0, 0, 0); + } + + #[test] + fn test_from_x_coordinate_flagged_public() { + check_from_x_coordinate_flagged(Mode::Public, 1756, 0, 5861, 5861); + } + + #[test] + fn test_from_x_coordinate_flagged_private() { + check_from_x_coordinate_flagged(Mode::Private, 1756, 0, 5861, 5861); + } } diff --git a/circuit/types/group/src/helpers/from_xy_coordinates.rs b/circuit/types/group/src/helpers/from_xy_coordinates.rs index ecce200d4d..bd521a368d 100644 --- a/circuit/types/group/src/helpers/from_xy_coordinates.rs +++ b/circuit/types/group/src/helpers/from_xy_coordinates.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/group/src/helpers/mod.rs b/circuit/types/group/src/helpers/mod.rs index 11ad03ce22..d60543ad79 100644 --- a/circuit/types/group/src/helpers/mod.rs +++ b/circuit/types/group/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/group/src/helpers/mul_by_cofactor.rs b/circuit/types/group/src/helpers/mul_by_cofactor.rs index be32b66eff..1d385279f8 100644 --- a/circuit/types/group/src/helpers/mul_by_cofactor.rs +++ b/circuit/types/group/src/helpers/mul_by_cofactor.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -46,7 +47,7 @@ mod tests { // Initialize the input. let affine = Group::::new(mode, input); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = affine.mul_by_cofactor(); assert_eq!(expected, candidate.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); @@ -86,7 +87,7 @@ mod tests { // Initialize the input. let affine = Group::::new(Mode::Private, input); - Circuit::scope(&format!("Constant {i}"), || { + Circuit::scope(format!("Constant {i}"), || { let candidate = affine * Scalar::constant(console::Scalar::new(::ScalarField::from(4u128))); assert_eq!(expected, candidate.eject_value()); diff --git a/circuit/types/group/src/helpers/to_bits.rs b/circuit/types/group/src/helpers/to_bits.rs index 50cf0db7d5..76284375d4 100644 --- a/circuit/types/group/src/helpers/to_bits.rs +++ b/circuit/types/group/src/helpers/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -59,7 +60,7 @@ mod tests { let expected = Uniform::rand(&mut rng); let candidate = Group::::new(mode, expected); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_bits_le(); assert_eq!(expected_number_of_bits, candidate.len()); for (expected_bit, candidate_bit) in @@ -82,7 +83,7 @@ mod tests { let expected = Uniform::rand(&mut rng); let candidate = Group::::new(mode, expected); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_bits_be(); assert_eq!(expected_number_of_bits, candidate.len()); for (expected_bit, candidate_bit) in diff --git a/circuit/types/group/src/helpers/to_field.rs b/circuit/types/group/src/helpers/to_field.rs index e3c0bbddeb..0b14035ce9 100644 --- a/circuit/types/group/src/helpers/to_field.rs +++ b/circuit/types/group/src/helpers/to_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -40,7 +41,7 @@ mod tests { let expected = Uniform::rand(rng); let candidate = Group::::new(mode, expected); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_field(); assert_eq!(expected.to_field().unwrap(), candidate.eject_value()); assert_scope!(0, 0, 0, 0); diff --git a/circuit/types/group/src/helpers/to_x_coordinate.rs b/circuit/types/group/src/helpers/to_x_coordinate.rs index 623295b7b1..47b7293041 100644 --- a/circuit/types/group/src/helpers/to_x_coordinate.rs +++ b/circuit/types/group/src/helpers/to_x_coordinate.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -34,7 +35,7 @@ mod tests { let expected = Uniform::rand(&mut TestRng::default()); let candidate = Group::::new(mode, expected); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_x_coordinate(); assert_eq!(expected.to_x_coordinate(), candidate.eject_value()); assert_scope!(0, 0, 0, 0); diff --git a/circuit/types/group/src/helpers/to_y_coordinate.rs b/circuit/types/group/src/helpers/to_y_coordinate.rs index 8e5f291d57..e5e04f450f 100644 --- a/circuit/types/group/src/helpers/to_y_coordinate.rs +++ b/circuit/types/group/src/helpers/to_y_coordinate.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -36,7 +37,7 @@ mod tests { let expected = Uniform::rand(&mut rng); let candidate = Group::::new(mode, expected); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_y_coordinate(); assert_eq!(expected.to_y_coordinate(), candidate.eject_value()); assert_scope!(0, 0, 0, 0); diff --git a/circuit/types/group/src/helpers/zero.rs b/circuit/types/group/src/helpers/zero.rs index 63c7d029b1..31790492d1 100644 --- a/circuit/types/group/src/helpers/zero.rs +++ b/circuit/types/group/src/helpers/zero.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/group/src/lib.rs b/circuit/types/group/src/lib.rs index 36d1f7f821..65d7ef2a36 100644 --- a/circuit/types/group/src/lib.rs +++ b/circuit/types/group/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -52,7 +53,7 @@ impl Group { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Group { type Primitive = console::Group; @@ -129,9 +130,25 @@ impl Group { // i.e. that it is 4 (= cofactor) times the postulated point on the curve. double_point.enforce_double(self); } + + /// Returns a `Boolean` indicating if `self` is in the largest prime-order subgroup, + /// assuming that `self` is on the curve. + pub fn is_in_group(&self) -> Boolean { + // Initialize the order of the subgroup as a bits. + let order = E::ScalarField::modulus(); + let order_bits_be = order.to_bits_be(); + let mut order_bits_be_constants = Vec::with_capacity(order_bits_be.len()); + for bit in order_bits_be.iter() { + order_bits_be_constants.push(Boolean::constant(*bit)); + } + // Multiply `self` by the order of the subgroup. + let self_times_order = order_bits_be_constants.mul(self); + // Check if the result is zero. + self_times_order.is_zero() + } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Group { type Primitive = console::Group; @@ -146,7 +163,7 @@ impl Eject for Group { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Parser for Group { /// Parses a string into a group circuit. #[inline] @@ -163,7 +180,7 @@ impl Parser for Group { } } -#[cfg(console)] +#[cfg(feature = "console")] impl FromStr for Group { type Err = Error; @@ -182,7 +199,7 @@ impl FromStr for Group { } } -#[cfg(console)] +#[cfg(feature = "console")] impl TypeName for Group { /// Returns the type name of the circuit as a string. #[inline] @@ -191,14 +208,14 @@ impl TypeName for Group { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Debug for Group { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(self, f) } } -#[cfg(console)] +#[cfg(feature = "console")] impl Display for Group { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}.{}", self.eject_value(), self.eject_mode()) @@ -242,7 +259,7 @@ mod tests { // Sample a random element. let point = Uniform::rand(&mut rng); - Circuit::scope(&format!("Constant {i}"), || { + Circuit::scope(format!("Constant {i}"), || { let affine = Group::::new(Mode::Constant, point); assert_eq!(point, affine.eject_value()); assert_scope!(10, 0, 0, 0); @@ -254,7 +271,7 @@ mod tests { // Sample a random element. let point = Uniform::rand(&mut rng); - Circuit::scope(&format!("Public {i}"), || { + Circuit::scope(format!("Public {i}"), || { let affine = Group::::new(Mode::Public, point); assert_eq!(point, affine.eject_value()); assert_scope!(4, 2, 12, 13); @@ -266,7 +283,7 @@ mod tests { // Sample a random element. let point = Uniform::rand(&mut rng); - Circuit::scope(&format!("Private {i}"), || { + Circuit::scope(format!("Private {i}"), || { let affine = Group::::new(Mode::Private, point); assert_eq!(point, affine.eject_value()); assert_scope!(4, 0, 14, 13); @@ -382,4 +399,82 @@ mod tests { } } } + + #[test] + fn test_is_in_group() { + type PrimitiveField = console::Field<::Network>; + + // First test the points that have low order. + + // The two halves of (0,1) in group arithmetic are (0,1) and (0,-1). + let minus1_string = "8444461749428370424248824938781546531375899335154063827935233455917409239040field"; + // The two halves of (0,-1) in group arithmetic are (q1x,0) and (q2x,0), + // where q1x = sqrt(-1) mod F_q and q2x = -sqrt(-1) mod F_q. + let q1x_string = "880904806456922042258150504921383618666682042621506879489field"; + let q2x_string = "8444461749428370423367920132324624489117748830232680209268551413295902359552field"; + + // (0,1) is in the large prime subgroup. + let y1: Field = Field::new(Mode::Public, PrimitiveField::from_str("1field").unwrap()); + let group0 = Group::::from_xy_coordinates_unchecked(Field::zero(), y1); + Circuit::scope("group0", || { + let group0_is_in_group = group0.is_in_group(); + assert!(group0_is_in_group.eject_value()); + assert_scope!(750, 0, 2253, 2253); + }); + Circuit::reset(); + + // The other three low order points are on the curve but not in the large prime subgroup. + // Make sure is_in_group returns false for these. + let minus1: Field = Field::new(Mode::Public, PrimitiveField::from_str(minus1_string).unwrap()); + let half0 = Group::::from_xy_coordinates_unchecked(Field::zero(), minus1); + Circuit::scope("half0", || { + let half0_is_not_in_group = !half0.is_in_group(); + assert!(half0_is_not_in_group.eject_value()); + assert_scope!(750, 0, 2253, 2253); + }); + Circuit::reset(); + + let q1x: Field = Field::new(Mode::Public, PrimitiveField::from_str(q1x_string).unwrap()); + let quarter1 = Group::::from_xy_coordinates_unchecked(q1x, Field::zero()); + Circuit::scope("quarter1", || { + let quarter1_is_not_in_group = !quarter1.is_in_group(); + assert!(quarter1_is_not_in_group.eject_value()); + assert_scope!(750, 0, 2253, 2253); + }); + Circuit::reset(); + + let q2x: Field = Field::new(Mode::Public, PrimitiveField::from_str(q2x_string).unwrap()); + let quarter2 = Group::::from_xy_coordinates_unchecked(q2x, Field::zero()); + Circuit::scope("quarter2", || { + let quarter2_is_not_in_group = !quarter2.is_in_group(); + assert!(quarter2_is_not_in_group.eject_value()); + assert_scope!(750, 0, 2253, 2253); + }); + Circuit::reset(); + + fn check_is_in_group(mode: Mode, num_constants: u64, num_public: u64, num_private: u64, num_constraints: u64) { + let mut rng = TestRng::default(); + + for i in 0..ITERATIONS { + // Sample a random element. + let point: console::Group<::Network> = Uniform::rand(&mut rng); + + // Inject the x-coordinate. + let x_coordinate = Field::new(mode, point.to_x_coordinate()); + + // Initialize the group element. + let element = Group::::from_x_coordinate(x_coordinate); + + Circuit::scope(format!("{mode} {i}"), || { + let is_in_group = element.is_in_group(); + assert!(is_in_group.eject_value()); + assert_scope!(num_constants, num_public, num_private, num_constraints); + }); + Circuit::reset(); + } + } + check_is_in_group(Mode::Constant, 1752, 0, 0, 0); + check_is_in_group(Mode::Public, 750, 0, 2755, 2755); + check_is_in_group(Mode::Private, 750, 0, 2755, 2755); + } } diff --git a/circuit/types/group/src/mul.rs b/circuit/types/group/src/mul.rs index 0c592ebe7c..8a11579dc5 100644 --- a/circuit/types/group/src/mul.rs +++ b/circuit/types/group/src/mul.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/group/src/neg.rs b/circuit/types/group/src/neg.rs index c8a8b45d5b..22732ab847 100644 --- a/circuit/types/group/src/neg.rs +++ b/circuit/types/group/src/neg.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/group/src/sub.rs b/circuit/types/group/src/sub.rs index 219da59d10..0bbc2ea1c8 100644 --- a/circuit/types/group/src/sub.rs +++ b/circuit/types/group/src/sub.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/group/src/ternary.rs b/circuit/types/group/src/ternary.rs index 201a320fc1..5647a0ff0d 100644 --- a/circuit/types/group/src/ternary.rs +++ b/circuit/types/group/src/ternary.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/Cargo.toml b/circuit/types/integers/Cargo.toml index 5903640f3f..6babf5f697 100644 --- a/circuit/types/integers/Cargo.toml +++ b/circuit/types/integers/Cargo.toml @@ -1,32 +1,34 @@ [package] name = "snarkvm-circuit-types-integers" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Integer circuit for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.console] package = "snarkvm-console-types-integers" path = "../../../console/types/integers" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit-environment] path = "../../environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-boolean] path = "../boolean" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-field] path = "../field" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-scalar] path = "../scalar" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.snarkvm-utilities] path = "../../../utilities" diff --git a/circuit/types/integers/build.rs b/circuit/types/integers/build.rs index ff14549b2c..1d0fe74e7c 100644 --- a/circuit/types/integers/build.rs +++ b/circuit/types/integers/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/abs_checked.rs b/circuit/types/integers/src/abs_checked.rs index 35332e2ee1..9bae13124d 100644 --- a/circuit/types/integers/src/abs_checked.rs +++ b/circuit/types/integers/src/abs_checked.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/abs_wrapped.rs b/circuit/types/integers/src/abs_wrapped.rs index 698d029fe7..61f11968d1 100644 --- a/circuit/types/integers/src/abs_wrapped.rs +++ b/circuit/types/integers/src/abs_wrapped.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/add_checked.rs b/circuit/types/integers/src/add_checked.rs index 2616f57d5f..ebd395c7ff 100644 --- a/circuit/types/integers/src/add_checked.rs +++ b/circuit/types/integers/src/add_checked.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/add_wrapped.rs b/circuit/types/integers/src/add_wrapped.rs index aa30bd482e..5d920fe416 100644 --- a/circuit/types/integers/src/add_wrapped.rs +++ b/circuit/types/integers/src/add_wrapped.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/and.rs b/circuit/types/integers/src/and.rs index 846876d6b5..50e328ed24 100644 --- a/circuit/types/integers/src/and.rs +++ b/circuit/types/integers/src/and.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/compare.rs b/circuit/types/integers/src/compare.rs index 7e0acdf44e..21ed0a4ed9 100644 --- a/circuit/types/integers/src/compare.rs +++ b/circuit/types/integers/src/compare.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/div_checked.rs b/circuit/types/integers/src/div_checked.rs index 67446c02c9..484e016f8d 100644 --- a/circuit/types/integers/src/div_checked.rs +++ b/circuit/types/integers/src/div_checked.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/div_wrapped.rs b/circuit/types/integers/src/div_wrapped.rs index 9098069608..a507f97331 100644 --- a/circuit/types/integers/src/div_wrapped.rs +++ b/circuit/types/integers/src/div_wrapped.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/equal.rs b/circuit/types/integers/src/equal.rs index 955ddaf7bd..baecd8cbb4 100644 --- a/circuit/types/integers/src/equal.rs +++ b/circuit/types/integers/src/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/helpers/from_bits.rs b/circuit/types/integers/src/helpers/from_bits.rs index 8919575dd8..5d6953f75a 100644 --- a/circuit/types/integers/src/helpers/from_bits.rs +++ b/circuit/types/integers/src/helpers/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -66,7 +67,7 @@ mod tests { let given_bits = Integer::::new(mode, expected).to_bits_le(); let expected_size_in_bits = given_bits.len(); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = Integer::::from_bits_le(&given_bits); assert_eq!(expected, candidate.eject_value()); assert_eq!(expected_size_in_bits, candidate.bits_le.len()); @@ -76,7 +77,7 @@ mod tests { // Add excess zero bits. let candidate = [given_bits, vec![Boolean::new(mode, false); i as usize]].concat(); - Circuit::scope(&format!("Excess {mode} {i}"), || { + Circuit::scope(format!("Excess {mode} {i}"), || { let candidate = Integer::::from_bits_le(&candidate); assert_eq!(expected, candidate.eject_value()); assert_eq!(expected_size_in_bits, candidate.bits_le.len()); @@ -106,7 +107,7 @@ mod tests { let given_bits = Integer::::new(mode, expected).to_bits_be(); let expected_size_in_bits = given_bits.len(); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = Integer::::from_bits_be(&given_bits); assert_eq!(expected, candidate.eject_value()); assert_eq!(expected_size_in_bits, candidate.bits_le.len()); @@ -116,7 +117,7 @@ mod tests { // Add excess zero bits. let candidate = [vec![Boolean::new(mode, false); i as usize], given_bits].concat(); - Circuit::scope(&format!("Excess {mode} {i}"), || { + Circuit::scope(format!("Excess {mode} {i}"), || { let candidate = Integer::::from_bits_be(&candidate); assert_eq!(expected, candidate.eject_value()); assert_eq!(expected_size_in_bits, candidate.bits_le.len()); diff --git a/circuit/types/integers/src/helpers/from_field.rs b/circuit/types/integers/src/helpers/from_field.rs index 3b5e80c3dd..b2fb99bab3 100644 --- a/circuit/types/integers/src/helpers/from_field.rs +++ b/circuit/types/integers/src/helpers/from_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/helpers/from_field_lossy.rs b/circuit/types/integers/src/helpers/from_field_lossy.rs index 990d2cb477..1ab412fc70 100644 --- a/circuit/types/integers/src/helpers/from_field_lossy.rs +++ b/circuit/types/integers/src/helpers/from_field_lossy.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/helpers/mod.rs b/circuit/types/integers/src/helpers/mod.rs index 75018c91d9..da1aeec8dc 100644 --- a/circuit/types/integers/src/helpers/mod.rs +++ b/circuit/types/integers/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/helpers/msb.rs b/circuit/types/integers/src/helpers/msb.rs index 6ac6f3157b..419017df0b 100644 --- a/circuit/types/integers/src/helpers/msb.rs +++ b/circuit/types/integers/src/helpers/msb.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/helpers/one.rs b/circuit/types/integers/src/helpers/one.rs index 747f2f7427..dd49ad7994 100644 --- a/circuit/types/integers/src/helpers/one.rs +++ b/circuit/types/integers/src/helpers/one.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/helpers/to_bits.rs b/circuit/types/integers/src/helpers/to_bits.rs index 8df5b8e35f..924cca44f9 100644 --- a/circuit/types/integers/src/helpers/to_bits.rs +++ b/circuit/types/integers/src/helpers/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -65,7 +66,7 @@ mod tests { let expected = Uniform::rand(&mut rng); let candidate = Integer::::new(mode, expected); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_bits_le(); assert_eq!(I::BITS, candidate.len() as u64); @@ -94,7 +95,7 @@ mod tests { let expected = Uniform::rand(&mut rng); let candidate = Integer::::new(mode, expected); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_bits_be(); assert_eq!(I::BITS, candidate.len() as u64); diff --git a/circuit/types/integers/src/helpers/to_field.rs b/circuit/types/integers/src/helpers/to_field.rs index 1eb5d17ca5..2a21d3a7ec 100644 --- a/circuit/types/integers/src/helpers/to_field.rs +++ b/circuit/types/integers/src/helpers/to_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/helpers/to_fields.rs b/circuit/types/integers/src/helpers/to_fields.rs index 49a60aa132..d10fbb81ff 100644 --- a/circuit/types/integers/src/helpers/to_fields.rs +++ b/circuit/types/integers/src/helpers/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/helpers/to_scalar.rs b/circuit/types/integers/src/helpers/to_scalar.rs index a3088e13da..e29f19497c 100644 --- a/circuit/types/integers/src/helpers/to_scalar.rs +++ b/circuit/types/integers/src/helpers/to_scalar.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/helpers/zero.rs b/circuit/types/integers/src/helpers/zero.rs index e44fcba22c..d75963d66a 100644 --- a/circuit/types/integers/src/helpers/zero.rs +++ b/circuit/types/integers/src/helpers/zero.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/lib.rs b/circuit/types/integers/src/lib.rs index c2d7a318b7..82f6e91b23 100644 --- a/circuit/types/integers/src/lib.rs +++ b/circuit/types/integers/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -98,7 +99,7 @@ impl Integer { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Integer { type Primitive = console::Integer; @@ -114,7 +115,7 @@ impl Inject for Integer { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Integer { type Primitive = console::Integer; @@ -132,7 +133,7 @@ impl Eject for Integer { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Parser for Integer { /// Parses a string into an integer circuit. #[inline] @@ -149,7 +150,7 @@ impl Parser for Integer { } } -#[cfg(console)] +#[cfg(feature = "console")] impl FromStr for Integer { type Err = Error; @@ -168,7 +169,7 @@ impl FromStr for Integer { } } -#[cfg(console)] +#[cfg(feature = "console")] impl TypeName for Integer { /// Returns the type name of the circuit as a string. #[inline] @@ -177,14 +178,14 @@ impl TypeName for Integer { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Debug for Integer { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(self, f) } } -#[cfg(console)] +#[cfg(feature = "console")] impl Display for Integer { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}.{}", self.eject_value(), self.eject_mode()) diff --git a/circuit/types/integers/src/modulo.rs b/circuit/types/integers/src/modulo.rs index a249848957..a9584a9ba2 100644 --- a/circuit/types/integers/src/modulo.rs +++ b/circuit/types/integers/src/modulo.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/mul_checked.rs b/circuit/types/integers/src/mul_checked.rs index 1cf4588fff..fccbb0b84b 100644 --- a/circuit/types/integers/src/mul_checked.rs +++ b/circuit/types/integers/src/mul_checked.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/mul_wrapped.rs b/circuit/types/integers/src/mul_wrapped.rs index 1feae66671..e96a9f0e53 100644 --- a/circuit/types/integers/src/mul_wrapped.rs +++ b/circuit/types/integers/src/mul_wrapped.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/neg.rs b/circuit/types/integers/src/neg.rs index 33723809c8..3718b6ef96 100644 --- a/circuit/types/integers/src/neg.rs +++ b/circuit/types/integers/src/neg.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/not.rs b/circuit/types/integers/src/not.rs index e324707e57..5619c3a6c6 100644 --- a/circuit/types/integers/src/not.rs +++ b/circuit/types/integers/src/not.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/or.rs b/circuit/types/integers/src/or.rs index b3f23a64cb..d74a10e3b9 100644 --- a/circuit/types/integers/src/or.rs +++ b/circuit/types/integers/src/or.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/pow_checked.rs b/circuit/types/integers/src/pow_checked.rs index 170211d7ef..427899e188 100644 --- a/circuit/types/integers/src/pow_checked.rs +++ b/circuit/types/integers/src/pow_checked.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/pow_wrapped.rs b/circuit/types/integers/src/pow_wrapped.rs index bb66551ded..337763474c 100644 --- a/circuit/types/integers/src/pow_wrapped.rs +++ b/circuit/types/integers/src/pow_wrapped.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/rem_checked.rs b/circuit/types/integers/src/rem_checked.rs index c4958580b3..477f5c0771 100644 --- a/circuit/types/integers/src/rem_checked.rs +++ b/circuit/types/integers/src/rem_checked.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/rem_wrapped.rs b/circuit/types/integers/src/rem_wrapped.rs index edc2f26f9c..5b2b53514f 100644 --- a/circuit/types/integers/src/rem_wrapped.rs +++ b/circuit/types/integers/src/rem_wrapped.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/shl_checked.rs b/circuit/types/integers/src/shl_checked.rs index 18b5f3545e..87109fcde7 100644 --- a/circuit/types/integers/src/shl_checked.rs +++ b/circuit/types/integers/src/shl_checked.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/shl_wrapped.rs b/circuit/types/integers/src/shl_wrapped.rs index 4414d05965..82d53b2411 100644 --- a/circuit/types/integers/src/shl_wrapped.rs +++ b/circuit/types/integers/src/shl_wrapped.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/shr_checked.rs b/circuit/types/integers/src/shr_checked.rs index f7a065eb14..41f24fb66b 100644 --- a/circuit/types/integers/src/shr_checked.rs +++ b/circuit/types/integers/src/shr_checked.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/shr_wrapped.rs b/circuit/types/integers/src/shr_wrapped.rs index 09cf3cceda..2c8a541301 100644 --- a/circuit/types/integers/src/shr_wrapped.rs +++ b/circuit/types/integers/src/shr_wrapped.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/sub_checked.rs b/circuit/types/integers/src/sub_checked.rs index bbaec84520..588987ddea 100644 --- a/circuit/types/integers/src/sub_checked.rs +++ b/circuit/types/integers/src/sub_checked.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/sub_wrapped.rs b/circuit/types/integers/src/sub_wrapped.rs index afe68b6398..46d62209ee 100644 --- a/circuit/types/integers/src/sub_wrapped.rs +++ b/circuit/types/integers/src/sub_wrapped.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/ternary.rs b/circuit/types/integers/src/ternary.rs index 924b5c9097..27de2d6b61 100644 --- a/circuit/types/integers/src/ternary.rs +++ b/circuit/types/integers/src/ternary.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/integers/src/xor.rs b/circuit/types/integers/src/xor.rs index bc6fc66376..458f246360 100644 --- a/circuit/types/integers/src/xor.rs +++ b/circuit/types/integers/src/xor.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/scalar/Cargo.toml b/circuit/types/scalar/Cargo.toml index 99e813f11b..30d670132e 100644 --- a/circuit/types/scalar/Cargo.toml +++ b/circuit/types/scalar/Cargo.toml @@ -1,28 +1,30 @@ [package] name = "snarkvm-circuit-types-scalar" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Scalar circuit for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.console] package = "snarkvm-console-types-scalar" path = "../../../console/types/scalar" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit-environment] path = "../../environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-boolean] path = "../boolean" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-field] path = "../field" -version = "=0.16.19" +version = "=1.1.0" [features] default = [ "enable_console" ] diff --git a/circuit/types/scalar/build.rs b/circuit/types/scalar/build.rs index ff14549b2c..1d0fe74e7c 100644 --- a/circuit/types/scalar/build.rs +++ b/circuit/types/scalar/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/scalar/src/add.rs b/circuit/types/scalar/src/add.rs index bfb016425d..ca57e8a9aa 100644 --- a/circuit/types/scalar/src/add.rs +++ b/circuit/types/scalar/src/add.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/scalar/src/compare.rs b/circuit/types/scalar/src/compare.rs index d0799bfc41..77f82f564a 100644 --- a/circuit/types/scalar/src/compare.rs +++ b/circuit/types/scalar/src/compare.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -83,7 +84,7 @@ mod tests { let candidate_b = Scalar::::new(mode_b, expected_b); // Perform the less than comparison. - Circuit::scope(&format!("{mode_a} {mode_b} {i}"), || { + Circuit::scope(format!("{mode_a} {mode_b} {i}"), || { let candidate = candidate_a.is_less_than(&candidate_b); assert_eq!(expected_a < expected_b, candidate.eject_value()); assert_scope!(<=num_constants, <=num_public, <=num_private, <=num_constraints); diff --git a/circuit/types/scalar/src/equal.rs b/circuit/types/scalar/src/equal.rs index 0b312901c3..c59692d5ed 100644 --- a/circuit/types/scalar/src/equal.rs +++ b/circuit/types/scalar/src/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/scalar/src/helpers/from_bits.rs b/circuit/types/scalar/src/helpers/from_bits.rs index 2422607938..4458224043 100644 --- a/circuit/types/scalar/src/helpers/from_bits.rs +++ b/circuit/types/scalar/src/helpers/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -107,7 +108,7 @@ mod tests { let given_bits = Scalar::::new(mode, expected).to_bits_le(); let expected_size_in_bits = given_bits.len(); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = Scalar::::from_bits_le(&given_bits); assert_eq!(expected, candidate.eject_value()); assert_eq!(expected_size_in_bits, candidate.bits_le.get().unwrap().len()); @@ -118,7 +119,7 @@ mod tests { // Add excess zero bits. let candidate = [given_bits, vec![Boolean::new(mode, false); i as usize]].concat(); - Circuit::scope(&format!("Excess {mode} {i}"), || { + Circuit::scope(format!("Excess {mode} {i}"), || { let candidate = Scalar::::from_bits_le(&candidate); assert_eq!(expected, candidate.eject_value()); assert_eq!(expected_size_in_bits, candidate.bits_le.get().unwrap().len()); @@ -148,7 +149,7 @@ mod tests { let given_bits = Scalar::::new(mode, expected).to_bits_be(); let expected_size_in_bits = given_bits.len(); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = Scalar::::from_bits_be(&given_bits); assert_eq!(expected, candidate.eject_value()); assert_eq!(expected_size_in_bits, candidate.bits_le.get().unwrap().len()); @@ -159,7 +160,7 @@ mod tests { // Add excess zero bits. let candidate = [vec![Boolean::new(mode, false); i as usize], given_bits].concat(); - Circuit::scope(&format!("Excess {mode} {i}"), || { + Circuit::scope(format!("Excess {mode} {i}"), || { let candidate = Scalar::::from_bits_be(&candidate); assert_eq!(expected, candidate.eject_value()); assert_eq!(expected_size_in_bits, candidate.bits_le.get().unwrap().len()); diff --git a/circuit/types/scalar/src/helpers/from_field.rs b/circuit/types/scalar/src/helpers/from_field.rs index 1ee4bd5864..da4be32cee 100644 --- a/circuit/types/scalar/src/helpers/from_field.rs +++ b/circuit/types/scalar/src/helpers/from_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -22,8 +23,8 @@ impl FromField for Scalar { /// This method guarantees the following: /// 1. If the field element is larger than the scalar field modulus, then the operation will fail. /// 2. If the field element is smaller than the scalar field modulus, then the operation will succeed. - /// - This is particularly useful for the case where a user called, `Scalar::from_field(scalar.to_field())`, - /// and the scalar bit representation is between `size_in_data_bits < bits.len() < size_in_bits`. + /// - This is particularly useful for the case where a user called, `Scalar::from_field(scalar.to_field())`, + /// and the scalar bit representation is between `size_in_data_bits < bits.len() < size_in_bits`. fn from_field(field: Self::Field) -> Self { // Note: We are reconstituting the integer from the base field. // This is safe as the number of bits in the integer is less than the base field modulus, diff --git a/circuit/types/scalar/src/helpers/from_field_lossy.rs b/circuit/types/scalar/src/helpers/from_field_lossy.rs index f30298623b..e28d18650e 100644 --- a/circuit/types/scalar/src/helpers/from_field_lossy.rs +++ b/circuit/types/scalar/src/helpers/from_field_lossy.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/scalar/src/helpers/mod.rs b/circuit/types/scalar/src/helpers/mod.rs index a6cd87b320..e8ebeba2f8 100644 --- a/circuit/types/scalar/src/helpers/mod.rs +++ b/circuit/types/scalar/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/scalar/src/helpers/one.rs b/circuit/types/scalar/src/helpers/one.rs index 1f3e0c4d13..7476f6fc84 100644 --- a/circuit/types/scalar/src/helpers/one.rs +++ b/circuit/types/scalar/src/helpers/one.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/scalar/src/helpers/to_bits.rs b/circuit/types/scalar/src/helpers/to_bits.rs index 3f80ad2e60..171c28e036 100644 --- a/circuit/types/scalar/src/helpers/to_bits.rs +++ b/circuit/types/scalar/src/helpers/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/scalar/src/helpers/to_field.rs b/circuit/types/scalar/src/helpers/to_field.rs index 7d4a096544..1fad8a15b9 100644 --- a/circuit/types/scalar/src/helpers/to_field.rs +++ b/circuit/types/scalar/src/helpers/to_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/scalar/src/helpers/to_fields.rs b/circuit/types/scalar/src/helpers/to_fields.rs index 64ec4adb78..816033a5e8 100644 --- a/circuit/types/scalar/src/helpers/to_fields.rs +++ b/circuit/types/scalar/src/helpers/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/scalar/src/helpers/zero.rs b/circuit/types/scalar/src/helpers/zero.rs index 287a523e4e..dfb1cf9efe 100644 --- a/circuit/types/scalar/src/helpers/zero.rs +++ b/circuit/types/scalar/src/helpers/zero.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/scalar/src/lib.rs b/circuit/types/scalar/src/lib.rs index 8076064f25..1dde301382 100644 --- a/circuit/types/scalar/src/lib.rs +++ b/circuit/types/scalar/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -43,7 +44,7 @@ pub struct Scalar { impl ScalarTrait for Scalar {} -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for Scalar { type Primitive = console::Scalar; @@ -62,7 +63,7 @@ impl Inject for Scalar { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for Scalar { type Primitive = console::Scalar; @@ -80,7 +81,7 @@ impl Eject for Scalar { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Parser for Scalar { /// Parses a string into a scalar circuit. #[inline] @@ -97,7 +98,7 @@ impl Parser for Scalar { } } -#[cfg(console)] +#[cfg(feature = "console")] impl FromStr for Scalar { type Err = Error; @@ -116,7 +117,7 @@ impl FromStr for Scalar { } } -#[cfg(console)] +#[cfg(feature = "console")] impl TypeName for Scalar { /// Returns the type name of the circuit as a string. #[inline] @@ -125,14 +126,14 @@ impl TypeName for Scalar { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Debug for Scalar { fn fmt(&self, f: &mut Formatter) -> fmt::Result { Display::fmt(self, f) } } -#[cfg(console)] +#[cfg(feature = "console")] impl Display for Scalar { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{}.{}", self.eject_value(), self.eject_mode()) diff --git a/circuit/types/scalar/src/ternary.rs b/circuit/types/scalar/src/ternary.rs index f1f400bda6..927dafeb08 100644 --- a/circuit/types/scalar/src/ternary.rs +++ b/circuit/types/scalar/src/ternary.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/src/lib.rs b/circuit/types/src/lib.rs index d5af6980e3..4c10089dab 100644 --- a/circuit/types/src/lib.rs +++ b/circuit/types/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -32,7 +33,7 @@ pub mod modules { pub use snarkvm_circuit_types_group::Group; pub use snarkvm_circuit_types_integers as integers; - pub use snarkvm_circuit_types_integers::{I128, I16, I32, I64, I8, U128, U16, U32, U64, U8}; + pub use snarkvm_circuit_types_integers::{I8, I16, I32, I64, I128, U8, U16, U32, U64, U128}; pub use snarkvm_circuit_types_scalar as scalar; pub use snarkvm_circuit_types_scalar::Scalar; diff --git a/circuit/types/string/Cargo.toml b/circuit/types/string/Cargo.toml index 716f2593c2..ca2b0ee97f 100644 --- a/circuit/types/string/Cargo.toml +++ b/circuit/types/string/Cargo.toml @@ -1,32 +1,34 @@ [package] name = "snarkvm-circuit-types-string" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "String circuit for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.console] package = "snarkvm-console-types-string" path = "../../../console/types/string" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-circuit-environment] path = "../../environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-boolean] path = "../boolean" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-field] path = "../field" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-circuit-types-integers] path = "../integers" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.snarkvm-utilities] path = "../../../utilities" diff --git a/circuit/types/string/build.rs b/circuit/types/string/build.rs index ff14549b2c..1d0fe74e7c 100644 --- a/circuit/types/string/build.rs +++ b/circuit/types/string/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/string/src/equal.rs b/circuit/types/string/src/equal.rs index 74f6fac743..6f0fdc19d6 100644 --- a/circuit/types/string/src/equal.rs +++ b/circuit/types/string/src/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/string/src/helpers/from_bits.rs b/circuit/types/string/src/helpers/from_bits.rs index 8f4822cb85..000c98f8e5 100644 --- a/circuit/types/string/src/helpers/from_bits.rs +++ b/circuit/types/string/src/helpers/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -85,7 +86,7 @@ mod tests { let candidate = StringType::::new(mode, console::StringType::new(&expected)).to_bits_le(); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = StringType::::from_bits_le(&candidate); assert_eq!(expected, *candidate.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); @@ -105,7 +106,7 @@ mod tests { let candidate = StringType::::new(mode, console::StringType::new(&expected)).to_bits_be(); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = StringType::::from_bits_be(&candidate); assert_eq!(expected, *candidate.eject_value()); assert_scope!(num_constants, num_public, num_private, num_constraints); diff --git a/circuit/types/string/src/helpers/mod.rs b/circuit/types/string/src/helpers/mod.rs index 10a4036948..b5a7ea8481 100644 --- a/circuit/types/string/src/helpers/mod.rs +++ b/circuit/types/string/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/circuit/types/string/src/helpers/to_bits.rs b/circuit/types/string/src/helpers/to_bits.rs index 7aef96d4d1..4cc4ec32cc 100644 --- a/circuit/types/string/src/helpers/to_bits.rs +++ b/circuit/types/string/src/helpers/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -60,7 +61,7 @@ mod tests { let candidate = StringType::::new(mode, console::StringType::new(&expected)); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_bits_le(); assert_eq!(expected_num_bytes * 8, candidate.len()); @@ -85,7 +86,7 @@ mod tests { let candidate = StringType::::new(mode, console::StringType::new(&expected)); - Circuit::scope(&format!("{mode} {i}"), || { + Circuit::scope(format!("{mode} {i}"), || { let candidate = candidate.to_bits_be(); assert_eq!(expected_num_bytes * 8, candidate.len()); diff --git a/circuit/types/string/src/helpers/to_fields.rs b/circuit/types/string/src/helpers/to_fields.rs index 99c92633a6..ca1017a5f4 100644 --- a/circuit/types/string/src/helpers/to_fields.rs +++ b/circuit/types/string/src/helpers/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -31,7 +32,7 @@ impl ToFields for StringType { mod tests { use super::*; use snarkvm_circuit_environment::Circuit; - use snarkvm_utilities::{bytes_from_bits_le, FromBytes}; + use snarkvm_utilities::{FromBytes, bytes_from_bits_le}; fn native_string_to_fields(string: &str) -> Vec::Network>> { string diff --git a/circuit/types/string/src/lib.rs b/circuit/types/string/src/lib.rs index 7e602fb756..16e6545d88 100644 --- a/circuit/types/string/src/lib.rs +++ b/circuit/types/string/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,7 +38,7 @@ pub struct StringType { impl StringTrait for StringType {} -#[cfg(console)] +#[cfg(feature = "console")] impl Inject for StringType { type Primitive = console::StringType; @@ -67,7 +68,7 @@ impl Inject for StringType { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Eject for StringType { type Primitive = console::StringType; @@ -93,7 +94,7 @@ impl Eject for StringType { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Parser for StringType { /// Parses a string into a string circuit. #[inline] @@ -110,7 +111,7 @@ impl Parser for StringType { } } -#[cfg(console)] +#[cfg(feature = "console")] impl FromStr for StringType { type Err = Error; @@ -129,7 +130,7 @@ impl FromStr for StringType { } } -#[cfg(console)] +#[cfg(feature = "console")] impl TypeName for StringType { /// Returns the type name of the circuit as a string. #[inline] @@ -138,14 +139,14 @@ impl TypeName for StringType { } } -#[cfg(console)] +#[cfg(feature = "console")] impl Debug for StringType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(self, f) } } -#[cfg(console)] +#[cfg(feature = "console")] impl Display for StringType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}.{}", self.eject_value(), self.eject_mode()) diff --git a/console/Cargo.toml b/console/Cargo.toml index f3f029f135..b7d7094acb 100644 --- a/console/Cargo.toml +++ b/console/Cargo.toml @@ -1,39 +1,41 @@ [package] name = "snarkvm-console" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Console environment for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.snarkvm-console-account] path = "./account" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-console-algorithms] path = "./algorithms" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-console-collections] path = "./collections" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-console-network] path = "./network" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-console-program] path = "./program" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-console-types] path = "./types" -version = "=0.16.19" +version = "=1.1.0" optional = true [features] @@ -48,6 +50,7 @@ default = [ wasm = [ "snarkvm-console-network/wasm" ] test = [ "snarkvm-console-account/test", + "snarkvm-console-network/test", "snarkvm-console-program/test" ] account = [ "network", "snarkvm-console-account" ] @@ -57,3 +60,4 @@ network = [ "collections", "snarkvm-console-network" ] program = [ "network", "snarkvm-console-program" ] serial = [ "snarkvm-console-collections/serial" ] types = [ "snarkvm-console-types" ] +test_targets = [ "snarkvm-console-network/test_targets" ] diff --git a/console/account/Cargo.toml b/console/account/Cargo.toml index 568551104a..30128e8993 100644 --- a/console/account/Cargo.toml +++ b/console/account/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "snarkvm-console-account" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Account operations for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" @@ -13,11 +15,11 @@ harness = false [dependencies.snarkvm-console-network] path = "../network" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types] path = "../types" -version = "=0.16.19" +version = "=1.1.0" default-features = false features = [ "address", "boolean", "field", "group", "scalar" ] diff --git a/console/account/benches/account.rs b/console/account/benches/account.rs index 5f3df699c1..b22db044f9 100644 --- a/console/account/benches/account.rs +++ b/console/account/benches/account.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,11 +17,11 @@ extern crate criterion; use snarkvm_console_account::{Address, PrivateKey, ViewKey}; -use snarkvm_console_network::{environment::prelude::*, Testnet3}; +use snarkvm_console_network::{MainnetV0, environment::prelude::*}; use criterion::Criterion; -type CurrentNetwork = Testnet3; +type CurrentNetwork = MainnetV0; fn account_private_key(c: &mut Criterion) { let rng = &mut TestRng::default(); diff --git a/console/account/src/address/mod.rs b/console/account/src/address/mod.rs index 807a00f000..2c644034be 100644 --- a/console/account/src/address/mod.rs +++ b/console/account/src/address/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/address/try_from.rs b/console/account/src/address/try_from.rs index 299e09b72e..4872bfc0d3 100644 --- a/console/account/src/address/try_from.rs +++ b/console/account/src/address/try_from.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -77,9 +78,9 @@ impl TryFrom<&ViewKey> for Address { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1_000; diff --git a/console/account/src/compute_key/bitwise.rs b/console/account/src/compute_key/bitwise.rs index 6a0f014586..d2f7fd2ff7 100644 --- a/console/account/src/compute_key/bitwise.rs +++ b/console/account/src/compute_key/bitwise.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/compute_key/bytes.rs b/console/account/src/compute_key/bytes.rs index 1e064c8951..10fbbb982d 100644 --- a/console/account/src/compute_key/bytes.rs +++ b/console/account/src/compute_key/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl ToBytes for ComputeKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/compute_key/from_bits.rs b/console/account/src/compute_key/from_bits.rs index fa1f73e576..5f95f23de0 100644 --- a/console/account/src/compute_key/from_bits.rs +++ b/console/account/src/compute_key/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -53,9 +54,9 @@ impl FromBits for ComputeKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/account/src/compute_key/mod.rs b/console/account/src/compute_key/mod.rs index 5b7e827f7d..b3f980ea08 100644 --- a/console/account/src/compute_key/mod.rs +++ b/console/account/src/compute_key/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/compute_key/serialize.rs b/console/account/src/compute_key/serialize.rs index 78f809bdb0..85f61d90d5 100644 --- a/console/account/src/compute_key/serialize.rs +++ b/console/account/src/compute_key/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -35,9 +36,9 @@ impl<'de, N: Network> Deserialize<'de> for ComputeKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/compute_key/size_in_bits.rs b/console/account/src/compute_key/size_in_bits.rs index 0d7993bb0e..7f518cb569 100644 --- a/console/account/src/compute_key/size_in_bits.rs +++ b/console/account/src/compute_key/size_in_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/compute_key/size_in_bytes.rs b/console/account/src/compute_key/size_in_bytes.rs index 68bd892bef..4ab6e4bf18 100644 --- a/console/account/src/compute_key/size_in_bytes.rs +++ b/console/account/src/compute_key/size_in_bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/compute_key/to_address.rs b/console/account/src/compute_key/to_address.rs index 3dc6eae1af..efcf7d11b0 100644 --- a/console/account/src/compute_key/to_address.rs +++ b/console/account/src/compute_key/to_address.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -27,9 +28,9 @@ impl ComputeKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/compute_key/to_bits.rs b/console/account/src/compute_key/to_bits.rs index 2a742b1c9e..c1c405c211 100644 --- a/console/account/src/compute_key/to_bits.rs +++ b/console/account/src/compute_key/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -35,9 +36,9 @@ impl ToBits for ComputeKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1_000; diff --git a/console/account/src/compute_key/to_fields.rs b/console/account/src/compute_key/to_fields.rs index f111be955b..54b42e173d 100644 --- a/console/account/src/compute_key/to_fields.rs +++ b/console/account/src/compute_key/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/compute_key/try_from.rs b/console/account/src/compute_key/try_from.rs index e652ca8323..b77c1c9c7d 100644 --- a/console/account/src/compute_key/try_from.rs +++ b/console/account/src/compute_key/try_from.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -63,9 +64,9 @@ impl TryFrom<&(Group, Group)> for ComputeKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/graph_key/bytes.rs b/console/account/src/graph_key/bytes.rs index a6b3efb71c..ab8ba23d8e 100644 --- a/console/account/src/graph_key/bytes.rs +++ b/console/account/src/graph_key/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -34,9 +35,9 @@ impl ToBytes for GraphKey { mod tests { use super::*; use crate::PrivateKey; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/graph_key/mod.rs b/console/account/src/graph_key/mod.rs index bff18db0dd..40bd23d987 100644 --- a/console/account/src/graph_key/mod.rs +++ b/console/account/src/graph_key/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/graph_key/serialize.rs b/console/account/src/graph_key/serialize.rs index 74739f8dbb..b622b8e689 100644 --- a/console/account/src/graph_key/serialize.rs +++ b/console/account/src/graph_key/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -32,9 +33,9 @@ impl<'de, N: Network> Deserialize<'de> for GraphKey { mod tests { use super::*; use crate::PrivateKey; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/graph_key/string.rs b/console/account/src/graph_key/string.rs index 5378a28d13..4739ff42b9 100644 --- a/console/account/src/graph_key/string.rs +++ b/console/account/src/graph_key/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -49,9 +50,9 @@ impl fmt::Display for GraphKey { mod tests { use super::*; use crate::PrivateKey; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 10_000; diff --git a/console/account/src/graph_key/try_from.rs b/console/account/src/graph_key/try_from.rs index 61a124f5c9..2ea32b21fd 100644 --- a/console/account/src/graph_key/try_from.rs +++ b/console/account/src/graph_key/try_from.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -60,9 +61,9 @@ impl TryFrom<&Field> for GraphKey { mod tests { use super::*; use crate::PrivateKey; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/lib.rs b/console/account/src/lib.rs index 77e5874bbf..66ffd4008f 100644 --- a/console/account/src/lib.rs +++ b/console/account/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -17,7 +18,7 @@ #![warn(clippy::cast_possible_truncation)] #![cfg_attr(test, allow(clippy::assertions_on_result_states))] -pub use snarkvm_console_types::{environment::prelude::*, Address, Field, Group, Scalar}; +pub use snarkvm_console_types::{Address, Field, Group, Scalar, environment::prelude::*}; mod address; @@ -49,9 +50,9 @@ pub use view_key::*; #[cfg(test)] mod tests { use crate::{Address, ComputeKey, PrivateKey, Signature, ViewKey}; - use snarkvm_console_network::{prelude::*, Testnet3}; + use snarkvm_console_network::{MainnetV0, prelude::*}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ALEO_PRIVATE_KEY: &str = "APrivateKey1zkp8cC4jgHEBnbtu3xxs1Ndja2EMizcvTRDq5Nikdkukg1p"; const ALEO_VIEW_KEY: &str = "AViewKey1n1n3ZbnVEtXVe3La2xWkUvY3EY7XaCG6RZJJ3tbvrrrD"; diff --git a/console/account/src/private_key/bytes.rs b/console/account/src/private_key/bytes.rs index 291720c277..3d28ff62de 100644 --- a/console/account/src/private_key/bytes.rs +++ b/console/account/src/private_key/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -31,9 +32,9 @@ impl ToBytes for PrivateKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/private_key/mod.rs b/console/account/src/private_key/mod.rs index 612054fe60..34cb60bf82 100644 --- a/console/account/src/private_key/mod.rs +++ b/console/account/src/private_key/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/private_key/serialize.rs b/console/account/src/private_key/serialize.rs index 3aeda9f436..ff26213c66 100644 --- a/console/account/src/private_key/serialize.rs +++ b/console/account/src/private_key/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -41,9 +42,9 @@ impl<'de, N: Network> Deserialize<'de> for PrivateKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/private_key/sign.rs b/console/account/src/private_key/sign.rs index c330e50b23..374e88aa6b 100644 --- a/console/account/src/private_key/sign.rs +++ b/console/account/src/private_key/sign.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -36,9 +37,9 @@ impl PrivateKey { mod tests { use super::*; use crate::Address; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 100; diff --git a/console/account/src/private_key/string.rs b/console/account/src/private_key/string.rs index 766178a079..e735f94001 100644 --- a/console/account/src/private_key/string.rs +++ b/console/account/src/private_key/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -48,9 +49,9 @@ impl fmt::Display for PrivateKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/private_key/try_from.rs b/console/account/src/private_key/try_from.rs index 16dfce2d13..046694c7fb 100644 --- a/console/account/src/private_key/try_from.rs +++ b/console/account/src/private_key/try_from.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/signature/bitwise.rs b/console/account/src/signature/bitwise.rs index 95add60aaf..196a146164 100644 --- a/console/account/src/signature/bitwise.rs +++ b/console/account/src/signature/bitwise.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -40,13 +41,3 @@ impl Ternary for Signature { } } } - -impl Ternary for Box> { - type Boolean = Boolean; - type Output = Self; - - /// Returns `first` if `condition` is `true`, otherwise returns `second`. - fn ternary(condition: &Self::Boolean, first: &Self, second: &Self) -> Self::Output { - Box::new(Signature::ternary(condition, first, second)) - } -} diff --git a/console/account/src/signature/bytes.rs b/console/account/src/signature/bytes.rs index bb7da60881..e1712bc091 100644 --- a/console/account/src/signature/bytes.rs +++ b/console/account/src/signature/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -38,9 +39,9 @@ impl ToBytes for Signature { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 100; diff --git a/console/account/src/signature/from_bits.rs b/console/account/src/signature/from_bits.rs index 5892bbfc7c..9101025d88 100644 --- a/console/account/src/signature/from_bits.rs +++ b/console/account/src/signature/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -71,9 +72,9 @@ impl FromBits for Signature { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/account/src/signature/mod.rs b/console/account/src/signature/mod.rs index 1225af3b38..b688fa93f2 100644 --- a/console/account/src/signature/mod.rs +++ b/console/account/src/signature/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -114,9 +115,9 @@ impl Signature { #[cfg(test)] mod test_helpers { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Samples a random signature. pub(super) fn sample_signature(num_fields: u64, rng: &mut TestRng) -> Signature { diff --git a/console/account/src/signature/parse.rs b/console/account/src/signature/parse.rs index 78b69e7771..e3f3cbc3c6 100644 --- a/console/account/src/signature/parse.rs +++ b/console/account/src/signature/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -74,9 +75,9 @@ impl Display for Signature { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1_000; @@ -112,7 +113,7 @@ mod tests { // Check the string representation. let candidate = format!("{expected}"); assert_eq!(expected, Signature::from_str(&candidate)?); - assert_eq!(SIGNATURE_PREFIX, candidate.to_string().split('1').next().unwrap()); + assert_eq!(SIGNATURE_PREFIX, candidate.split('1').next().unwrap()); } Ok(()) } diff --git a/console/account/src/signature/serialize.rs b/console/account/src/signature/serialize.rs index 623e83b104..04b29661b2 100644 --- a/console/account/src/signature/serialize.rs +++ b/console/account/src/signature/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/signature/sign.rs b/console/account/src/signature/sign.rs index 037425b371..97459a68f8 100644 --- a/console/account/src/signature/sign.rs +++ b/console/account/src/signature/sign.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/signature/size_in_bits.rs b/console/account/src/signature/size_in_bits.rs index 2da01be67f..66a0e53e9f 100644 --- a/console/account/src/signature/size_in_bits.rs +++ b/console/account/src/signature/size_in_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/signature/size_in_bytes.rs b/console/account/src/signature/size_in_bytes.rs index 7f1e9dced8..8e7c66e045 100644 --- a/console/account/src/signature/size_in_bytes.rs +++ b/console/account/src/signature/size_in_bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/signature/to_bits.rs b/console/account/src/signature/to_bits.rs index 0c4512c516..a49fa7655e 100644 --- a/console/account/src/signature/to_bits.rs +++ b/console/account/src/signature/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -39,9 +40,9 @@ impl ToBits for Signature { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1_000; diff --git a/console/account/src/signature/to_fields.rs b/console/account/src/signature/to_fields.rs index 32763477f2..b061273cdc 100644 --- a/console/account/src/signature/to_fields.rs +++ b/console/account/src/signature/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/account/src/signature/verify.rs b/console/account/src/signature/verify.rs index c0b97bb2e4..13e4a962bf 100644 --- a/console/account/src/signature/verify.rs +++ b/console/account/src/signature/verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -80,9 +81,9 @@ impl Signature { #[cfg(feature = "private_key")] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 100; diff --git a/console/account/src/view_key/bytes.rs b/console/account/src/view_key/bytes.rs index 9592de8231..a0337fe532 100644 --- a/console/account/src/view_key/bytes.rs +++ b/console/account/src/view_key/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -31,9 +32,9 @@ impl ToBytes for ViewKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/view_key/mod.rs b/console/account/src/view_key/mod.rs index ed7421d101..2913ed9207 100644 --- a/console/account/src/view_key/mod.rs +++ b/console/account/src/view_key/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -51,9 +52,9 @@ impl Deref for ViewKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/view_key/serialize.rs b/console/account/src/view_key/serialize.rs index 03a6f28078..973b683d66 100644 --- a/console/account/src/view_key/serialize.rs +++ b/console/account/src/view_key/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -41,9 +42,9 @@ impl<'de, N: Network> Deserialize<'de> for ViewKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/view_key/string.rs b/console/account/src/view_key/string.rs index cf7c93a56a..7a605e3b7e 100644 --- a/console/account/src/view_key/string.rs +++ b/console/account/src/view_key/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -48,9 +49,9 @@ impl fmt::Display for ViewKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/view_key/to_address.rs b/console/account/src/view_key/to_address.rs index 892064946c..fb5809a42a 100644 --- a/console/account/src/view_key/to_address.rs +++ b/console/account/src/view_key/to_address.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,9 +25,9 @@ impl ViewKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/account/src/view_key/try_from.rs b/console/account/src/view_key/try_from.rs index 6f11378a93..81e64b701a 100644 --- a/console/account/src/view_key/try_from.rs +++ b/console/account/src/view_key/try_from.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -51,9 +52,9 @@ impl TryFrom<(&PrivateKey, &ComputeKey)> for ViewKey { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/algorithms/Cargo.toml b/console/algorithms/Cargo.toml index 575d0c8173..d4c2dcf45b 100644 --- a/console/algorithms/Cargo.toml +++ b/console/algorithms/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "snarkvm-console-algorithms" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Console algorithms for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" @@ -23,18 +25,18 @@ harness = false [dependencies.snarkvm-console-types] path = "../types" -version = "=0.16.19" +version = "=1.1.0" default-features = false features = [ "field", "group", "integers", "scalar" ] [dependencies.snarkvm-fields] path = "../../fields" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-utilities] path = "../../utilities" -version = "=0.16.19" +version = "=1.1.0" [dependencies.blake2s_simd] version = "1.0" diff --git a/console/algorithms/benches/bhp.rs b/console/algorithms/benches/bhp.rs index d13f4fd63a..2ba3e2b6b9 100644 --- a/console/algorithms/benches/bhp.rs +++ b/console/algorithms/benches/bhp.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,7 +16,7 @@ #[macro_use] extern crate criterion; -use snarkvm_console_algorithms::{BHP1024, BHP256, BHP512, BHP768}; +use snarkvm_console_algorithms::{BHP256, BHP512, BHP768, BHP1024}; use snarkvm_console_types::prelude::*; use snarkvm_utilities::{TestRng, Uniform}; diff --git a/console/algorithms/benches/elligator2.rs b/console/algorithms/benches/elligator2.rs index 055aa977b6..4fc094431c 100644 --- a/console/algorithms/benches/elligator2.rs +++ b/console/algorithms/benches/elligator2.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/benches/poseidon.rs b/console/algorithms/benches/poseidon.rs index be7a74b426..71256bd345 100644 --- a/console/algorithms/benches/poseidon.rs +++ b/console/algorithms/benches/poseidon.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/bhp/commit.rs b/console/algorithms/src/bhp/commit.rs index 10d19c818d..38fdcf7ce6 100644 --- a/console/algorithms/src/bhp/commit.rs +++ b/console/algorithms/src/bhp/commit.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/bhp/commit_uncompressed.rs b/console/algorithms/src/bhp/commit_uncompressed.rs index d772973a30..e9950044ec 100644 --- a/console/algorithms/src/bhp/commit_uncompressed.rs +++ b/console/algorithms/src/bhp/commit_uncompressed.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/bhp/hash.rs b/console/algorithms/src/bhp/hash.rs index f5e64ecfd7..88ccd14bd2 100644 --- a/console/algorithms/src/bhp/hash.rs +++ b/console/algorithms/src/bhp/hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/bhp/hash_uncompressed.rs b/console/algorithms/src/bhp/hash_uncompressed.rs index 85d16ec591..5bb1d9d974 100644 --- a/console/algorithms/src/bhp/hash_uncompressed.rs +++ b/console/algorithms/src/bhp/hash_uncompressed.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/bhp/hasher/hash_uncompressed.rs b/console/algorithms/src/bhp/hasher/hash_uncompressed.rs index afad77765a..18236a03c8 100644 --- a/console/algorithms/src/bhp/hasher/hash_uncompressed.rs +++ b/console/algorithms/src/bhp/hasher/hash_uncompressed.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/bhp/hasher/mod.rs b/console/algorithms/src/bhp/hasher/mod.rs index 929f5be16f..1de1958378 100644 --- a/console/algorithms/src/bhp/hasher/mod.rs +++ b/console/algorithms/src/bhp/hasher/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/bhp/mod.rs b/console/algorithms/src/bhp/mod.rs index 801b0f7fa6..bff928e025 100644 --- a/console/algorithms/src/bhp/mod.rs +++ b/console/algorithms/src/bhp/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/blake2xs/hash_to_curve.rs b/console/algorithms/src/blake2xs/hash_to_curve.rs index afbf7acedf..1fa3e1bbad 100644 --- a/console/algorithms/src/blake2xs/hash_to_curve.rs +++ b/console/algorithms/src/blake2xs/hash_to_curve.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/blake2xs/mod.rs b/console/algorithms/src/blake2xs/mod.rs index 8ebc5bf1c6..af4e6a7239 100644 --- a/console/algorithms/src/blake2xs/mod.rs +++ b/console/algorithms/src/blake2xs/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/elligator2/decode.rs b/console/algorithms/src/elligator2/decode.rs index fcfb8a0086..500ef7aec0 100644 --- a/console/algorithms/src/elligator2/decode.rs +++ b/console/algorithms/src/elligator2/decode.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/elligator2/encode.rs b/console/algorithms/src/elligator2/encode.rs index ea9110830f..d1b800aa39 100644 --- a/console/algorithms/src/elligator2/encode.rs +++ b/console/algorithms/src/elligator2/encode.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/elligator2/mod.rs b/console/algorithms/src/elligator2/mod.rs index 16c09b83a9..8b7792c355 100644 --- a/console/algorithms/src/elligator2/mod.rs +++ b/console/algorithms/src/elligator2/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/keccak/hash.rs b/console/algorithms/src/keccak/hash.rs index 52dc3ecb29..afd3ddced1 100644 --- a/console/algorithms/src/keccak/hash.rs +++ b/console/algorithms/src/keccak/hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/keccak/mod.rs b/console/algorithms/src/keccak/mod.rs index b1c54e931a..f1fc3efe02 100644 --- a/console/algorithms/src/keccak/mod.rs +++ b/console/algorithms/src/keccak/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/lib.rs b/console/algorithms/src/lib.rs index 9c6c5e13dc..44df2a4007 100644 --- a/console/algorithms/src/lib.rs +++ b/console/algorithms/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,7 +21,7 @@ pub use snarkvm_console_types::prelude::*; pub mod bhp; -pub use bhp::{BHP, BHP1024, BHP256, BHP512, BHP768}; +pub use bhp::{BHP, BHP256, BHP512, BHP768, BHP1024}; mod blake2xs; pub use blake2xs::Blake2Xs; @@ -32,7 +33,7 @@ mod keccak; pub use keccak::*; mod pedersen; -pub use pedersen::{Pedersen, Pedersen128, Pedersen64}; +pub use pedersen::{Pedersen, Pedersen64, Pedersen128}; mod poseidon; pub use poseidon::{Poseidon, Poseidon2, Poseidon4, Poseidon8}; diff --git a/console/algorithms/src/pedersen/commit.rs b/console/algorithms/src/pedersen/commit.rs index 66575599f5..0311a481fe 100644 --- a/console/algorithms/src/pedersen/commit.rs +++ b/console/algorithms/src/pedersen/commit.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/pedersen/commit_uncompressed.rs b/console/algorithms/src/pedersen/commit_uncompressed.rs index 519b0656d6..14203457bf 100644 --- a/console/algorithms/src/pedersen/commit_uncompressed.rs +++ b/console/algorithms/src/pedersen/commit_uncompressed.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/pedersen/hash.rs b/console/algorithms/src/pedersen/hash.rs index e9fc9885ec..0718b135f5 100644 --- a/console/algorithms/src/pedersen/hash.rs +++ b/console/algorithms/src/pedersen/hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/pedersen/hash_uncompressed.rs b/console/algorithms/src/pedersen/hash_uncompressed.rs index 9bac454ac1..70fcc01b60 100644 --- a/console/algorithms/src/pedersen/hash_uncompressed.rs +++ b/console/algorithms/src/pedersen/hash_uncompressed.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/pedersen/mod.rs b/console/algorithms/src/pedersen/mod.rs index 349a8d2c2c..ceeee73dab 100644 --- a/console/algorithms/src/pedersen/mod.rs +++ b/console/algorithms/src/pedersen/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/poseidon/hash.rs b/console/algorithms/src/poseidon/hash.rs index aef86d3ae2..bedaf4e54e 100644 --- a/console/algorithms/src/poseidon/hash.rs +++ b/console/algorithms/src/poseidon/hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/poseidon/hash_many.rs b/console/algorithms/src/poseidon/hash_many.rs index fa789d900e..df516db2bd 100644 --- a/console/algorithms/src/poseidon/hash_many.rs +++ b/console/algorithms/src/poseidon/hash_many.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/poseidon/hash_to_group.rs b/console/algorithms/src/poseidon/hash_to_group.rs index 746e5612bd..399d8e5225 100644 --- a/console/algorithms/src/poseidon/hash_to_group.rs +++ b/console/algorithms/src/poseidon/hash_to_group.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/poseidon/hash_to_scalar.rs b/console/algorithms/src/poseidon/hash_to_scalar.rs index 5042d130dd..cfe8eb1460 100644 --- a/console/algorithms/src/poseidon/hash_to_scalar.rs +++ b/console/algorithms/src/poseidon/hash_to_scalar.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/poseidon/helpers/mod.rs b/console/algorithms/src/poseidon/helpers/mod.rs index 1f33f86842..afa0964b89 100644 --- a/console/algorithms/src/poseidon/helpers/mod.rs +++ b/console/algorithms/src/poseidon/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,7 +19,7 @@ pub(super) use sponge::*; mod state; pub(super) use state::*; -use snarkvm_console_types::{prelude::*, Field}; +use snarkvm_console_types::{Field, prelude::*}; use smallvec::SmallVec; diff --git a/console/algorithms/src/poseidon/helpers/sponge.rs b/console/algorithms/src/poseidon/helpers/sponge.rs index 92fd0b626c..7d005868f6 100644 --- a/console/algorithms/src/poseidon/helpers/sponge.rs +++ b/console/algorithms/src/poseidon/helpers/sponge.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,10 +14,10 @@ // limitations under the License. use crate::poseidon::{ - helpers::{AlgebraicSponge, DuplexSpongeMode}, State, + helpers::{AlgebraicSponge, DuplexSpongeMode}, }; -use snarkvm_console_types::{prelude::*, Field}; +use snarkvm_console_types::{Field, prelude::*}; use snarkvm_fields::PoseidonParameters; use smallvec::SmallVec; diff --git a/console/algorithms/src/poseidon/helpers/state.rs b/console/algorithms/src/poseidon/helpers/state.rs index 08896fdb53..083789b1ac 100644 --- a/console/algorithms/src/poseidon/helpers/state.rs +++ b/console/algorithms/src/poseidon/helpers/state.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use snarkvm_console_types::{prelude::*, Field}; +use snarkvm_console_types::{Field, prelude::*}; use core::ops::{Index, IndexMut, Range}; diff --git a/console/algorithms/src/poseidon/mod.rs b/console/algorithms/src/poseidon/mod.rs index b74b21a3e2..ca5da7f42a 100644 --- a/console/algorithms/src/poseidon/mod.rs +++ b/console/algorithms/src/poseidon/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,7 +21,7 @@ mod hash_to_group; mod hash_to_scalar; mod prf; -use crate::{poseidon::helpers::*, Elligator2}; +use crate::{Elligator2, poseidon::helpers::*}; use snarkvm_console_types::prelude::*; use snarkvm_fields::{PoseidonDefaultField, PoseidonParameters}; @@ -170,4 +171,253 @@ mod tests { single_rate_test::<7>(); single_rate_test::<8>(); } + + #[test] + fn test_suite_hash2() { + fn test_case_hash2(index: u8, input: Vec>) { + let poseidon2 = Poseidon2::::setup("Poseidon2").unwrap(); + assert_snapshot("test_hash", format!("rate_2_test_{index}"), poseidon2.hash(&input).unwrap()); + } + test_case_hash2(0, vec![]); + test_case_hash2(1, vec![Field::::from_u8(0)]); + test_case_hash2(2, vec![Field::::from_u8(1)]); + test_case_hash2(3, vec![Field::::from_u8(0), Field::::from_u8(1)]); + test_case_hash2(4, vec![Field::::from_u8(7), Field::::from_u8(6)]); + } + + #[test] + fn test_suite_hash4() { + fn test_case_hash4(index: u8, input: Vec>) { + let poseidon4 = Poseidon4::::setup("Poseidon4").unwrap(); + assert_snapshot("test_hash", format!("rate_4_test_{index}"), poseidon4.hash(&input).unwrap()); + } + test_case_hash4(0, vec![]); + test_case_hash4(1, vec![Field::::from_u8(0)]); + test_case_hash4(2, vec![Field::::from_u8(1)]); + test_case_hash4(3, vec![Field::::from_u8(0), Field::::from_u8(1)]); + test_case_hash4(4, vec![Field::::from_u8(7), Field::::from_u8(6)]); + test_case_hash4(5, vec![ + Field::::from_str( + "3801852864665033841774715284518384682376829752661853198612247855579120198106field", + ) + .unwrap(), + Field::::from_str( + "8354898322875240371401674517397790035008442020361740574117886421279083828480field", + ) + .unwrap(), + Field::::from_str( + "4810388512520169167962815122521832339992376865086300759308552937986944510606field", + ) + .unwrap(), + ]); + test_case_hash4(6, vec![ + Field::::from_str( + "3801852864665033841774715284518384682376829752661853198612247855579120198106field", + ) + .unwrap(), + Field::::from_str( + "8354898322875240371401674517397790035008442020361740574117886421279083828480field", + ) + .unwrap(), + Field::::from_str( + "4810388512520169167962815122521832339992376865086300759308552937986944510606field", + ) + .unwrap(), + Field::::from_str( + "1806278863067630397941269234951941896370617486625414347832536440203404317871field", + ) + .unwrap(), + ]); + test_case_hash4(7, vec![ + Field::::from_str( + "3801852864665033841774715284518384682376829752661853198612247855579120198106field", + ) + .unwrap(), + Field::::from_str( + "8354898322875240371401674517397790035008442020361740574117886421279083828480field", + ) + .unwrap(), + Field::::from_str( + "4810388512520169167962815122521832339992376865086300759308552937986944510606field", + ) + .unwrap(), + Field::::from_str( + "1806278863067630397941269234951941896370617486625414347832536440203404317871field", + ) + .unwrap(), + Field::::from_str( + "4017177598231920767921734423139954103557056461408532722673217828464276314809field", + ) + .unwrap(), + ]); + } + + #[test] + fn test_suite_hash8() { + fn test_case_hash8(index: u16, input: Vec>) { + let poseidon8 = Poseidon8::::setup("Poseidon8").unwrap(); + assert_snapshot("test_hash", format!("rate_8_test_{index}"), poseidon8.hash(&input).unwrap()); + } + test_case_hash8(0, vec![]); + test_case_hash8(1, vec![Field::::from_u8(0)]); + test_case_hash8(2, vec![Field::::from_u8(1)]); + test_case_hash8(3, vec![Field::::from_u8(0), Field::::from_u8(1)]); + test_case_hash8(4, vec![Field::::from_u8(7), Field::::from_u8(6)]); + test_case_hash8(5, vec![ + Field::::from_str( + "3801852864665033841774715284518384682376829752661853198612247855579120198106field", + ) + .unwrap(), + Field::::from_str( + "8354898322875240371401674517397790035008442020361740574117886421279083828480field", + ) + .unwrap(), + Field::::from_str( + "4810388512520169167962815122521832339992376865086300759308552937986944510606field", + ) + .unwrap(), + ]); + test_case_hash8(6, vec![ + Field::::from_str( + "3801852864665033841774715284518384682376829752661853198612247855579120198106field", + ) + .unwrap(), + Field::::from_str( + "8354898322875240371401674517397790035008442020361740574117886421279083828480field", + ) + .unwrap(), + Field::::from_str( + "4810388512520169167962815122521832339992376865086300759308552937986944510606field", + ) + .unwrap(), + Field::::from_str( + "1806278863067630397941269234951941896370617486625414347832536440203404317871field", + ) + .unwrap(), + ]); + test_case_hash8(7, vec![ + Field::::from_str( + "3801852864665033841774715284518384682376829752661853198612247855579120198106field", + ) + .unwrap(), + Field::::from_str( + "8354898322875240371401674517397790035008442020361740574117886421279083828480field", + ) + .unwrap(), + Field::::from_str( + "4810388512520169167962815122521832339992376865086300759308552937986944510606field", + ) + .unwrap(), + Field::::from_str( + "1806278863067630397941269234951941896370617486625414347832536440203404317871field", + ) + .unwrap(), + Field::::from_str( + "4017177598231920767921734423139954103557056461408532722673217828464276314809field", + ) + .unwrap(), + ]); + test_case_hash8(8, vec![ + Field::::from_str( + "2241061724039470158487229089505123379386376040366677537043719491567584322339field", + ) + .unwrap(), + Field::::from_str( + "4450395467941419565906844040025562669400620759737863109185235386261110553073field", + ) + .unwrap(), + Field::::from_str( + "3763549180544198711495347718218896634621699987767108409942867882747700142403field", + ) + .unwrap(), + Field::::from_str( + "1834649076610684411560795826346579299134200286711220272747136514724202486145field", + ) + .unwrap(), + Field::::from_str( + "3330794675297759513930533281299019673013197332462213086257974185952740704073field", + ) + .unwrap(), + Field::::from_str( + "5929621997900969559642343088519370677943323262633114245367700983937202243619field", + ) + .unwrap(), + Field::::from_str( + "8211311402459203356251863974142333868284569297703150729090604853345946857386field", + ) + .unwrap(), + ]); + test_case_hash8(9, vec![ + Field::::from_str( + "160895951580389706659907027483151875213333010019551276998320919296228647317field", + ) + .unwrap(), + Field::::from_str( + "8334099740396373026754940038411748941117628023990297711605274995172393663866field", + ) + .unwrap(), + Field::::from_str( + "6508516067551208838086421306235504440162527555399726948591414865066786644888field", + ) + .unwrap(), + Field::::from_str( + "5260580011132523115913756761919139190330166964648541423363604516046903841683field", + ) + .unwrap(), + Field::::from_str( + "1066299182733912299977577599302716102002738653010828827086884529157392046228field", + ) + .unwrap(), + Field::::from_str( + "1977519953625589014039847898215240724041194773120013187722954068145627219929field", + ) + .unwrap(), + Field::::from_str( + "1618348632868002512910764605250139381231860094469042556990470848701700964713field", + ) + .unwrap(), + Field::::from_str( + "1157459381876765943377450451674060447297483544491073402235960067133285590974field", + ) + .unwrap(), + ]); + test_case_hash8(10, vec![ + Field::::from_str( + "3912308888616251672812272013988802988420414245857866136212784631403027079860field", + ) + .unwrap(), + Field::::from_str( + "4100923705771018951561873336835055979905965765839649442185404560120892958216field", + ) + .unwrap(), + Field::::from_str( + "5701101373789959818781445339314572139971317958997296225671698446757742149719field", + ) + .unwrap(), + Field::::from_str( + "5785597627944719799683455467917641287692417422465938462034769734951914291948field", + ) + .unwrap(), + Field::::from_str( + "214818498460401597228033958287537426429167258531438668351703993840760770582field", + ) + .unwrap(), + Field::::from_str( + "4497884203527978976088488455523871581608892729212445595385399904032800522087field", + ) + .unwrap(), + Field::::from_str( + "4010331535874074900042223641934450423780782982190514529696596753456937384201field", + ) + .unwrap(), + Field::::from_str( + "6067637133445382691713836557146174628934072680692724940823629181144890569742field", + ) + .unwrap(), + Field::::from_str( + "5966421531117752671625849775894572561179958822813329961720805067254995723444field", + ) + .unwrap(), + ]); + } } diff --git a/console/algorithms/src/poseidon/prf.rs b/console/algorithms/src/poseidon/prf.rs index 8b71fdb5d9..405e8f43ec 100644 --- a/console/algorithms/src/poseidon/prf.rs +++ b/console/algorithms/src/poseidon/prf.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_0.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_0.snap new file mode 100644 index 0000000000..3a9206b65c --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_0.snap @@ -0,0 +1 @@ +890528275010128413086262374581080260861073041656622537351850370623612770892field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_1.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_1.snap new file mode 100644 index 0000000000..f168451598 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_1.snap @@ -0,0 +1 @@ +5628341397010129094749668483581880102727432924493934736184943293239516955115field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_2.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_2.snap new file mode 100644 index 0000000000..bd4d43c89b --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_2.snap @@ -0,0 +1 @@ +8157139884333238590486942177518291201805404831318752263970723012511043776504field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_3.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_3.snap new file mode 100644 index 0000000000..df1d74d6e2 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_3.snap @@ -0,0 +1 @@ +1264503312579512465189393860390753485466098990459556420139454725533509612591field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_4.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_4.snap new file mode 100644 index 0000000000..4fefae5666 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_2_test_4.snap @@ -0,0 +1 @@ +610307558855046745962283397484544098131504333994299967172265018394298942553field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_0.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_0.snap new file mode 100644 index 0000000000..091fb2acd5 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_0.snap @@ -0,0 +1 @@ +1044346838034619416100171813313106342224256770546574686139345274096660160611field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_1.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_1.snap new file mode 100644 index 0000000000..9eaae5fd62 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_1.snap @@ -0,0 +1 @@ +6531918078649604677267704629524208386557917803204512136246020129886969612813field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_2.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_2.snap new file mode 100644 index 0000000000..4974beeb00 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_2.snap @@ -0,0 +1 @@ +4426996492654533614386079842002262353437097961897230015892590642692830916891field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_3.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_3.snap new file mode 100644 index 0000000000..e93255bfd3 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_3.snap @@ -0,0 +1 @@ +3515567246660071748861271187713830429704652891229797018766869690557265012151field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_4.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_4.snap new file mode 100644 index 0000000000..8d8b56b478 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_4.snap @@ -0,0 +1 @@ +6569866994757293255004300918458370975674559167201047636575858551784982288595field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_5.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_5.snap new file mode 100644 index 0000000000..a2c326b740 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_5.snap @@ -0,0 +1 @@ +87141345289194987249335251035288105774877062220257664575645549134632926482field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_6.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_6.snap new file mode 100644 index 0000000000..90b305b74c --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_6.snap @@ -0,0 +1 @@ +7213538381157479600695819072074313481664544179359574938537072092346114865618field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_7.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_7.snap new file mode 100644 index 0000000000..ce42b96e5c --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_4_test_7.snap @@ -0,0 +1 @@ +5481099192588700791287898101517060190977970633110857260811993991553610949275field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_0.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_0.snap new file mode 100644 index 0000000000..7b66e9f380 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_0.snap @@ -0,0 +1 @@ +1567761742253784763517697634212670888744157690807242184088612393580063919530field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_1.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_1.snap new file mode 100644 index 0000000000..6e8f55f836 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_1.snap @@ -0,0 +1 @@ +4116380618505203139735709763188062899546807129226239980574382125889245087784field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_10.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_10.snap new file mode 100644 index 0000000000..16f625fbe0 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_10.snap @@ -0,0 +1 @@ +305373231140119141495771730195166660114047796312466197355241017473154264594field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_2.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_2.snap new file mode 100644 index 0000000000..5904866362 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_2.snap @@ -0,0 +1 @@ +1602821949296022806146270121391383580291702991974340780933114647223620852779field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_3.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_3.snap new file mode 100644 index 0000000000..337fb8053c --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_3.snap @@ -0,0 +1 @@ +4504853075224575973859580682353724684440391731949662062689299393698522574250field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_4.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_4.snap new file mode 100644 index 0000000000..d58a18f390 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_4.snap @@ -0,0 +1 @@ +2011084681212961452311333305005509211229919616031257660941313625311987279984field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_5.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_5.snap new file mode 100644 index 0000000000..2bf7340576 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_5.snap @@ -0,0 +1 @@ +2441207636122714306371856624370101512638654024941597476504350040586876819967field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_6.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_6.snap new file mode 100644 index 0000000000..cbe5938b6d --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_6.snap @@ -0,0 +1 @@ +6088573564989104999418724140351215790250870264476768543870720179680005600079field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_7.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_7.snap new file mode 100644 index 0000000000..ab14ebd888 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_7.snap @@ -0,0 +1 @@ +5831342285401093988805641165492026817697793896414496472388751494052459296879field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_8.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_8.snap new file mode 100644 index 0000000000..9f32867b97 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_8.snap @@ -0,0 +1 @@ +1444892038274156943837009734886522214149622494611671083296024163883829362979field \ No newline at end of file diff --git a/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_9.snap b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_9.snap new file mode 100644 index 0000000000..5d34904771 --- /dev/null +++ b/console/algorithms/src/poseidon/resources/test_hash/rate_8_test_9.snap @@ -0,0 +1 @@ +1194605944695343789228228597749032243744971209446840517486291637780197055440field \ No newline at end of file diff --git a/console/collections/Cargo.toml b/console/collections/Cargo.toml index c853649f27..036d17bd69 100644 --- a/console/collections/Cargo.toml +++ b/console/collections/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "snarkvm-console-collections" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Collections for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" @@ -18,11 +20,11 @@ harness = false [dependencies.snarkvm-console-algorithms] path = "../algorithms" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types] path = "../types" -version = "=0.16.19" +version = "=1.1.0" default-features = false features = [ "field", "integers" ] diff --git a/console/collections/benches/kary_merkle_tree.rs b/console/collections/benches/kary_merkle_tree.rs index f3610a0681..fe2e4e0840 100644 --- a/console/collections/benches/kary_merkle_tree.rs +++ b/console/collections/benches/kary_merkle_tree.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,8 +19,8 @@ extern crate criterion; use snarkvm_console_algorithms::Sha3_256; use snarkvm_console_collections::kary_merkle_tree::KaryMerkleTree; use snarkvm_console_network::{ + MainnetV0, prelude::{TestRng, ToBits, Uniform}, - Testnet3, }; use snarkvm_console_types::Field; @@ -30,7 +31,7 @@ const ARITY: u8 = 8; /// Generates the specified number of random Merkle tree leaves. macro_rules! generate_leaves { - ($num_leaves:expr, $rng:expr) => {{ (0..$num_leaves).map(|_| Field::::rand($rng).to_bits_le()).collect::>() }}; + ($num_leaves:expr, $rng:expr) => {{ (0..$num_leaves).map(|_| Field::::rand($rng).to_bits_le()).collect::>() }}; } fn new(c: &mut Criterion) { diff --git a/console/collections/benches/merkle_tree.rs b/console/collections/benches/merkle_tree.rs index 01baa7fdbc..e1cd6289b2 100644 --- a/console/collections/benches/merkle_tree.rs +++ b/console/collections/benches/merkle_tree.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,9 +17,9 @@ extern crate criterion; use snarkvm_console_network::{ - prelude::{TestRng, ToBits, Uniform}, + MainnetV0, Network, - Testnet3, + prelude::{TestRng, ToBits, Uniform}, }; use snarkvm_console_types::Field; @@ -34,7 +35,7 @@ const UPDATE_SIZES: &[usize] = &[1, 10, 100, 1_000, 10_000]; /// Generates the specified number of random Merkle tree leaves. macro_rules! generate_leaves { - ($num_leaves:expr, $rng:expr) => {{ (0..$num_leaves).map(|_| Field::::rand($rng).to_bits_le()).collect::>() }}; + ($num_leaves:expr, $rng:expr) => {{ (0..$num_leaves).map(|_| Field::::rand($rng).to_bits_le()).collect::>() }}; } fn new(c: &mut Criterion) { @@ -45,7 +46,7 @@ fn new(c: &mut Criterion) { // Benchmark the creation of a Merkle tree with the specified number of leaves. c.bench_function(&format!("MerkleTree/new/{num_leaves}"), |b| { b.iter(|| { - let _tree = Testnet3::merkle_tree_bhp::(&leaves[0..*num_leaves]).unwrap(); + let _tree = MainnetV0::merkle_tree_bhp::(&leaves[0..*num_leaves]).unwrap(); }) }); } @@ -61,7 +62,7 @@ fn append(c: &mut Criterion) { for num_leaves in NUM_LEAVES { for num_new_leaves in APPEND_SIZES { // Construct a Merkle tree with the specified number of leaves. - let merkle_tree = Testnet3::merkle_tree_bhp::(&leaves[..*num_leaves]).unwrap(); + let merkle_tree = MainnetV0::merkle_tree_bhp::(&leaves[..*num_leaves]).unwrap(); c.bench_function(&format!("MerkleTree/append/{num_leaves}/{num_new_leaves}"), |b| { b.iter_batched( || merkle_tree.clone(), @@ -93,7 +94,7 @@ fn update(c: &mut Criterion) { for num_new_leaves in UPDATE_SIZES { // Construct a Merkle tree with the specified number of leaves. - let merkle_tree = Testnet3::merkle_tree_bhp::(&leaves[..*num_leaves]).unwrap(); + let merkle_tree = MainnetV0::merkle_tree_bhp::(&leaves[..*num_leaves]).unwrap(); c.bench_function(&format!("MerkleTree/update/{num_leaves}/{num_new_leaves}"), |b| { b.iter_batched( @@ -131,7 +132,7 @@ fn update_many(c: &mut Criterion) { for num_new_leaves in UPDATE_SIZES { // Construct a Merkle tree with the specified number of leaves. - let merkle_tree = Testnet3::merkle_tree_bhp::(&leaves[..*num_leaves]).unwrap(); + let merkle_tree = MainnetV0::merkle_tree_bhp::(&leaves[..*num_leaves]).unwrap(); let num_new_leaves = std::cmp::min(*num_new_leaves, updates.len()); let updates = BTreeMap::from_iter(updates[..num_new_leaves].iter().cloned()); c.bench_function(&format!("MerkleTree/update_many/{num_leaves}/{num_new_leaves}",), |b| { @@ -157,18 +158,18 @@ fn update_vs_update_many(c: &mut Criterion) { // Compute the number of leaves at this depth. let num_leaves = 2usize.saturating_pow(depth as u32); // Construct a Merkle tree with the specified number of leaves. - let tree = Testnet3::merkle_tree_bhp::(&leaves[..num_leaves]).unwrap(); + let tree = MainnetV0::merkle_tree_bhp::(&leaves[..num_leaves]).unwrap(); // Generate a new leaf and select a random index to update. let index: usize = Uniform::rand(&mut rng); let index = index % num_leaves; let new_leaf = generate_leaves!(1, &mut rng).pop().unwrap(); // Benchmark the standard update operation. - group.bench_with_input(BenchmarkId::new("Single", &format!("{depth}")), &new_leaf, |b, new_leaf| { + group.bench_with_input(BenchmarkId::new("Single", format!("{depth}")), &new_leaf, |b, new_leaf| { b.iter_batched(|| tree.clone(), |mut tree| tree.update(index, new_leaf), BatchSize::SmallInput) }); // Benchmark the `update_many` operation. group.bench_with_input( - BenchmarkId::new("Batch", &format!("{depth}")), + BenchmarkId::new("Batch", format!("{depth}")), &BTreeMap::from([(index, new_leaf)]), |b, updates| b.iter_batched(|| tree.clone(), |mut tree| tree.update_many(updates), BatchSize::SmallInput), ); diff --git a/console/collections/src/kary_merkle_tree/helpers/leaf_hash.rs b/console/collections/src/kary_merkle_tree/helpers/leaf_hash.rs index a48486e371..cfcd566dd4 100644 --- a/console/collections/src/kary_merkle_tree/helpers/leaf_hash.rs +++ b/console/collections/src/kary_merkle_tree/helpers/leaf_hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use snarkvm_console_algorithms::{Keccak, Poseidon, BHP}; +use snarkvm_console_algorithms::{BHP, Keccak, Poseidon}; use snarkvm_console_types::prelude::*; use crate::kary_merkle_tree::BooleanHash; diff --git a/console/collections/src/kary_merkle_tree/helpers/mod.rs b/console/collections/src/kary_merkle_tree/helpers/mod.rs index df71d870df..1d06917d43 100644 --- a/console/collections/src/kary_merkle_tree/helpers/mod.rs +++ b/console/collections/src/kary_merkle_tree/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/collections/src/kary_merkle_tree/helpers/path_hash.rs b/console/collections/src/kary_merkle_tree/helpers/path_hash.rs index 57ae61a2a4..5998e3c688 100644 --- a/console/collections/src/kary_merkle_tree/helpers/path_hash.rs +++ b/console/collections/src/kary_merkle_tree/helpers/path_hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use super::BooleanHash; -use snarkvm_console_algorithms::{Keccak, Poseidon, BHP}; +use snarkvm_console_algorithms::{BHP, Keccak, Poseidon}; use snarkvm_console_types::prelude::*; #[cfg(not(feature = "serial"))] @@ -32,8 +33,8 @@ pub trait PathHash: Clone + Send + Sync { self.hash_children(&children) } - /// Returns the hash for each tuple of child nodes. - fn hash_all_children(&self, child_nodes: &[Vec]) -> Result> { + /// Returns the hash for each child node. + fn hash_all_children(&self, child_nodes: &[&[Self::Hash]]) -> Result> { match child_nodes.len() { 0 => Ok(vec![]), 1..=100 => child_nodes.iter().map(|children| self.hash_children(children)).collect(), diff --git a/console/collections/src/kary_merkle_tree/mod.rs b/console/collections/src/kary_merkle_tree/mod.rs index 81ebd5c488..5b05a7672a 100644 --- a/console/collections/src/kary_merkle_tree/mod.rs +++ b/console/collections/src/kary_merkle_tree/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,6 +25,7 @@ mod tests; use snarkvm_console_types::prelude::*; use aleo_std::prelude::*; +use std::ops::Range; #[derive(Clone)] pub struct KaryMerkleTree, PH: PathHash, const DEPTH: u8, const ARITY: u8> { @@ -89,8 +91,18 @@ impl, PH: PathHash, const DEPTH: u8, const ARITY: // Compute the empty hash. let empty_hash = path_hasher.hash_empty::()?; + // Calculate the size of the tree which excludes leafless nodes. + // The minimum tree size is either a single root node or the calculated number of nodes plus + // the supplied leaves, and empty hashes that pad up to the tree's arity (making every node full). + let arity = ARITY as usize; + let all_nodes_are_full = leaves.len() % arity == 0; + let minimum_tree_size = std::cmp::max( + 1, + num_nodes + leaves.len() + if all_nodes_are_full { 0 } else { arity - leaves.len() % arity }, + ); + // Initialize the Merkle tree. - let mut tree = vec![empty_hash; tree_size]; + let mut tree = vec![empty_hash; minimum_tree_size]; // Compute and store each leaf hash. tree[num_nodes..num_nodes + leaves.len()].clone_from_slice(&leaf_hasher.hash_leaves(leaves)?); @@ -105,10 +117,21 @@ impl, PH: PathHash, const DEPTH: u8, const ARITY: // Construct the children for each node in the current level. let child_nodes = (start..end) - .map(|i| child_indexes::(i).map(|child_index| tree[child_index]).collect::>()) + .take_while(|&i| child_indexes::(i).next().and_then(|idx| tree.get(idx)).is_some()) + .map(|i| &tree[child_indexes::(i)]) .collect::>(); + // Compute and store the hashes for each node in the current level. - tree[start..end].clone_from_slice(&path_hasher.hash_all_children(&child_nodes)?); + let num_full_nodes = child_nodes.len(); + let hashes = path_hasher.hash_all_children(&child_nodes)?; + tree[start..][..num_full_nodes].clone_from_slice(&hashes); + // Use the precomputed empty node hash for every empty node, if there are any. + if start + num_full_nodes < end { + let empty_node_hash = path_hasher.hash_children(&vec![empty_hash; arity])?; + for node in tree.iter_mut().take(end).skip(start + num_full_nodes) { + *node = empty_node_hash; + } + } // Update the start index for the next level. start_index = start; } @@ -241,7 +264,7 @@ fn tree_depth(tree_size: usize) -> Result } /// Returns the indexes of the children, given an index. -fn child_indexes(index: usize) -> impl Iterator { +fn child_indexes(index: usize) -> Range { let start = index * ARITY as usize + 1; start..start + ARITY as usize } diff --git a/console/collections/src/kary_merkle_tree/path/mod.rs b/console/collections/src/kary_merkle_tree/path/mod.rs index 3fa0f4a354..f3dedfccdf 100644 --- a/console/collections/src/kary_merkle_tree/path/mod.rs +++ b/console/collections/src/kary_merkle_tree/path/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/collections/src/kary_merkle_tree/tests/mod.rs b/console/collections/src/kary_merkle_tree/tests/mod.rs index 08abc90673..4ee1a09cb2 100644 --- a/console/collections/src/kary_merkle_tree/tests/mod.rs +++ b/console/collections/src/kary_merkle_tree/tests/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use super::*; -use snarkvm_console_algorithms::{Keccak256, Poseidon, Sha3_256, BHP1024, BHP512}; +use snarkvm_console_algorithms::{BHP512, BHP1024, Keccak256, Poseidon, Sha3_256}; use snarkvm_console_types::prelude::Console; type CurrentEnvironment = Console; @@ -170,7 +171,7 @@ fn check_merkle_tree_depth_3_arity_3_padded, PH: P // Construct the Merkle tree for the given leaves. let merkle_tree = KaryMerkleTree::::new(leaf_hasher, path_hasher, &leaves)?; - assert_eq!(40, merkle_tree.tree.len()); + assert_eq!(25, merkle_tree.tree.len()); assert_eq!(10, merkle_tree.number_of_leaves); // Depth 3. @@ -194,7 +195,7 @@ fn check_merkle_tree_depth_3_arity_3_padded, PH: P assert_eq!(expected_leaf7, merkle_tree.tree[20]); assert_eq!(expected_leaf8, merkle_tree.tree[21]); assert_eq!(expected_leaf9, merkle_tree.tree[22]); - for i in 23..40 { + for i in 23..25 { assert_eq!(path_hasher.hash_empty::()?, merkle_tree.tree[i]); } diff --git a/console/collections/src/lib.rs b/console/collections/src/lib.rs index 2e44497dbc..06094faab2 100644 --- a/console/collections/src/lib.rs +++ b/console/collections/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/collections/src/merkle_tree/helpers/leaf_hash.rs b/console/collections/src/merkle_tree/helpers/leaf_hash.rs index 11cd1fc04f..c0cac0875d 100644 --- a/console/collections/src/merkle_tree/helpers/leaf_hash.rs +++ b/console/collections/src/merkle_tree/helpers/leaf_hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use snarkvm_console_algorithms::{Poseidon, BHP}; +use snarkvm_console_algorithms::{BHP, Poseidon}; use snarkvm_console_types::prelude::*; #[cfg(not(feature = "serial"))] diff --git a/console/collections/src/merkle_tree/helpers/mod.rs b/console/collections/src/merkle_tree/helpers/mod.rs index f4a8b75691..cfcfd418cb 100644 --- a/console/collections/src/merkle_tree/helpers/mod.rs +++ b/console/collections/src/merkle_tree/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/collections/src/merkle_tree/helpers/path_hash.rs b/console/collections/src/merkle_tree/helpers/path_hash.rs index fc9841672c..b026beb77a 100644 --- a/console/collections/src/merkle_tree/helpers/path_hash.rs +++ b/console/collections/src/merkle_tree/helpers/path_hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use snarkvm_console_algorithms::{Poseidon, BHP}; +use snarkvm_console_algorithms::{BHP, Poseidon}; use snarkvm_console_types::prelude::*; #[cfg(not(feature = "serial"))] diff --git a/console/collections/src/merkle_tree/mod.rs b/console/collections/src/merkle_tree/mod.rs index 2e3c273e63..e4fa6e7037 100644 --- a/console/collections/src/merkle_tree/mod.rs +++ b/console/collections/src/merkle_tree/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -77,8 +78,14 @@ impl, PH: PathHash // Compute the empty hash. let empty_hash = path_hasher.hash_empty()?; + // Calculate the size of the tree which excludes leafless nodes. + // The minimum tree size is either a single root node or the calculated number of nodes plus + // the supplied leaves; if the number of leaves is odd, an empty hash is added for padding. + let minimum_tree_size = + std::cmp::max(1, num_nodes + leaves.len() + if leaves.len() > 1 { leaves.len() % 2 } else { 0 }); + // Initialize the Merkle tree. - let mut tree = vec![empty_hash; tree_size]; + let mut tree = vec![empty_hash; minimum_tree_size]; // Compute and store each leaf hash. tree[num_nodes..num_nodes + leaves.len()].copy_from_slice(&leaf_hasher.hash_leaves(leaves)?); @@ -90,10 +97,22 @@ impl, PH: PathHash while let Some(start) = parent(start_index) { // Compute the end index of the current level. let end = left_child(start); - // Construct the children for each node in the current level. - let tuples = (start..end).map(|i| (tree[left_child(i)], tree[right_child(i)])).collect::>(); + // Construct the children for each node in the current level; the leaves are padded, which means + // that there either are 2 children, or there are none, at which point we may stop iterating. + let tuples = (start..end) + .take_while(|&i| tree.get(left_child(i)).is_some()) + .map(|i| (tree[left_child(i)], tree[right_child(i)])) + .collect::>(); // Compute and store the hashes for each node in the current level. - tree[start..end].copy_from_slice(&path_hasher.hash_all_children(&tuples)?); + let num_full_nodes = tuples.len(); + tree[start..][..num_full_nodes].copy_from_slice(&path_hasher.hash_all_children(&tuples)?); + // Use the precomputed empty node hash for every empty node, if there are any. + if start + num_full_nodes < end { + let empty_node_hash = path_hasher.hash_children(&empty_hash, &empty_hash)?; + for node in tree.iter_mut().take(end).skip(start + num_full_nodes) { + *node = empty_node_hash; + } + } // Update the start index for the next level. start_index = start; } @@ -144,8 +163,16 @@ impl, PH: PathHash tree.extend(self.leaf_hashes()?); // Extend the new Merkle tree with the new leaf hashes. tree.extend(&self.leaf_hasher.hash_leaves(new_leaves)?); + + // Calculate the size of the tree which excludes leafless nodes. + let new_number_of_leaves = self.number_of_leaves + new_leaves.len(); + let minimum_tree_size = std::cmp::max( + 1, + num_nodes + new_number_of_leaves + if new_number_of_leaves > 1 { new_number_of_leaves % 2 } else { 0 }, + ); + // Resize the new Merkle tree with empty hashes to pad up to `tree_size`. - tree.resize(tree_size, self.empty_hash); + tree.resize(minimum_tree_size, self.empty_hash); lap!(timer, "Hashed {} new leaves", new_leaves.len()); // Initialize a start index to track the starting index of the current level. @@ -453,12 +480,20 @@ impl, PH: PathHash // Compute the number of padded levels. let padding_depth = DEPTH - tree_depth; + // Calculate the size of the tree which excludes leafless nodes. + let minimum_tree_size = std::cmp::max( + 1, + num_nodes + + updated_number_of_leaves + + if updated_number_of_leaves > 1 { updated_number_of_leaves % 2 } else { 0 }, + ); + // Initialize the Merkle tree. let mut tree = vec![self.empty_hash; num_nodes]; // Extend the new Merkle tree with the existing leaf hashes, excluding the last 'n' leaves. tree.extend(&self.leaf_hashes()?[..updated_number_of_leaves]); // Resize the new Merkle tree with empty hashes to pad up to `tree_size`. - tree.resize(tree_size, self.empty_hash); + tree.resize(minimum_tree_size, self.empty_hash); lap!(timer, "Resizing to {} leaves", updated_number_of_leaves); // Initialize a start index to track the starting index of the current level. @@ -627,6 +662,7 @@ impl, PH: PathHash let timer = timer!("MerkleTree::compute_updated_tree"); // Compute and store the hashes for each level, iterating from the penultimate level to the root level. + let empty_hash = self.path_hasher.hash_empty()?; while let (Some(start), Some(middle)) = (parent(start_index), parent(middle_index)) { // Compute the end index of the current level. let end = left_child(start); @@ -651,7 +687,12 @@ impl, PH: PathHash if let Some(middle_precompute) = parent(middle_precompute) { // Construct the children for the new indices in the current level. let tuples = (middle..middle_precompute) - .map(|i| (tree[left_child(i)], tree[right_child(i)])) + .map(|i| { + ( + tree.get(left_child(i)).copied().unwrap_or(empty_hash), + tree.get(right_child(i)).copied().unwrap_or(empty_hash), + ) + }) .collect::>(); // Process the indices that need to be computed for the current level. // If any level requires computing more than 100 nodes, borrow the tree for performance. @@ -687,7 +728,14 @@ impl, PH: PathHash } } else { // Construct the children for the new indices in the current level. - let tuples = (middle..end).map(|i| (tree[left_child(i)], tree[right_child(i)])).collect::>(); + let tuples = (middle..end) + .map(|i| { + ( + tree.get(left_child(i)).copied().unwrap_or(empty_hash), + tree.get(right_child(i)).copied().unwrap_or(empty_hash), + ) + }) + .collect::>(); // Process the indices that need to be computed for the current level. // If any level requires computing more than 100 nodes, borrow the tree for performance. match tuples.len() >= 100 { diff --git a/console/collections/src/merkle_tree/path/mod.rs b/console/collections/src/merkle_tree/path/mod.rs index b7dbcf47b8..d69e6066f9 100644 --- a/console/collections/src/merkle_tree/path/mod.rs +++ b/console/collections/src/merkle_tree/path/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/collections/src/merkle_tree/tests/append.rs b/console/collections/src/merkle_tree/tests/append.rs index 035d2c33ef..acb5230600 100644 --- a/console/collections/src/merkle_tree/tests/append.rs +++ b/console/collections/src/merkle_tree/tests/append.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use super::*; -use snarkvm_console_algorithms::{Poseidon, BHP1024, BHP512}; +use snarkvm_console_algorithms::{BHP512, BHP1024, Poseidon}; use snarkvm_console_types::prelude::Console; type CurrentEnvironment = Console; @@ -30,13 +31,12 @@ fn check_merkle_tree, PH: PathHash path_hasher: &PH, leaves: &[LH::Leaf], additional_leaves: &[LH::Leaf], + rng: &mut TestRng, ) -> Result<()> { // Construct the Merkle tree for the given leaves. let mut merkle_tree = MerkleTree::::new(leaf_hasher, path_hasher, leaves)?; assert_eq!(leaves.len(), merkle_tree.number_of_leaves); - let mut rng = TestRng::default(); - // Check each leaf in the Merkle tree. if !leaves.is_empty() { for (leaf_index, leaf) in leaves.iter().enumerate() { @@ -47,7 +47,7 @@ fn check_merkle_tree, PH: PathHash // Verify the Merkle proof **fails** on an invalid root. assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::zero(), leaf)); assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::one(), leaf)); - assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::rand(&mut rng), leaf)); + assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::rand(rng), leaf)); } } // If additional leaves are provided, check that the Merkle tree is consistent with them. @@ -63,7 +63,7 @@ fn check_merkle_tree, PH: PathHash // Verify the Merkle proof **fails** on an invalid root. assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::zero(), leaf)); assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::one(), leaf)); - assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::rand(&mut rng), leaf)); + assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::rand(rng), leaf)); } } Ok(()) @@ -158,7 +158,7 @@ fn check_merkle_tree_depth_3_padded Result<()> { &(0..num_additional_leaves) .map(|_| Field::::rand(rng).to_bits_le()) .collect::>>(), + rng, )?; } } @@ -439,6 +434,7 @@ fn test_merkle_tree_poseidon() -> Result<()> { &path_hasher, &(0..num_leaves).map(|_| vec![Uniform::rand(rng)]).collect::>(), &(0..num_additional_leaves).map(|_| vec![Uniform::rand(rng)]).collect::>(), + rng, )?; } } diff --git a/console/collections/src/merkle_tree/tests/mod.rs b/console/collections/src/merkle_tree/tests/mod.rs index 81e53307a8..f09bb19eba 100644 --- a/console/collections/src/merkle_tree/tests/mod.rs +++ b/console/collections/src/merkle_tree/tests/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/collections/src/merkle_tree/tests/remove.rs b/console/collections/src/merkle_tree/tests/remove.rs index f7f737437f..317c2b53cb 100644 --- a/console/collections/src/merkle_tree/tests/remove.rs +++ b/console/collections/src/merkle_tree/tests/remove.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use super::*; -use snarkvm_console_algorithms::{Poseidon, BHP1024, BHP512}; +use snarkvm_console_algorithms::{BHP512, BHP1024, Poseidon}; use snarkvm_console_types::prelude::Console; type CurrentEnvironment = Console; diff --git a/console/collections/src/merkle_tree/tests/update.rs b/console/collections/src/merkle_tree/tests/update.rs index 9538ffaf3f..7e82045862 100644 --- a/console/collections/src/merkle_tree/tests/update.rs +++ b/console/collections/src/merkle_tree/tests/update.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use super::*; -use snarkvm_console_algorithms::{Poseidon, BHP1024, BHP512}; +use snarkvm_console_algorithms::{BHP512, BHP1024, Poseidon}; use snarkvm_console_types::prelude::Console; use indexmap::IndexMap; @@ -32,13 +33,12 @@ fn check_merkle_tree, PH: PathHash path_hasher: &PH, leaves: &[LH::Leaf], updates: &[(usize, LH::Leaf)], + rng: &mut TestRng, ) -> Result<()> { // Construct the Merkle tree for the given leaves. let mut merkle_tree = MerkleTree::::new(leaf_hasher, path_hasher, leaves)?; assert_eq!(leaves.len(), merkle_tree.number_of_leaves); - let mut rng = TestRng::default(); - // Check each leaf in the Merkle tree. for (leaf_index, leaf) in leaves.iter().enumerate() { // Compute a Merkle proof for the leaf. @@ -48,7 +48,7 @@ fn check_merkle_tree, PH: PathHash // Verify the Merkle proof **fails** on an invalid root. assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::zero(), leaf)); assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::one(), leaf)); - assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::rand(&mut rng), leaf)); + assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::rand(rng), leaf)); } // Update the leaves of the Merkle tree. @@ -65,7 +65,7 @@ fn check_merkle_tree, PH: PathHash // Verify the Merkle proof **fails** on an invalid root. assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::zero(), leaf)); assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::one(), leaf)); - assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::rand(&mut rng), leaf)); + assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::rand(rng), leaf)); } Ok(()) } @@ -236,6 +236,7 @@ fn test_merkle_tree_bhp() -> Result<()> { &(0..num_updates) .map(|i| ((i % num_leaves) as usize, Field::::rand(rng).to_bits_le())) .collect::)>>(), + rng, )?; } } @@ -275,6 +276,7 @@ fn test_merkle_tree_poseidon() -> Result<()> { &(0..num_additional_leaves) .map(|i| ((i % num_leaves) as usize, vec![Uniform::rand(rng)])) .collect::>(), + rng, )?; } } diff --git a/console/collections/src/merkle_tree/tests/update_many.rs b/console/collections/src/merkle_tree/tests/update_many.rs index 9519a9a71b..9890777b26 100644 --- a/console/collections/src/merkle_tree/tests/update_many.rs +++ b/console/collections/src/merkle_tree/tests/update_many.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use super::*; -use snarkvm_console_algorithms::{Poseidon, BHP1024, BHP512}; +use snarkvm_console_algorithms::{BHP512, BHP1024, Poseidon}; use snarkvm_console_types::prelude::Console; use indexmap::IndexMap; @@ -32,13 +33,12 @@ fn check_merkle_tree, PH: PathHash path_hasher: &PH, leaves: &[LH::Leaf], updates: &BTreeMap, + rng: &mut TestRng, ) -> Result<()> { // Construct the Merkle tree for the given leaves. let mut merkle_tree = MerkleTree::::new(leaf_hasher, path_hasher, leaves)?; assert_eq!(leaves.len(), merkle_tree.number_of_leaves); - let mut rng = TestRng::default(); - // Check each leaf in the Merkle tree. for (leaf_index, leaf) in leaves.iter().enumerate() { // Compute a Merkle proof for the leaf. @@ -48,7 +48,7 @@ fn check_merkle_tree, PH: PathHash // Verify the Merkle proof **fails** on an invalid root. assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::zero(), leaf)); assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::one(), leaf)); - assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::rand(&mut rng), leaf)); + assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::rand(rng), leaf)); } // If additional leaves are provided, check that the Merkle tree is consistent with them. @@ -64,7 +64,7 @@ fn check_merkle_tree, PH: PathHash // Verify the Merkle proof **fails** on an invalid root. assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::zero(), leaf)); assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::one(), leaf)); - assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::rand(&mut rng), leaf)); + assert!(!proof.verify(leaf_hasher, path_hasher, &PH::Hash::rand(rng), leaf)); } } Ok(()) @@ -235,6 +235,7 @@ fn test_merkle_tree_bhp() -> Result<()> { .rev() .map(|i| ((i % num_leaves) as usize, Field::::rand(rng).to_bits_le())) .collect::>>(), + rng, )?; } } @@ -275,6 +276,7 @@ fn test_merkle_tree_poseidon() -> Result<()> { .rev() .map(|i| ((i % num_leaves) as usize, vec![Uniform::rand(rng)])) .collect::>(), + rng, )?; } } diff --git a/console/network/Cargo.toml b/console/network/Cargo.toml index 5ea82ad718..34f970c636 100644 --- a/console/network/Cargo.toml +++ b/console/network/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "snarkvm-console-network" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Network console library for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" @@ -12,48 +14,50 @@ wasm = [ "snarkvm-algorithms/polycommit_wasm", "snarkvm-parameters/wasm" ] +test = [ ] +test_targets = [ ] [dependencies.snarkvm-algorithms] path = "../../algorithms" -version = "=0.16.19" +version = "=1.1.0" default-features = false features = [ "snark" ] [dependencies.snarkvm-console-algorithms] path = "../algorithms" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-collections] path = "../collections" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-network-environment] path = "./environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types] path = "../types" -version = "=0.16.19" +version = "=1.1.0" default-features = false features = [ "field", "group", "scalar" ] [dependencies.snarkvm-curves] path = "../../curves" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-fields] path = "../../fields" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-parameters] path = "../../parameters" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-utilities] path = "../../utilities" -version = "=0.16.19" +version = "=1.1.0" [dependencies.anyhow] version = "1.0.73" diff --git a/console/network/environment/Cargo.toml b/console/network/environment/Cargo.toml index 63b459700f..f61c7dccc7 100644 --- a/console/network/environment/Cargo.toml +++ b/console/network/environment/Cargo.toml @@ -1,24 +1,26 @@ [package] name = "snarkvm-console-network-environment" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Environment console library for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.snarkvm-curves] path = "../../../curves" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-fields] path = "../../../fields" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-utilities] path = "../../../utilities" -version = "=0.16.19" +version = "=1.1.0" [dependencies.anyhow] version = "1.0.73" diff --git a/console/network/environment/src/environment.rs b/console/network/environment/src/environment.rs index a5b87438a0..d675b6c71f 100644 --- a/console/network/environment/src/environment.rs +++ b/console/network/environment/src/environment.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,13 +15,13 @@ use crate::prelude::{Deserialize, DeserializeOwned, Serialize}; use snarkvm_curves::{ - bls12_377::Bls12_377, - edwards_bls12::{EdwardsAffine, EdwardsParameters}, AffineCurve, MontgomeryParameters, PairingEngine, ProjectiveCurve, TwistedEdwardsParameters, + bls12_377::Bls12_377, + edwards_bls12::{EdwardsAffine, EdwardsParameters}, }; use snarkvm_fields::{PrimeField, SquareRootField}; use snarkvm_utilities::BigInteger; diff --git a/console/network/environment/src/helpers/mod.rs b/console/network/environment/src/helpers/mod.rs index 40505277ec..ad4cdb2ae7 100644 --- a/console/network/environment/src/helpers/mod.rs +++ b/console/network/environment/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/network/environment/src/helpers/or_halt.rs b/console/network/environment/src/helpers/or_halt.rs index 7312e977c0..a241b4b42b 100644 --- a/console/network/environment/src/helpers/or_halt.rs +++ b/console/network/environment/src/helpers/or_halt.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/network/environment/src/helpers/sanitizer.rs b/console/network/environment/src/helpers/sanitizer.rs index bceed0e0b1..8892ef34fd 100644 --- a/console/network/environment/src/helpers/sanitizer.rs +++ b/console/network/environment/src/helpers/sanitizer.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{string_parser::is_char_supported, ParserResult}; +use crate::{ParserResult, string_parser::is_char_supported}; use nom::{ branch::alt, @@ -116,12 +117,33 @@ impl Sanitizer { /// /// Discard any leading newline. fn str_till_eol(string: &str) -> ParserResult<&str> { - map( - recognize(Self::till(alt((value((), tag("\\\n")), value((), Sanitizer::parse_safe_char))), Self::eol)), - |i| { - if i.as_bytes().last() == Some(&b'\n') { &i[0..i.len() - 1] } else { i } - }, - )(string) + // A heuristic approach is applied here in order to avoid + // costly parsing operations in the most common scenarios. + if let Some((before, after)) = string.split_once('\n') { + let is_multiline = before.ends_with('\\'); + + if !is_multiline { + let contains_unsafe_chars = !before.chars().all(is_char_supported); + + if !contains_unsafe_chars { + Ok((after, before)) + } else { + recognize(Self::till(value((), Sanitizer::parse_safe_char), Self::eol))(before) + } + } else { + map( + recognize(Self::till( + alt((value((), tag("\\\n")), value((), Sanitizer::parse_safe_char))), + Self::eol, + )), + |i| { + if i.as_bytes().last() == Some(&b'\n') { &i[0..i.len() - 1] } else { i } + }, + )(string) + } + } else { + Ok((string, "")) + } } /// Parse a string until `*/` is encountered. diff --git a/console/network/environment/src/helpers/variable_length.rs b/console/network/environment/src/helpers/variable_length.rs index 2a8115e421..63d94b9aac 100644 --- a/console/network/environment/src/helpers/variable_length.rs +++ b/console/network/environment/src/helpers/variable_length.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,9 +14,9 @@ // limitations under the License. use snarkvm_utilities::{ + FromBytes, error, io::{Read, Result as IoResult}, - FromBytes, }; /// Returns the variable length integer of the given value. diff --git a/console/network/environment/src/lib.rs b/console/network/environment/src/lib.rs index c7c54316ac..bd14120900 100644 --- a/console/network/environment/src/lib.rs +++ b/console/network/environment/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -29,6 +30,7 @@ pub mod prelude { environment::*, helpers::*, traits::{ + ToBits, algorithms::*, arithmetic::*, bitwise::*, @@ -53,33 +55,34 @@ pub mod prelude { *, }, visibility::*, - ToBits, }, }; pub use snarkvm_curves::{AffineCurve, MontgomeryParameters, ProjectiveCurve, TwistedEdwardsParameters}; pub use snarkvm_fields::{Field as _, PrimeField as _, SquareRootField as _, Zero as _}; pub use snarkvm_utilities::{ + DeserializeExt, + FromBits as _, + FromBytes, + FromBytesDeserializer, + LimitedWriter, + TestRng, + ToBits as _, + ToBytes, + ToBytesSerializer, + Uniform, cfg_chunks, cfg_find, cfg_find_map, cfg_into_iter, cfg_iter, cfg_iter_mut, + cfg_keys, cfg_reduce, cfg_values, error, has_duplicates, io::{Read, Result as IoResult, Write}, - DeserializeExt, - FromBits as _, - FromBytes, - FromBytesDeserializer, - TestRng, - ToBits as _, - ToBytes, - ToBytesSerializer, - Uniform, }; pub use core::{ @@ -116,30 +119,32 @@ pub mod prelude { str::{self, FromStr}, }; - pub use anyhow::{anyhow, bail, ensure, Error, Result}; + pub use anyhow::{Error, Result, anyhow, bail, ensure}; pub use bech32::{self, FromBase32, ToBase32}; pub use itertools::Itertools; pub use nom::{ + Err, branch::alt, bytes::{complete::tag, streaming::take}, character::complete::{alpha1, alphanumeric1, char, one_of}, combinator::{complete, fail, map, map_res, opt, recognize}, + error::{ErrorKind, make_error}, multi::{count, many0, many0_count, many1, separated_list0, separated_list1}, sequence::{pair, terminated}, }; pub use num_traits::{AsPrimitive, One, Pow, Zero}; pub use rand::{ - distributions::{Alphanumeric, Distribution, Standard}, CryptoRng, Rng, + distributions::{Alphanumeric, Distribution, Standard}, }; pub use serde::{ - de, - de::{DeserializeOwned, SeqAccess, Visitor}, - ser::{self, SerializeSeq, SerializeStruct}, Deserialize, Deserializer, Serialize, Serializer, + de, + de::{DeserializeOwned, EnumAccess, MapAccess, SeqAccess, VariantAccess, Visitor}, + ser::{self, SerializeSeq, SerializeStruct}, }; } diff --git a/console/network/environment/src/traits/algorithms.rs b/console/network/environment/src/traits/algorithms.rs index 378f78d325..d486cd8c78 100644 --- a/console/network/environment/src/traits/algorithms.rs +++ b/console/network/environment/src/traits/algorithms.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/network/environment/src/traits/arithmetic.rs b/console/network/environment/src/traits/arithmetic.rs index d3f516994c..677efe5bae 100644 --- a/console/network/environment/src/traits/arithmetic.rs +++ b/console/network/environment/src/traits/arithmetic.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/network/environment/src/traits/bitwise.rs b/console/network/environment/src/traits/bitwise.rs index c21fb9fbdd..7aaac6644b 100644 --- a/console/network/environment/src/traits/bitwise.rs +++ b/console/network/environment/src/traits/bitwise.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -66,3 +67,13 @@ pub trait Ternary { where Self: Sized; } + +impl Ternary for Box { + type Boolean = T::Boolean; + type Output = Box; + + /// Returns `first` if `condition` is `true`, otherwise returns `second`. + fn ternary(condition: &Self::Boolean, first: &Self, second: &Self) -> Self::Output { + Box::new(T::ternary(condition, first, second)) + } +} diff --git a/console/network/environment/src/traits/from_bits.rs b/console/network/environment/src/traits/from_bits.rs index eab07e64f9..1fbbd94846 100644 --- a/console/network/environment/src/traits/from_bits.rs +++ b/console/network/environment/src/traits/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/network/environment/src/traits/from_field.rs b/console/network/environment/src/traits/from_field.rs index 6d3b3bd072..aaf537c40f 100644 --- a/console/network/environment/src/traits/from_field.rs +++ b/console/network/environment/src/traits/from_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/network/environment/src/traits/mod.rs b/console/network/environment/src/traits/mod.rs index aaeb41611f..125b4000c7 100644 --- a/console/network/environment/src/traits/mod.rs +++ b/console/network/environment/src/traits/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub use snarkvm_utilities::{to_bits_le, ToBits}; +pub use snarkvm_utilities::{ToBits, to_bits_le}; pub mod algorithms; pub use algorithms::*; diff --git a/console/network/environment/src/traits/parse.rs b/console/network/environment/src/traits/parse.rs index 7c8dbd6f7c..b5931b3d4a 100644 --- a/console/network/environment/src/traits/parse.rs +++ b/console/network/environment/src/traits/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,9 +14,9 @@ // limitations under the License. use nom::{ - error::{convert_error, VerboseError}, Err as NomErr, IResult, + error::{VerboseError, convert_error}, }; /// The `nom`-compatible parser return type. diff --git a/console/network/environment/src/traits/parse_string.rs b/console/network/environment/src/traits/parse_string.rs index 64df8531a1..854f9731fa 100644 --- a/console/network/environment/src/traits/parse_string.rs +++ b/console/network/environment/src/traits/parse_string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,18 +15,19 @@ /// From https://github.com/Geal/nom/blob/main/examples/string.rs pub mod string_parser { - //! This example shows an example of how to parse an escaped string. The - //! rules for the string are similar to JSON and rust. A string is: - //! - //! - Enclosed by double quotes - //! - Can contain any raw unescaped code point besides \ and " - //! - Matches the following escape sequences: \b, \f, \n, \r, \t, \", \\, \/ - //! - Matches code points like Rust: \u{XXXX}, where XXXX can be up to 6 - //! hex characters - //! - an escape followed by whitespace consumes all whitespace between the - //! escape and the next non-whitespace character - + /// This example shows an example of how to parse an escaped string. The + /// rules for the string are similar to JSON and rust. A string is: + /// + /// - Enclosed by double quotes + /// - Can contain any raw unescaped code point besides \ and " + /// - Matches the following escape sequences: \b, \f, \n, \r, \t, \", \\, \/ + /// - Matches code points like Rust: \u{XXXX}, where XXXX can be up to 6 + /// hex characters + /// - an escape followed by whitespace consumes all whitespace between the + /// escape and the next non-whitespace character use nom::{ + Err::Error, + IResult, branch::alt, bytes::streaming::{is_not, take_while_m_n}, character::streaming::{char, multispace1}, @@ -33,8 +35,6 @@ pub mod string_parser { error::{ErrorKind, FromExternalError, ParseError}, multi::fold_many0, sequence::{delimited, preceded}, - Err::Error, - IResult, }; /// Checks for supported code points. diff --git a/console/network/environment/src/traits/to_field.rs b/console/network/environment/src/traits/to_field.rs index 40c39c379b..324114117c 100644 --- a/console/network/environment/src/traits/to_field.rs +++ b/console/network/environment/src/traits/to_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/network/environment/src/traits/type_name.rs b/console/network/environment/src/traits/type_name.rs index 7e25a89613..d9ef32ff57 100644 --- a/console/network/environment/src/traits/type_name.rs +++ b/console/network/environment/src/traits/type_name.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/network/environment/src/traits/types.rs b/console/network/environment/src/traits/types.rs index a57bc0aa84..273304eed0 100644 --- a/console/network/environment/src/traits/types.rs +++ b/console/network/environment/src/traits/types.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/network/environment/src/traits/visibility.rs b/console/network/environment/src/traits/visibility.rs index 24f9667c0b..bd4745ac8c 100644 --- a/console/network/environment/src/traits/visibility.rs +++ b/console/network/environment/src/traits/visibility.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/network/src/canary_v0.rs b/console/network/src/canary_v0.rs new file mode 100644 index 0000000000..5aae6930ef --- /dev/null +++ b/console/network/src/canary_v0.rs @@ -0,0 +1,513 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; +use crate::TRANSACTION_PREFIX; +use snarkvm_console_algorithms::{ + BHP256, + BHP512, + BHP768, + BHP1024, + Blake2Xs, + Keccak256, + Keccak384, + Keccak512, + Pedersen64, + Pedersen128, + Poseidon2, + Poseidon4, + Poseidon8, + Sha3_256, + Sha3_384, + Sha3_512, +}; + +lazy_static! { + /// The group bases for the Aleo signature and encryption schemes. + static ref GENERATOR_G: Vec> = CanaryV0::new_bases("AleoAccountEncryptionAndSignatureScheme0"); + + /// The Varuna sponge parameters. + static ref VARUNA_FS_PARAMETERS: FiatShamirParameters = FiatShamir::::sample_parameters(); + + /// The encryption domain as a constant field element. + static ref ENCRYPTION_DOMAIN: Field = Field::::new_domain_separator("AleoSymmetricEncryption0"); + /// The graph key domain as a constant field element. + static ref GRAPH_KEY_DOMAIN: Field = Field::::new_domain_separator("AleoGraphKey0"); + /// The serial number domain as a constant field element. + static ref SERIAL_NUMBER_DOMAIN: Field = Field::::new_domain_separator("AleoSerialNumber0"); + + /// The BHP hash function, which can take an input of up to 256 bits. + pub static ref CANARY_BHP_256: BHP256 = BHP256::::setup("AleoBHP256").expect("Failed to setup BHP256"); + /// The BHP hash function, which can take an input of up to 512 bits. + pub static ref CANARY_BHP_512: BHP512 = BHP512::::setup("AleoBHP512").expect("Failed to setup BHP512"); + /// The BHP hash function, which can take an input of up to 768 bits. + pub static ref CANARY_BHP_768: BHP768 = BHP768::::setup("AleoBHP768").expect("Failed to setup BHP768"); + /// The BHP hash function, which can take an input of up to 1024 bits. + pub static ref CANARY_BHP_1024: BHP1024 = BHP1024::::setup("AleoBHP1024").expect("Failed to setup BHP1024"); + + /// The Pedersen hash function, which can take an input of up to 64 bits. + pub static ref CANARY_PEDERSEN_64: Pedersen64 = Pedersen64::::setup("AleoPedersen64"); + /// The Pedersen hash function, which can take an input of up to 128 bits. + pub static ref CANARY_PEDERSEN_128: Pedersen128 = Pedersen128::::setup("AleoPedersen128"); + + /// The Poseidon hash function, using a rate of 2. + pub static ref CANARY_POSEIDON_2: Poseidon2 = Poseidon2::::setup("AleoPoseidon2").expect("Failed to setup Poseidon2"); + /// The Poseidon hash function, using a rate of 4. + pub static ref CANARY_POSEIDON_4: Poseidon4 = Poseidon4::::setup("AleoPoseidon4").expect("Failed to setup Poseidon4"); + /// The Poseidon hash function, using a rate of 8. + pub static ref CANARY_POSEIDON_8: Poseidon8 = Poseidon8::::setup("AleoPoseidon8").expect("Failed to setup Poseidon8"); + + pub static ref CANARY_CREDITS_PROVING_KEYS: IndexMap>> = { + let mut map = IndexMap::new(); + snarkvm_parameters::insert_canary_credit_keys!(map, VarunaProvingKey, Prover); + map + }; + pub static ref CANARY_CREDITS_VERIFYING_KEYS: IndexMap>> = { + let mut map = IndexMap::new(); + snarkvm_parameters::insert_canary_credit_keys!(map, VarunaVerifyingKey, Verifier); + map + }; +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct CanaryV0; + +impl CanaryV0 { + /// Initializes a new instance of group bases from a given input domain message. + fn new_bases(message: &str) -> Vec> { + // Hash the given message to a point on the curve, to initialize the starting base. + let (base, _, _) = Blake2Xs::hash_to_curve::<::Affine>(message); + + // Compute the bases up to the size of the scalar field (in bits). + let mut g = Group::::new(base); + let mut g_bases = Vec::with_capacity(Scalar::::size_in_bits()); + for _ in 0..Scalar::::size_in_bits() { + g_bases.push(g); + g = g.double(); + } + g_bases + } +} + +impl Environment for CanaryV0 { + type Affine = ::Affine; + type BigInteger = ::BigInteger; + type Field = ::Field; + type PairingCurve = ::PairingCurve; + type Projective = ::Projective; + type Scalar = ::Scalar; + + /// The coefficient `A` of the twisted Edwards curve. + const EDWARDS_A: Self::Field = Console::EDWARDS_A; + /// The coefficient `D` of the twisted Edwards curve. + const EDWARDS_D: Self::Field = Console::EDWARDS_D; + /// The coefficient `A` of the Montgomery curve. + const MONTGOMERY_A: Self::Field = Console::MONTGOMERY_A; + /// The coefficient `B` of the Montgomery curve. + const MONTGOMERY_B: Self::Field = Console::MONTGOMERY_B; +} + +impl Network for CanaryV0 { + /// The block hash type. + type BlockHash = AleoID, { hrp2!("ab") }>; + /// The ratification ID type. + type RatificationID = AleoID, { hrp2!("ar") }>; + /// The state root type. + type StateRoot = AleoID, { hrp2!("sr") }>; + /// The transaction ID type. + type TransactionID = AleoID, { hrp2!(TRANSACTION_PREFIX) }>; + /// The transition ID type. + type TransitionID = AleoID, { hrp2!("au") }>; + /// The transmission checksum type. + type TransmissionChecksum = u128; + + /// The block height from which consensus V2 rules apply. + #[cfg(not(any(test, feature = "test")))] + const CONSENSUS_V2_HEIGHT: u32 = 2_900_000; + // TODO (raychu86): Update this value based on the desired canary height. + /// The block height from which consensus V2 rules apply. + #[cfg(any(test, feature = "test"))] + const CONSENSUS_V2_HEIGHT: u32 = 0; + /// The network edition. + const EDITION: u16 = 0; + /// The genesis block coinbase target. + #[cfg(not(feature = "test_targets"))] + const GENESIS_COINBASE_TARGET: u64 = (1u64 << 29).saturating_sub(1); + #[cfg(feature = "test_targets")] + const GENESIS_COINBASE_TARGET: u64 = (1u64 << 5).saturating_sub(1); + /// The genesis block proof target. + #[cfg(not(feature = "test_targets"))] + const GENESIS_PROOF_TARGET: u64 = 1u64 << 27; + #[cfg(feature = "test_targets")] + const GENESIS_PROOF_TARGET: u64 = 1u64 << 3; + /// The fixed timestamp of the genesis block. + const GENESIS_TIMESTAMP: i64 = 1715776496 /* 2024-05-15 12:34:56 UTC */; + /// The network ID. + const ID: u16 = 2; + /// The function name for the inclusion circuit. + const INCLUSION_FUNCTION_NAME: &'static str = MainnetV0::INCLUSION_FUNCTION_NAME; + /// The maximum number of certificates in a batch. + const MAX_CERTIFICATES: u16 = 100; + /// The network name. + const NAME: &'static str = "Aleo Canary (v0)"; + + /// Returns the genesis block bytes. + fn genesis_bytes() -> &'static [u8] { + snarkvm_parameters::canary::GenesisBytes::load_bytes() + } + + /// Returns the restrictions list as a JSON-compatible string. + fn restrictions_list_as_str() -> &'static str { + snarkvm_parameters::canary::RESTRICTIONS_LIST + } + + /// Returns the proving key for the given function name in `credits.aleo`. + fn get_credits_proving_key(function_name: String) -> Result<&'static Arc>> { + CANARY_CREDITS_PROVING_KEYS + .get(&function_name) + .ok_or_else(|| anyhow!("Proving key for credits.aleo/{function_name}' not found")) + } + + /// Returns the verifying key for the given function name in `credits.aleo`. + fn get_credits_verifying_key(function_name: String) -> Result<&'static Arc>> { + CANARY_CREDITS_VERIFYING_KEYS + .get(&function_name) + .ok_or_else(|| anyhow!("Verifying key for credits.aleo/{function_name}' not found")) + } + + /// Returns the `proving key` for the inclusion circuit. + fn inclusion_proving_key() -> &'static Arc> { + static INSTANCE: OnceCell>> = OnceCell::new(); + INSTANCE.get_or_init(|| { + // Skipping the first byte, which is the encoded version. + Arc::new( + CircuitProvingKey::from_bytes_le(&snarkvm_parameters::canary::INCLUSION_PROVING_KEY[1..]) + .expect("Failed to load inclusion proving key."), + ) + }) + } + + /// Returns the `verifying key` for the inclusion circuit. + fn inclusion_verifying_key() -> &'static Arc> { + static INSTANCE: OnceCell>> = OnceCell::new(); + INSTANCE.get_or_init(|| { + // Skipping the first byte, which is the encoded version. + Arc::new( + CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::canary::INCLUSION_VERIFYING_KEY[1..]) + .expect("Failed to load inclusion verifying key."), + ) + }) + } + + /// Returns the powers of `G`. + fn g_powers() -> &'static Vec> { + &GENERATOR_G + } + + /// Returns the scalar multiplication on the generator `G`. + fn g_scalar_multiply(scalar: &Scalar) -> Group { + GENERATOR_G + .iter() + .zip_eq(&scalar.to_bits_le()) + .filter_map(|(base, bit)| match bit { + true => Some(base), + false => None, + }) + .sum() + } + + /// Returns the Varuna universal prover. + fn varuna_universal_prover() -> &'static UniversalProver { + MainnetV0::varuna_universal_prover() + } + + /// Returns the Varuna universal verifier. + fn varuna_universal_verifier() -> &'static UniversalVerifier { + MainnetV0::varuna_universal_verifier() + } + + /// Returns the sponge parameters used for the sponge in the Varuna SNARK. + fn varuna_fs_parameters() -> &'static FiatShamirParameters { + &VARUNA_FS_PARAMETERS + } + + /// Returns the encryption domain as a constant field element. + fn encryption_domain() -> Field { + *ENCRYPTION_DOMAIN + } + + /// Returns the graph key domain as a constant field element. + fn graph_key_domain() -> Field { + *GRAPH_KEY_DOMAIN + } + + /// Returns the serial number domain as a constant field element. + fn serial_number_domain() -> Field { + *SERIAL_NUMBER_DOMAIN + } + + /// Returns a BHP commitment with an input hasher of 256-bits and randomizer. + fn commit_bhp256(input: &[bool], randomizer: &Scalar) -> Result> { + CANARY_BHP_256.commit(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 512-bits and randomizer. + fn commit_bhp512(input: &[bool], randomizer: &Scalar) -> Result> { + CANARY_BHP_512.commit(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 768-bits and randomizer. + fn commit_bhp768(input: &[bool], randomizer: &Scalar) -> Result> { + CANARY_BHP_768.commit(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 1024-bits and randomizer. + fn commit_bhp1024(input: &[bool], randomizer: &Scalar) -> Result> { + CANARY_BHP_1024.commit(input, randomizer) + } + + /// Returns a Pedersen commitment for the given (up to) 64-bit input and randomizer. + fn commit_ped64(input: &[bool], randomizer: &Scalar) -> Result> { + CANARY_PEDERSEN_64.commit(input, randomizer) + } + + /// Returns a Pedersen commitment for the given (up to) 128-bit input and randomizer. + fn commit_ped128(input: &[bool], randomizer: &Scalar) -> Result> { + CANARY_PEDERSEN_128.commit(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 256-bits and randomizer. + fn commit_to_group_bhp256(input: &[bool], randomizer: &Scalar) -> Result> { + CANARY_BHP_256.commit_uncompressed(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 512-bits and randomizer. + fn commit_to_group_bhp512(input: &[bool], randomizer: &Scalar) -> Result> { + CANARY_BHP_512.commit_uncompressed(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 768-bits and randomizer. + fn commit_to_group_bhp768(input: &[bool], randomizer: &Scalar) -> Result> { + CANARY_BHP_768.commit_uncompressed(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 1024-bits and randomizer. + fn commit_to_group_bhp1024(input: &[bool], randomizer: &Scalar) -> Result> { + CANARY_BHP_1024.commit_uncompressed(input, randomizer) + } + + /// Returns a Pedersen commitment for the given (up to) 64-bit input and randomizer. + fn commit_to_group_ped64(input: &[bool], randomizer: &Scalar) -> Result> { + CANARY_PEDERSEN_64.commit_uncompressed(input, randomizer) + } + + /// Returns a Pedersen commitment for the given (up to) 128-bit input and randomizer. + fn commit_to_group_ped128(input: &[bool], randomizer: &Scalar) -> Result> { + CANARY_PEDERSEN_128.commit_uncompressed(input, randomizer) + } + + /// Returns the BHP hash with an input hasher of 256-bits. + fn hash_bhp256(input: &[bool]) -> Result> { + CANARY_BHP_256.hash(input) + } + + /// Returns the BHP hash with an input hasher of 512-bits. + fn hash_bhp512(input: &[bool]) -> Result> { + CANARY_BHP_512.hash(input) + } + + /// Returns the BHP hash with an input hasher of 768-bits. + fn hash_bhp768(input: &[bool]) -> Result> { + CANARY_BHP_768.hash(input) + } + + /// Returns the BHP hash with an input hasher of 1024-bits. + fn hash_bhp1024(input: &[bool]) -> Result> { + CANARY_BHP_1024.hash(input) + } + + /// Returns the Keccak hash with a 256-bit output. + fn hash_keccak256(input: &[bool]) -> Result> { + Keccak256::default().hash(input) + } + + /// Returns the Keccak hash with a 384-bit output. + fn hash_keccak384(input: &[bool]) -> Result> { + Keccak384::default().hash(input) + } + + /// Returns the Keccak hash with a 512-bit output. + fn hash_keccak512(input: &[bool]) -> Result> { + Keccak512::default().hash(input) + } + + /// Returns the Pedersen hash for a given (up to) 64-bit input. + fn hash_ped64(input: &[bool]) -> Result> { + CANARY_PEDERSEN_64.hash(input) + } + + /// Returns the Pedersen hash for a given (up to) 128-bit input. + fn hash_ped128(input: &[bool]) -> Result> { + CANARY_PEDERSEN_128.hash(input) + } + + /// Returns the Poseidon hash with an input rate of 2. + fn hash_psd2(input: &[Field]) -> Result> { + CANARY_POSEIDON_2.hash(input) + } + + /// Returns the Poseidon hash with an input rate of 4. + fn hash_psd4(input: &[Field]) -> Result> { + CANARY_POSEIDON_4.hash(input) + } + + /// Returns the Poseidon hash with an input rate of 8. + fn hash_psd8(input: &[Field]) -> Result> { + CANARY_POSEIDON_8.hash(input) + } + + /// Returns the SHA-3 hash with a 256-bit output. + fn hash_sha3_256(input: &[bool]) -> Result> { + Sha3_256::default().hash(input) + } + + /// Returns the SHA-3 hash with a 384-bit output. + fn hash_sha3_384(input: &[bool]) -> Result> { + Sha3_384::default().hash(input) + } + + /// Returns the SHA-3 hash with a 512-bit output. + fn hash_sha3_512(input: &[bool]) -> Result> { + Sha3_512::default().hash(input) + } + + /// Returns the extended Poseidon hash with an input rate of 2. + fn hash_many_psd2(input: &[Field], num_outputs: u16) -> Vec> { + CANARY_POSEIDON_2.hash_many(input, num_outputs) + } + + /// Returns the extended Poseidon hash with an input rate of 4. + fn hash_many_psd4(input: &[Field], num_outputs: u16) -> Vec> { + CANARY_POSEIDON_4.hash_many(input, num_outputs) + } + + /// Returns the extended Poseidon hash with an input rate of 8. + fn hash_many_psd8(input: &[Field], num_outputs: u16) -> Vec> { + CANARY_POSEIDON_8.hash_many(input, num_outputs) + } + + /// Returns the BHP hash with an input hasher of 256-bits. + fn hash_to_group_bhp256(input: &[bool]) -> Result> { + CANARY_BHP_256.hash_uncompressed(input) + } + + /// Returns the BHP hash with an input hasher of 512-bits. + fn hash_to_group_bhp512(input: &[bool]) -> Result> { + CANARY_BHP_512.hash_uncompressed(input) + } + + /// Returns the BHP hash with an input hasher of 768-bits. + fn hash_to_group_bhp768(input: &[bool]) -> Result> { + CANARY_BHP_768.hash_uncompressed(input) + } + + /// Returns the BHP hash with an input hasher of 1024-bits. + fn hash_to_group_bhp1024(input: &[bool]) -> Result> { + CANARY_BHP_1024.hash_uncompressed(input) + } + + /// Returns the Pedersen hash for a given (up to) 64-bit input. + fn hash_to_group_ped64(input: &[bool]) -> Result> { + CANARY_PEDERSEN_64.hash_uncompressed(input) + } + + /// Returns the Pedersen hash for a given (up to) 128-bit input. + fn hash_to_group_ped128(input: &[bool]) -> Result> { + CANARY_PEDERSEN_128.hash_uncompressed(input) + } + + /// Returns the Poseidon hash with an input rate of 2 on the affine curve. + fn hash_to_group_psd2(input: &[Field]) -> Result> { + CANARY_POSEIDON_2.hash_to_group(input) + } + + /// Returns the Poseidon hash with an input rate of 4 on the affine curve. + fn hash_to_group_psd4(input: &[Field]) -> Result> { + CANARY_POSEIDON_4.hash_to_group(input) + } + + /// Returns the Poseidon hash with an input rate of 8 on the affine curve. + fn hash_to_group_psd8(input: &[Field]) -> Result> { + CANARY_POSEIDON_8.hash_to_group(input) + } + + /// Returns the Poseidon hash with an input rate of 2 on the scalar field. + fn hash_to_scalar_psd2(input: &[Field]) -> Result> { + CANARY_POSEIDON_2.hash_to_scalar(input) + } + + /// Returns the Poseidon hash with an input rate of 4 on the scalar field. + fn hash_to_scalar_psd4(input: &[Field]) -> Result> { + CANARY_POSEIDON_4.hash_to_scalar(input) + } + + /// Returns the Poseidon hash with an input rate of 8 on the scalar field. + fn hash_to_scalar_psd8(input: &[Field]) -> Result> { + CANARY_POSEIDON_8.hash_to_scalar(input) + } + + /// Returns a Merkle tree with a BHP leaf hasher of 1024-bits and a BHP path hasher of 512-bits. + fn merkle_tree_bhp(leaves: &[Vec]) -> Result> { + MerkleTree::new(&*CANARY_BHP_1024, &*CANARY_BHP_512, leaves) + } + + /// Returns a Merkle tree with a Poseidon leaf hasher with input rate of 4 and a Poseidon path hasher with input rate of 2. + fn merkle_tree_psd(leaves: &[Vec>]) -> Result> { + MerkleTree::new(&*CANARY_POSEIDON_4, &*CANARY_POSEIDON_2, leaves) + } + + /// Returns `true` if the given Merkle path is valid for the given root and leaf. + fn verify_merkle_path_bhp( + path: &MerklePath, + root: &Field, + leaf: &Vec, + ) -> bool { + path.verify(&*CANARY_BHP_1024, &*CANARY_BHP_512, root, leaf) + } + + /// Returns `true` if the given Merkle path is valid for the given root and leaf. + fn verify_merkle_path_psd( + path: &MerklePath, + root: &Field, + leaf: &Vec>, + ) -> bool { + path.verify(&*CANARY_POSEIDON_4, &*CANARY_POSEIDON_2, root, leaf) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + type CurrentNetwork = CanaryV0; + + #[test] + fn test_g_scalar_multiply() { + // Compute G^r. + let scalar = Scalar::rand(&mut TestRng::default()); + let group = CurrentNetwork::g_scalar_multiply(&scalar); + assert_eq!(group, CurrentNetwork::g_powers()[0] * scalar); + } +} diff --git a/console/network/src/helpers/id.rs b/console/network/src/helpers/id.rs index 77d3ae6056..a7d20b5e3b 100644 --- a/console/network/src/helpers/id.rs +++ b/console/network/src/helpers/id.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,7 +17,7 @@ use crate::prelude::*; use anyhow::Result; use bech32::{self, FromBase32, ToBase32}; -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; use std::borrow::Borrow; pub trait Bech32ID: diff --git a/console/network/src/helpers/mod.rs b/console/network/src/helpers/mod.rs index bd239df4d4..5e5f6124f3 100644 --- a/console/network/src/helpers/mod.rs +++ b/console/network/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/network/src/helpers/object.rs b/console/network/src/helpers/object.rs index fbffb39e35..2771858872 100644 --- a/console/network/src/helpers/object.rs +++ b/console/network/src/helpers/object.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,7 +17,7 @@ use crate::prelude::*; use anyhow::Result; use bech32::{self, FromBase32, ToBase32}; -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; use std::borrow::Borrow; pub trait Bech32Object: diff --git a/console/network/src/lib.rs b/console/network/src/lib.rs index 717946cba2..8a627bafed 100644 --- a/console/network/src/lib.rs +++ b/console/network/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -25,21 +26,27 @@ pub use snarkvm_console_network_environment::*; mod helpers; pub use helpers::*; -mod testnet3; -pub use testnet3::*; +mod canary_v0; +pub use canary_v0::*; + +mod mainnet_v0; +pub use mainnet_v0::*; + +mod testnet_v0; +pub use testnet_v0::*; pub mod prelude { - pub use crate::{environment::prelude::*, Network}; + pub use crate::{Network, environment::prelude::*}; } use crate::environment::prelude::*; use snarkvm_algorithms::{ + AlgebraicSponge, crypto_hash::PoseidonSponge, snark::varuna::{CircuitProvingKey, CircuitVerifyingKey, VarunaHidingMode}, srs::{UniversalProver, UniversalVerifier}, - AlgebraicSponge, }; -use snarkvm_console_algorithms::{Poseidon2, Poseidon4, BHP1024, BHP512}; +use snarkvm_console_algorithms::{BHP512, BHP1024, Poseidon2, Poseidon4}; use snarkvm_console_collections::merkle_tree::{MerklePath, MerkleTree}; use snarkvm_console_types::{Field, Group, Scalar}; use snarkvm_curves::PairingEngine; @@ -84,22 +91,41 @@ pub trait Network: /// The network edition. const EDITION: u16; + /// The block height from which consensus V2 rules apply. + const CONSENSUS_V2_HEIGHT: u32; + /// The function name for the inclusion circuit. const INCLUSION_FUNCTION_NAME: &'static str; /// The fixed timestamp of the genesis block. - const GENESIS_TIMESTAMP: i64 = 1696118400; // 2023-10-01 00:00:00 UTC + const GENESIS_TIMESTAMP: i64; /// The genesis block coinbase target. - const GENESIS_COINBASE_TARGET: u64 = (1u64 << 32).saturating_sub(1); + const GENESIS_COINBASE_TARGET: u64; /// The genesis block proof target. - const GENESIS_PROOF_TARGET: u64 = 1u64 << 25; + const GENESIS_PROOF_TARGET: u64; + /// The maximum number of solutions that can be included per block as a power of 2. + const MAX_SOLUTIONS_AS_POWER_OF_TWO: u8 = 2; // 4 solutions + /// The maximum number of solutions that can be included per block. + const MAX_SOLUTIONS: usize = 1 << Self::MAX_SOLUTIONS_AS_POWER_OF_TWO; // 4 solutions /// The starting supply of Aleo credits. const STARTING_SUPPLY: u64 = 1_500_000_000_000_000; // 1.5B credits /// The cost in microcredits per byte for the deployment transaction. const DEPLOYMENT_FEE_MULTIPLIER: u64 = 1_000; // 1 millicredit per byte + /// The constant that divides the storage polynomial. + const EXECUTION_STORAGE_FEE_SCALING_FACTOR: u64 = 5000; + /// The maximum size execution transactions can be before a quadratic storage penalty applies. + const EXECUTION_STORAGE_PENALTY_THRESHOLD: u64 = 5000; + /// The cost in microcredits per constraint for the deployment transaction. + const SYNTHESIS_FEE_MULTIPLIER: u64 = 25; // 25 microcredits per constraint + /// The maximum number of variables in a deployment. + const MAX_DEPLOYMENT_VARIABLES: u64 = 1 << 20; // 1,048,576 variables + /// The maximum number of constraints in a deployment. + const MAX_DEPLOYMENT_CONSTRAINTS: u64 = 1 << 20; // 1,048,576 constraints /// The maximum number of microcredits that can be spent as a fee. const MAX_FEE: u64 = 1_000_000_000_000_000; + /// The maximum number of microcredits that can be spent on a finalize block. + const TRANSACTION_SPEND_LIMIT: u64 = 100_000_000; /// The anchor height, defined as the expected number of blocks to reach the coinbase target. const ANCHOR_HEIGHT: u32 = Self::ANCHOR_TIME as u32 / Self::BLOCK_TIME as u32; @@ -107,10 +133,6 @@ pub trait Network: const ANCHOR_TIME: u16 = 25; /// The expected time per block in seconds. const BLOCK_TIME: u16 = 10; - /// The coinbase puzzle degree. - const COINBASE_PUZZLE_DEGREE: u32 = (1 << 13) - 1; // 8,191 - /// The maximum number of solutions that can be included per block. - const MAX_SOLUTIONS: usize = 1 << 8; // 256 solutions /// The number of blocks per epoch. const NUM_BLOCKS_PER_EPOCH: u32 = 3600 / Self::BLOCK_TIME as u32; // 360 blocks == ~1 hour @@ -138,10 +160,19 @@ pub trait Network: /// The maximum number of entries in a record. const MAX_RECORD_ENTRIES: usize = Self::MIN_RECORD_ENTRIES.saturating_add(Self::MAX_DATA_ENTRIES); + /// The maximum program size by number of characters. + const MAX_PROGRAM_SIZE: usize = 100_000; // 100 KB + /// The maximum number of mappings in a program. const MAX_MAPPINGS: usize = 31; /// The maximum number of functions in a program. const MAX_FUNCTIONS: usize = 31; + /// The maximum number of structs in a program. + const MAX_STRUCTS: usize = 10 * Self::MAX_FUNCTIONS; + /// The maximum number of records in a program. + const MAX_RECORDS: usize = 10 * Self::MAX_FUNCTIONS; + /// The maximum number of closures in a program. + const MAX_CLOSURES: usize = 2 * Self::MAX_FUNCTIONS; /// The maximum number of operands in an instruction. const MAX_OPERANDS: usize = Self::MAX_INPUTS; /// The maximum number of instructions in a closure or function. @@ -156,6 +187,18 @@ pub trait Network: /// The maximum number of outputs per transition. const MAX_OUTPUTS: usize = 16; + /// The maximum program depth. + const MAX_PROGRAM_DEPTH: usize = 64; + /// The maximum number of imports. + const MAX_IMPORTS: usize = 64; + + /// The maximum number of certificates in a batch. + const MAX_CERTIFICATES: u16; + + /// The maximum number of bytes in a transaction. + // Note: This value must **not** be decreased as it would invalidate existing transactions. + const MAX_TRANSACTION_SIZE: usize = 128_000; // 128 kB + /// The state root type. type StateRoot: Bech32ID>; /// The block hash type. @@ -166,10 +209,15 @@ pub trait Network: type TransactionID: Bech32ID>; /// The transition ID type. type TransitionID: Bech32ID>; + /// The transmission checksum type. + type TransmissionChecksum: IntegerType; /// Returns the genesis block bytes. fn genesis_bytes() -> &'static [u8]; + /// Returns the restrictions list as a JSON-compatible string. + fn restrictions_list_as_str() -> &'static str; + /// Returns the proving key for the given function name in `credits.aleo`. fn get_credits_proving_key(function_name: String) -> Result<&'static Arc>>; diff --git a/console/network/src/testnet3.rs b/console/network/src/mainnet_v0.rs similarity index 83% rename from console/network/src/testnet3.rs rename to console/network/src/mainnet_v0.rs index e4f47594ca..b38e59b2c9 100644 --- a/console/network/src/testnet3.rs +++ b/console/network/src/mainnet_v0.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,58 +15,58 @@ use super::*; use snarkvm_console_algorithms::{ + BHP256, + BHP512, + BHP768, + BHP1024, Blake2Xs, Keccak256, Keccak384, Keccak512, - Pedersen128, Pedersen64, + Pedersen128, Poseidon2, Poseidon4, Poseidon8, Sha3_256, Sha3_384, Sha3_512, - BHP1024, - BHP256, - BHP512, - BHP768, }; lazy_static! { /// The group bases for the Aleo signature and encryption schemes. - pub static ref GENERATOR_G: Vec> = Testnet3::new_bases("AleoAccountEncryptionAndSignatureScheme0"); + pub static ref GENERATOR_G: Vec> = MainnetV0::new_bases("AleoAccountEncryptionAndSignatureScheme0"); /// The Varuna sponge parameters. - pub static ref VARUNA_FS_PARAMETERS: FiatShamirParameters = FiatShamir::::sample_parameters(); + pub static ref VARUNA_FS_PARAMETERS: FiatShamirParameters = FiatShamir::::sample_parameters(); /// The encryption domain as a constant field element. - pub static ref ENCRYPTION_DOMAIN: Field = Field::::new_domain_separator("AleoSymmetricEncryption0"); + pub static ref ENCRYPTION_DOMAIN: Field = Field::::new_domain_separator("AleoSymmetricEncryption0"); /// The graph key domain as a constant field element. - pub static ref GRAPH_KEY_DOMAIN: Field = Field::::new_domain_separator("AleoGraphKey0"); + pub static ref GRAPH_KEY_DOMAIN: Field = Field::::new_domain_separator("AleoGraphKey0"); /// The serial number domain as a constant field element. - pub static ref SERIAL_NUMBER_DOMAIN: Field = Field::::new_domain_separator("AleoSerialNumber0"); + pub static ref SERIAL_NUMBER_DOMAIN: Field = Field::::new_domain_separator("AleoSerialNumber0"); /// The BHP hash function, which can take an input of up to 256 bits. - pub static ref BHP_256: BHP256 = BHP256::::setup("AleoBHP256").expect("Failed to setup BHP256"); + pub static ref BHP_256: BHP256 = BHP256::::setup("AleoBHP256").expect("Failed to setup BHP256"); /// The BHP hash function, which can take an input of up to 512 bits. - pub static ref BHP_512: BHP512 = BHP512::::setup("AleoBHP512").expect("Failed to setup BHP512"); + pub static ref BHP_512: BHP512 = BHP512::::setup("AleoBHP512").expect("Failed to setup BHP512"); /// The BHP hash function, which can take an input of up to 768 bits. - pub static ref BHP_768: BHP768 = BHP768::::setup("AleoBHP768").expect("Failed to setup BHP768"); + pub static ref BHP_768: BHP768 = BHP768::::setup("AleoBHP768").expect("Failed to setup BHP768"); /// The BHP hash function, which can take an input of up to 1024 bits. - pub static ref BHP_1024: BHP1024 = BHP1024::::setup("AleoBHP1024").expect("Failed to setup BHP1024"); + pub static ref BHP_1024: BHP1024 = BHP1024::::setup("AleoBHP1024").expect("Failed to setup BHP1024"); /// The Pedersen hash function, which can take an input of up to 64 bits. - pub static ref PEDERSEN_64: Pedersen64 = Pedersen64::::setup("AleoPedersen64"); + pub static ref PEDERSEN_64: Pedersen64 = Pedersen64::::setup("AleoPedersen64"); /// The Pedersen hash function, which can take an input of up to 128 bits. - pub static ref PEDERSEN_128: Pedersen128 = Pedersen128::::setup("AleoPedersen128"); + pub static ref PEDERSEN_128: Pedersen128 = Pedersen128::::setup("AleoPedersen128"); /// The Poseidon hash function, using a rate of 2. - pub static ref POSEIDON_2: Poseidon2 = Poseidon2::::setup("AleoPoseidon2").expect("Failed to setup Poseidon2"); + pub static ref POSEIDON_2: Poseidon2 = Poseidon2::::setup("AleoPoseidon2").expect("Failed to setup Poseidon2"); /// The Poseidon hash function, using a rate of 4. - pub static ref POSEIDON_4: Poseidon4 = Poseidon4::::setup("AleoPoseidon4").expect("Failed to setup Poseidon4"); + pub static ref POSEIDON_4: Poseidon4 = Poseidon4::::setup("AleoPoseidon4").expect("Failed to setup Poseidon4"); /// The Poseidon hash function, using a rate of 8. - pub static ref POSEIDON_8: Poseidon8 = Poseidon8::::setup("AleoPoseidon8").expect("Failed to setup Poseidon8"); + pub static ref POSEIDON_8: Poseidon8 = Poseidon8::::setup("AleoPoseidon8").expect("Failed to setup Poseidon8"); pub static ref CREDITS_PROVING_KEYS: IndexMap>> = { let mut map = IndexMap::new(); @@ -82,9 +83,9 @@ lazy_static! { pub const TRANSACTION_PREFIX: &str = "at"; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct Testnet3; +pub struct MainnetV0; -impl Testnet3 { +impl MainnetV0 { /// Initializes a new instance of group bases from a given input domain message. fn new_bases(message: &str) -> Vec> { // Hash the given message to a point on the curve, to initialize the starting base. @@ -101,7 +102,7 @@ impl Testnet3 { } } -impl Environment for Testnet3 { +impl Environment for MainnetV0 { type Affine = ::Affine; type BigInteger = ::BigInteger; type Field = ::Field; @@ -119,7 +120,7 @@ impl Environment for Testnet3 { const MONTGOMERY_B: Self::Field = Console::MONTGOMERY_B; } -impl Network for Testnet3 { +impl Network for MainnetV0 { /// The block hash type. type BlockHash = AleoID, { hrp2!("ab") }>; /// The ratification ID type. @@ -130,19 +131,51 @@ impl Network for Testnet3 { type TransactionID = AleoID, { hrp2!(TRANSACTION_PREFIX) }>; /// The transition ID type. type TransitionID = AleoID, { hrp2!("au") }>; - + /// The transmission checksum type. + type TransmissionChecksum = u128; + + /// The block height from which consensus V2 rules apply. + #[cfg(not(any(test, feature = "test")))] + const CONSENSUS_V2_HEIGHT: u32 = 2_800_000; + // TODO (raychu86): Update this value based on the desired mainnet height. + /// The block height from which consensus V2 rules apply. + #[cfg(any(test, feature = "test"))] + const CONSENSUS_V2_HEIGHT: u32 = 10; /// The network edition. const EDITION: u16 = 0; + /// The genesis block coinbase target. + #[cfg(not(feature = "test"))] + const GENESIS_COINBASE_TARGET: u64 = (1u64 << 29).saturating_sub(1); + /// The genesis block coinbase target. + /// This is deliberately set to a low value (32) for testing purposes only. + #[cfg(feature = "test")] + const GENESIS_COINBASE_TARGET: u64 = (1u64 << 5).saturating_sub(1); + /// The genesis block proof target. + #[cfg(not(feature = "test"))] + const GENESIS_PROOF_TARGET: u64 = 1u64 << 27; + /// The genesis block proof target. + /// This is deliberately set to a low value (8) for testing purposes only. + #[cfg(feature = "test")] + const GENESIS_PROOF_TARGET: u64 = 1u64 << 3; + /// The fixed timestamp of the genesis block. + const GENESIS_TIMESTAMP: i64 = 1725462000 /* 2024-09-04 11:00:00 UTC */; /// The network ID. - const ID: u16 = 3; + const ID: u16 = 0; /// The function name for the inclusion circuit. - const INCLUSION_FUNCTION_NAME: &'static str = snarkvm_parameters::testnet3::TESTNET3_INCLUSION_FUNCTION_NAME; + const INCLUSION_FUNCTION_NAME: &'static str = snarkvm_parameters::mainnet::NETWORK_INCLUSION_FUNCTION_NAME; + /// The maximum number of certificates in a batch. + const MAX_CERTIFICATES: u16 = 16; /// The network name. - const NAME: &'static str = "Aleo Testnet 3"; + const NAME: &'static str = "Aleo Mainnet (v0)"; /// Returns the genesis block bytes. fn genesis_bytes() -> &'static [u8] { - snarkvm_parameters::testnet3::GenesisBytes::load_bytes() + snarkvm_parameters::mainnet::GenesisBytes::load_bytes() + } + + /// Returns the restrictions list as a JSON-compatible string. + fn restrictions_list_as_str() -> &'static str { + snarkvm_parameters::mainnet::RESTRICTIONS_LIST } /// Returns the proving key for the given function name in `credits.aleo`. @@ -165,7 +198,7 @@ impl Network for Testnet3 { INSTANCE.get_or_init(|| { // Skipping the first byte, which is the encoded version. Arc::new( - CircuitProvingKey::from_bytes_le(&snarkvm_parameters::testnet3::INCLUSION_PROVING_KEY[1..]) + CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_PROVING_KEY[1..]) .expect("Failed to load inclusion proving key."), ) }) @@ -177,7 +210,7 @@ impl Network for Testnet3 { INSTANCE.get_or_init(|| { // Skipping the first byte, which is the encoded version. Arc::new( - CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::testnet3::INCLUSION_VERIFYING_KEY[1..]) + CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_VERIFYING_KEY[1..]) .expect("Failed to load inclusion verifying key."), ) }) @@ -485,7 +518,7 @@ impl Network for Testnet3 { mod tests { use super::*; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_g_scalar_multiply() { diff --git a/console/network/src/testnet_v0.rs b/console/network/src/testnet_v0.rs new file mode 100644 index 0000000000..0e4e9d1cd7 --- /dev/null +++ b/console/network/src/testnet_v0.rs @@ -0,0 +1,513 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; +use crate::TRANSACTION_PREFIX; +use snarkvm_console_algorithms::{ + BHP256, + BHP512, + BHP768, + BHP1024, + Blake2Xs, + Keccak256, + Keccak384, + Keccak512, + Pedersen64, + Pedersen128, + Poseidon2, + Poseidon4, + Poseidon8, + Sha3_256, + Sha3_384, + Sha3_512, +}; + +lazy_static! { + /// The group bases for the Aleo signature and encryption schemes. + static ref GENERATOR_G: Vec> = TestnetV0::new_bases("AleoAccountEncryptionAndSignatureScheme0"); + + /// The Varuna sponge parameters. + static ref VARUNA_FS_PARAMETERS: FiatShamirParameters = FiatShamir::::sample_parameters(); + + /// The encryption domain as a constant field element. + static ref ENCRYPTION_DOMAIN: Field = Field::::new_domain_separator("AleoSymmetricEncryption0"); + /// The graph key domain as a constant field element. + static ref GRAPH_KEY_DOMAIN: Field = Field::::new_domain_separator("AleoGraphKey0"); + /// The serial number domain as a constant field element. + static ref SERIAL_NUMBER_DOMAIN: Field = Field::::new_domain_separator("AleoSerialNumber0"); + + /// The BHP hash function, which can take an input of up to 256 bits. + pub static ref TESTNET_BHP_256: BHP256 = BHP256::::setup("AleoBHP256").expect("Failed to setup BHP256"); + /// The BHP hash function, which can take an input of up to 512 bits. + pub static ref TESTNET_BHP_512: BHP512 = BHP512::::setup("AleoBHP512").expect("Failed to setup BHP512"); + /// The BHP hash function, which can take an input of up to 768 bits. + pub static ref TESTNET_BHP_768: BHP768 = BHP768::::setup("AleoBHP768").expect("Failed to setup BHP768"); + /// The BHP hash function, which can take an input of up to 1024 bits. + pub static ref TESTNET_BHP_1024: BHP1024 = BHP1024::::setup("AleoBHP1024").expect("Failed to setup BHP1024"); + + /// The Pedersen hash function, which can take an input of up to 64 bits. + pub static ref TESTNET_PEDERSEN_64: Pedersen64 = Pedersen64::::setup("AleoPedersen64"); + /// The Pedersen hash function, which can take an input of up to 128 bits. + pub static ref TESTNET_PEDERSEN_128: Pedersen128 = Pedersen128::::setup("AleoPedersen128"); + + /// The Poseidon hash function, using a rate of 2. + pub static ref TESTNET_POSEIDON_2: Poseidon2 = Poseidon2::::setup("AleoPoseidon2").expect("Failed to setup Poseidon2"); + /// The Poseidon hash function, using a rate of 4. + pub static ref TESTNET_POSEIDON_4: Poseidon4 = Poseidon4::::setup("AleoPoseidon4").expect("Failed to setup Poseidon4"); + /// The Poseidon hash function, using a rate of 8. + pub static ref TESTNET_POSEIDON_8: Poseidon8 = Poseidon8::::setup("AleoPoseidon8").expect("Failed to setup Poseidon8"); + + pub static ref TESTNET_CREDITS_PROVING_KEYS: IndexMap>> = { + let mut map = IndexMap::new(); + snarkvm_parameters::insert_testnet_credit_keys!(map, VarunaProvingKey, Prover); + map + }; + pub static ref TESTNET_CREDITS_VERIFYING_KEYS: IndexMap>> = { + let mut map = IndexMap::new(); + snarkvm_parameters::insert_testnet_credit_keys!(map, VarunaVerifyingKey, Verifier); + map + }; +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct TestnetV0; + +impl TestnetV0 { + /// Initializes a new instance of group bases from a given input domain message. + fn new_bases(message: &str) -> Vec> { + // Hash the given message to a point on the curve, to initialize the starting base. + let (base, _, _) = Blake2Xs::hash_to_curve::<::Affine>(message); + + // Compute the bases up to the size of the scalar field (in bits). + let mut g = Group::::new(base); + let mut g_bases = Vec::with_capacity(Scalar::::size_in_bits()); + for _ in 0..Scalar::::size_in_bits() { + g_bases.push(g); + g = g.double(); + } + g_bases + } +} + +impl Environment for TestnetV0 { + type Affine = ::Affine; + type BigInteger = ::BigInteger; + type Field = ::Field; + type PairingCurve = ::PairingCurve; + type Projective = ::Projective; + type Scalar = ::Scalar; + + /// The coefficient `A` of the twisted Edwards curve. + const EDWARDS_A: Self::Field = Console::EDWARDS_A; + /// The coefficient `D` of the twisted Edwards curve. + const EDWARDS_D: Self::Field = Console::EDWARDS_D; + /// The coefficient `A` of the Montgomery curve. + const MONTGOMERY_A: Self::Field = Console::MONTGOMERY_A; + /// The coefficient `B` of the Montgomery curve. + const MONTGOMERY_B: Self::Field = Console::MONTGOMERY_B; +} + +impl Network for TestnetV0 { + /// The block hash type. + type BlockHash = AleoID, { hrp2!("ab") }>; + /// The ratification ID type. + type RatificationID = AleoID, { hrp2!("ar") }>; + /// The state root type. + type StateRoot = AleoID, { hrp2!("sr") }>; + /// The transaction ID type. + type TransactionID = AleoID, { hrp2!(TRANSACTION_PREFIX) }>; + /// The transition ID type. + type TransitionID = AleoID, { hrp2!("au") }>; + /// The transmission checksum type. + type TransmissionChecksum = u128; + + /// The block height from which consensus V2 rules apply. + #[cfg(not(any(test, feature = "test")))] + const CONSENSUS_V2_HEIGHT: u32 = 2_950_000; + // TODO (raychu86): Update this value based on the desired testnet height. + /// The block height from which consensus V2 rules apply. + #[cfg(any(test, feature = "test"))] + const CONSENSUS_V2_HEIGHT: u32 = 10; + /// The network edition. + const EDITION: u16 = 0; + /// The genesis block coinbase target. + #[cfg(not(feature = "test_targets"))] + const GENESIS_COINBASE_TARGET: u64 = (1u64 << 29).saturating_sub(1); + #[cfg(feature = "test_targets")] + const GENESIS_COINBASE_TARGET: u64 = (1u64 << 5).saturating_sub(1); + /// The genesis block proof target. + #[cfg(not(feature = "test_targets"))] + const GENESIS_PROOF_TARGET: u64 = 1u64 << 27; + #[cfg(feature = "test_targets")] + const GENESIS_PROOF_TARGET: u64 = 1u64 << 3; + /// The fixed timestamp of the genesis block. + const GENESIS_TIMESTAMP: i64 = 1715776496 /* 2024-05-15 12:34:56 UTC */; + /// The network ID. + const ID: u16 = 1; + /// The function name for the inclusion circuit. + const INCLUSION_FUNCTION_NAME: &'static str = MainnetV0::INCLUSION_FUNCTION_NAME; + /// The maximum number of certificates in a batch. + const MAX_CERTIFICATES: u16 = 100; + /// The network name. + const NAME: &'static str = "Aleo Testnet (v0)"; + + /// Returns the genesis block bytes. + fn genesis_bytes() -> &'static [u8] { + snarkvm_parameters::testnet::GenesisBytes::load_bytes() + } + + /// Returns the restrictions list as a JSON-compatible string. + fn restrictions_list_as_str() -> &'static str { + snarkvm_parameters::testnet::RESTRICTIONS_LIST + } + + /// Returns the proving key for the given function name in `credits.aleo`. + fn get_credits_proving_key(function_name: String) -> Result<&'static Arc>> { + TESTNET_CREDITS_PROVING_KEYS + .get(&function_name) + .ok_or_else(|| anyhow!("Proving key for credits.aleo/{function_name}' not found")) + } + + /// Returns the verifying key for the given function name in `credits.aleo`. + fn get_credits_verifying_key(function_name: String) -> Result<&'static Arc>> { + TESTNET_CREDITS_VERIFYING_KEYS + .get(&function_name) + .ok_or_else(|| anyhow!("Verifying key for credits.aleo/{function_name}' not found")) + } + + /// Returns the `proving key` for the inclusion circuit. + fn inclusion_proving_key() -> &'static Arc> { + static INSTANCE: OnceCell>> = OnceCell::new(); + INSTANCE.get_or_init(|| { + // Skipping the first byte, which is the encoded version. + Arc::new( + CircuitProvingKey::from_bytes_le(&snarkvm_parameters::testnet::INCLUSION_PROVING_KEY[1..]) + .expect("Failed to load inclusion proving key."), + ) + }) + } + + /// Returns the `verifying key` for the inclusion circuit. + fn inclusion_verifying_key() -> &'static Arc> { + static INSTANCE: OnceCell>> = OnceCell::new(); + INSTANCE.get_or_init(|| { + // Skipping the first byte, which is the encoded version. + Arc::new( + CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::testnet::INCLUSION_VERIFYING_KEY[1..]) + .expect("Failed to load inclusion verifying key."), + ) + }) + } + + /// Returns the powers of `G`. + fn g_powers() -> &'static Vec> { + &GENERATOR_G + } + + /// Returns the scalar multiplication on the generator `G`. + fn g_scalar_multiply(scalar: &Scalar) -> Group { + GENERATOR_G + .iter() + .zip_eq(&scalar.to_bits_le()) + .filter_map(|(base, bit)| match bit { + true => Some(base), + false => None, + }) + .sum() + } + + /// Returns the Varuna universal prover. + fn varuna_universal_prover() -> &'static UniversalProver { + MainnetV0::varuna_universal_prover() + } + + /// Returns the Varuna universal verifier. + fn varuna_universal_verifier() -> &'static UniversalVerifier { + MainnetV0::varuna_universal_verifier() + } + + /// Returns the sponge parameters used for the sponge in the Varuna SNARK. + fn varuna_fs_parameters() -> &'static FiatShamirParameters { + &VARUNA_FS_PARAMETERS + } + + /// Returns the encryption domain as a constant field element. + fn encryption_domain() -> Field { + *ENCRYPTION_DOMAIN + } + + /// Returns the graph key domain as a constant field element. + fn graph_key_domain() -> Field { + *GRAPH_KEY_DOMAIN + } + + /// Returns the serial number domain as a constant field element. + fn serial_number_domain() -> Field { + *SERIAL_NUMBER_DOMAIN + } + + /// Returns a BHP commitment with an input hasher of 256-bits and randomizer. + fn commit_bhp256(input: &[bool], randomizer: &Scalar) -> Result> { + TESTNET_BHP_256.commit(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 512-bits and randomizer. + fn commit_bhp512(input: &[bool], randomizer: &Scalar) -> Result> { + TESTNET_BHP_512.commit(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 768-bits and randomizer. + fn commit_bhp768(input: &[bool], randomizer: &Scalar) -> Result> { + TESTNET_BHP_768.commit(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 1024-bits and randomizer. + fn commit_bhp1024(input: &[bool], randomizer: &Scalar) -> Result> { + TESTNET_BHP_1024.commit(input, randomizer) + } + + /// Returns a Pedersen commitment for the given (up to) 64-bit input and randomizer. + fn commit_ped64(input: &[bool], randomizer: &Scalar) -> Result> { + TESTNET_PEDERSEN_64.commit(input, randomizer) + } + + /// Returns a Pedersen commitment for the given (up to) 128-bit input and randomizer. + fn commit_ped128(input: &[bool], randomizer: &Scalar) -> Result> { + TESTNET_PEDERSEN_128.commit(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 256-bits and randomizer. + fn commit_to_group_bhp256(input: &[bool], randomizer: &Scalar) -> Result> { + TESTNET_BHP_256.commit_uncompressed(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 512-bits and randomizer. + fn commit_to_group_bhp512(input: &[bool], randomizer: &Scalar) -> Result> { + TESTNET_BHP_512.commit_uncompressed(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 768-bits and randomizer. + fn commit_to_group_bhp768(input: &[bool], randomizer: &Scalar) -> Result> { + TESTNET_BHP_768.commit_uncompressed(input, randomizer) + } + + /// Returns a BHP commitment with an input hasher of 1024-bits and randomizer. + fn commit_to_group_bhp1024(input: &[bool], randomizer: &Scalar) -> Result> { + TESTNET_BHP_1024.commit_uncompressed(input, randomizer) + } + + /// Returns a Pedersen commitment for the given (up to) 64-bit input and randomizer. + fn commit_to_group_ped64(input: &[bool], randomizer: &Scalar) -> Result> { + TESTNET_PEDERSEN_64.commit_uncompressed(input, randomizer) + } + + /// Returns a Pedersen commitment for the given (up to) 128-bit input and randomizer. + fn commit_to_group_ped128(input: &[bool], randomizer: &Scalar) -> Result> { + TESTNET_PEDERSEN_128.commit_uncompressed(input, randomizer) + } + + /// Returns the BHP hash with an input hasher of 256-bits. + fn hash_bhp256(input: &[bool]) -> Result> { + TESTNET_BHP_256.hash(input) + } + + /// Returns the BHP hash with an input hasher of 512-bits. + fn hash_bhp512(input: &[bool]) -> Result> { + TESTNET_BHP_512.hash(input) + } + + /// Returns the BHP hash with an input hasher of 768-bits. + fn hash_bhp768(input: &[bool]) -> Result> { + TESTNET_BHP_768.hash(input) + } + + /// Returns the BHP hash with an input hasher of 1024-bits. + fn hash_bhp1024(input: &[bool]) -> Result> { + TESTNET_BHP_1024.hash(input) + } + + /// Returns the Keccak hash with a 256-bit output. + fn hash_keccak256(input: &[bool]) -> Result> { + Keccak256::default().hash(input) + } + + /// Returns the Keccak hash with a 384-bit output. + fn hash_keccak384(input: &[bool]) -> Result> { + Keccak384::default().hash(input) + } + + /// Returns the Keccak hash with a 512-bit output. + fn hash_keccak512(input: &[bool]) -> Result> { + Keccak512::default().hash(input) + } + + /// Returns the Pedersen hash for a given (up to) 64-bit input. + fn hash_ped64(input: &[bool]) -> Result> { + TESTNET_PEDERSEN_64.hash(input) + } + + /// Returns the Pedersen hash for a given (up to) 128-bit input. + fn hash_ped128(input: &[bool]) -> Result> { + TESTNET_PEDERSEN_128.hash(input) + } + + /// Returns the Poseidon hash with an input rate of 2. + fn hash_psd2(input: &[Field]) -> Result> { + TESTNET_POSEIDON_2.hash(input) + } + + /// Returns the Poseidon hash with an input rate of 4. + fn hash_psd4(input: &[Field]) -> Result> { + TESTNET_POSEIDON_4.hash(input) + } + + /// Returns the Poseidon hash with an input rate of 8. + fn hash_psd8(input: &[Field]) -> Result> { + TESTNET_POSEIDON_8.hash(input) + } + + /// Returns the SHA-3 hash with a 256-bit output. + fn hash_sha3_256(input: &[bool]) -> Result> { + Sha3_256::default().hash(input) + } + + /// Returns the SHA-3 hash with a 384-bit output. + fn hash_sha3_384(input: &[bool]) -> Result> { + Sha3_384::default().hash(input) + } + + /// Returns the SHA-3 hash with a 512-bit output. + fn hash_sha3_512(input: &[bool]) -> Result> { + Sha3_512::default().hash(input) + } + + /// Returns the extended Poseidon hash with an input rate of 2. + fn hash_many_psd2(input: &[Field], num_outputs: u16) -> Vec> { + TESTNET_POSEIDON_2.hash_many(input, num_outputs) + } + + /// Returns the extended Poseidon hash with an input rate of 4. + fn hash_many_psd4(input: &[Field], num_outputs: u16) -> Vec> { + TESTNET_POSEIDON_4.hash_many(input, num_outputs) + } + + /// Returns the extended Poseidon hash with an input rate of 8. + fn hash_many_psd8(input: &[Field], num_outputs: u16) -> Vec> { + TESTNET_POSEIDON_8.hash_many(input, num_outputs) + } + + /// Returns the BHP hash with an input hasher of 256-bits. + fn hash_to_group_bhp256(input: &[bool]) -> Result> { + TESTNET_BHP_256.hash_uncompressed(input) + } + + /// Returns the BHP hash with an input hasher of 512-bits. + fn hash_to_group_bhp512(input: &[bool]) -> Result> { + TESTNET_BHP_512.hash_uncompressed(input) + } + + /// Returns the BHP hash with an input hasher of 768-bits. + fn hash_to_group_bhp768(input: &[bool]) -> Result> { + TESTNET_BHP_768.hash_uncompressed(input) + } + + /// Returns the BHP hash with an input hasher of 1024-bits. + fn hash_to_group_bhp1024(input: &[bool]) -> Result> { + TESTNET_BHP_1024.hash_uncompressed(input) + } + + /// Returns the Pedersen hash for a given (up to) 64-bit input. + fn hash_to_group_ped64(input: &[bool]) -> Result> { + TESTNET_PEDERSEN_64.hash_uncompressed(input) + } + + /// Returns the Pedersen hash for a given (up to) 128-bit input. + fn hash_to_group_ped128(input: &[bool]) -> Result> { + TESTNET_PEDERSEN_128.hash_uncompressed(input) + } + + /// Returns the Poseidon hash with an input rate of 2 on the affine curve. + fn hash_to_group_psd2(input: &[Field]) -> Result> { + TESTNET_POSEIDON_2.hash_to_group(input) + } + + /// Returns the Poseidon hash with an input rate of 4 on the affine curve. + fn hash_to_group_psd4(input: &[Field]) -> Result> { + TESTNET_POSEIDON_4.hash_to_group(input) + } + + /// Returns the Poseidon hash with an input rate of 8 on the affine curve. + fn hash_to_group_psd8(input: &[Field]) -> Result> { + TESTNET_POSEIDON_8.hash_to_group(input) + } + + /// Returns the Poseidon hash with an input rate of 2 on the scalar field. + fn hash_to_scalar_psd2(input: &[Field]) -> Result> { + TESTNET_POSEIDON_2.hash_to_scalar(input) + } + + /// Returns the Poseidon hash with an input rate of 4 on the scalar field. + fn hash_to_scalar_psd4(input: &[Field]) -> Result> { + TESTNET_POSEIDON_4.hash_to_scalar(input) + } + + /// Returns the Poseidon hash with an input rate of 8 on the scalar field. + fn hash_to_scalar_psd8(input: &[Field]) -> Result> { + TESTNET_POSEIDON_8.hash_to_scalar(input) + } + + /// Returns a Merkle tree with a BHP leaf hasher of 1024-bits and a BHP path hasher of 512-bits. + fn merkle_tree_bhp(leaves: &[Vec]) -> Result> { + MerkleTree::new(&*TESTNET_BHP_1024, &*TESTNET_BHP_512, leaves) + } + + /// Returns a Merkle tree with a Poseidon leaf hasher with input rate of 4 and a Poseidon path hasher with input rate of 2. + fn merkle_tree_psd(leaves: &[Vec>]) -> Result> { + MerkleTree::new(&*TESTNET_POSEIDON_4, &*TESTNET_POSEIDON_2, leaves) + } + + /// Returns `true` if the given Merkle path is valid for the given root and leaf. + fn verify_merkle_path_bhp( + path: &MerklePath, + root: &Field, + leaf: &Vec, + ) -> bool { + path.verify(&*TESTNET_BHP_1024, &*TESTNET_BHP_512, root, leaf) + } + + /// Returns `true` if the given Merkle path is valid for the given root and leaf. + fn verify_merkle_path_psd( + path: &MerklePath, + root: &Field, + leaf: &Vec>, + ) -> bool { + path.verify(&*TESTNET_POSEIDON_4, &*TESTNET_POSEIDON_2, root, leaf) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + type CurrentNetwork = TestnetV0; + + #[test] + fn test_g_scalar_multiply() { + // Compute G^r. + let scalar = Scalar::rand(&mut TestRng::default()); + let group = CurrentNetwork::g_scalar_multiply(&scalar); + assert_eq!(group, CurrentNetwork::g_powers()[0] * scalar); + } +} diff --git a/console/program/Cargo.toml b/console/program/Cargo.toml index 23df63249a..2a84afbf51 100644 --- a/console/program/Cargo.toml +++ b/console/program/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "snarkvm-console-program" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Program operations for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" @@ -12,27 +14,27 @@ test = [ ] [dependencies.snarkvm-console-account] path = "../account" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-algorithms] path = "../algorithms" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-collections] path = "../collections" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-network] path = "../network" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types] path = "../types" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-utilities] path = "../../utilities" -version = "=0.16.19" +version = "=1.1.0" [dependencies.enum_index] version = "0.2" @@ -40,6 +42,9 @@ version = "0.2" [dependencies.enum_index_derive] version = "0.2" +[dependencies.enum-iterator] +version = "2.1" + [dependencies.indexmap] version = "2.0" diff --git a/console/program/src/data/access/bytes.rs b/console/program/src/data/access/bytes.rs index f2a560b148..13dde1b46f 100644 --- a/console/program/src/data/access/bytes.rs +++ b/console/program/src/data/access/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -46,9 +47,9 @@ impl ToBytes for Access { mod tests { use super::*; use crate::data::identifier::tests::sample_identifier; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u32 = 1000; diff --git a/console/program/src/data/access/mod.rs b/console/program/src/data/access/mod.rs index f2d3f56827..ddedaa6de1 100644 --- a/console/program/src/data/access/mod.rs +++ b/console/program/src/data/access/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/access/parse.rs b/console/program/src/data/access/parse.rs index 4d5801e336..7d4def4593 100644 --- a/console/program/src/data/access/parse.rs +++ b/console/program/src/data/access/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -63,9 +64,9 @@ impl Display for Access { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { diff --git a/console/program/src/data/access/serialize.rs b/console/program/src/data/access/serialize.rs index 461f8c6d0c..50daa1c745 100644 --- a/console/program/src/data/access/serialize.rs +++ b/console/program/src/data/access/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for Access { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; fn check_serde_json< T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes, diff --git a/console/program/src/data/ciphertext/bytes.rs b/console/program/src/data/ciphertext/bytes.rs index d983d9bb71..28d8214405 100644 --- a/console/program/src/data/ciphertext/bytes.rs +++ b/console/program/src/data/ciphertext/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -49,9 +50,9 @@ impl ToBytes for Ciphertext { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u32 = 1000; diff --git a/console/program/src/data/ciphertext/decrypt.rs b/console/program/src/data/ciphertext/decrypt.rs index 1de811c4dc..95db6025db 100644 --- a/console/program/src/data/ciphertext/decrypt.rs +++ b/console/program/src/data/ciphertext/decrypt.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -51,9 +52,9 @@ mod tests { use super::*; use crate::Literal; use snarkvm_console_account::{Address, PrivateKey}; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 100; diff --git a/console/program/src/data/ciphertext/equal.rs b/console/program/src/data/ciphertext/equal.rs index 31bbd5fffc..2c3a1db1da 100644 --- a/console/program/src/data/ciphertext/equal.rs +++ b/console/program/src/data/ciphertext/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/ciphertext/from_bits.rs b/console/program/src/data/ciphertext/from_bits.rs index 45c818a82e..b143c22e49 100644 --- a/console/program/src/data/ciphertext/from_bits.rs +++ b/console/program/src/data/ciphertext/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/ciphertext/from_fields.rs b/console/program/src/data/ciphertext/from_fields.rs index 2d01debc66..e5eb336ee5 100644 --- a/console/program/src/data/ciphertext/from_fields.rs +++ b/console/program/src/data/ciphertext/from_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/ciphertext/mod.rs b/console/program/src/data/ciphertext/mod.rs index 344ec2c256..bcc4877a22 100644 --- a/console/program/src/data/ciphertext/mod.rs +++ b/console/program/src/data/ciphertext/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/ciphertext/num_randomizers.rs b/console/program/src/data/ciphertext/num_randomizers.rs index f5af31439c..ee503849be 100644 --- a/console/program/src/data/ciphertext/num_randomizers.rs +++ b/console/program/src/data/ciphertext/num_randomizers.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/ciphertext/parse.rs b/console/program/src/data/ciphertext/parse.rs index c3ca3f9b0a..693b84fc25 100644 --- a/console/program/src/data/ciphertext/parse.rs +++ b/console/program/src/data/ciphertext/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -74,9 +75,9 @@ impl Display for Ciphertext { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1_000; @@ -113,7 +114,7 @@ mod tests { // Check the string representation. let candidate = format!("{expected}"); assert_eq!(expected, Ciphertext::from_str(&candidate)?); - assert_eq!(CIPHERTEXT_PREFIX, candidate.to_string().split('1').next().unwrap()); + assert_eq!(CIPHERTEXT_PREFIX, candidate.split('1').next().unwrap()); } Ok(()) } diff --git a/console/program/src/data/ciphertext/serialize.rs b/console/program/src/data/ciphertext/serialize.rs index 30070ead75..09740f25ae 100644 --- a/console/program/src/data/ciphertext/serialize.rs +++ b/console/program/src/data/ciphertext/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for Ciphertext { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/program/src/data/ciphertext/size_in_fields.rs b/console/program/src/data/ciphertext/size_in_fields.rs index 6aa25689a8..54f39a84d2 100644 --- a/console/program/src/data/ciphertext/size_in_fields.rs +++ b/console/program/src/data/ciphertext/size_in_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/ciphertext/to_bits.rs b/console/program/src/data/ciphertext/to_bits.rs index bc9f619268..418fded54b 100644 --- a/console/program/src/data/ciphertext/to_bits.rs +++ b/console/program/src/data/ciphertext/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/ciphertext/to_fields.rs b/console/program/src/data/ciphertext/to_fields.rs index c4f91d6999..a33953d0b4 100644 --- a/console/program/src/data/ciphertext/to_fields.rs +++ b/console/program/src/data/ciphertext/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/future/argument.rs b/console/program/src/data/future/argument.rs index f87392dc7c..c539c26d8f 100644 --- a/console/program/src/data/future/argument.rs +++ b/console/program/src/data/future/argument.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/future/bytes.rs b/console/program/src/data/future/bytes.rs index aa6122b4a4..4a33965ba0 100644 --- a/console/program/src/data/future/bytes.rs +++ b/console/program/src/data/future/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -72,9 +73,9 @@ impl ToBytes for Future { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { diff --git a/console/program/src/data/future/equal.rs b/console/program/src/data/future/equal.rs index 5384724749..efc8f26687 100644 --- a/console/program/src/data/future/equal.rs +++ b/console/program/src/data/future/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/future/find.rs b/console/program/src/data/future/find.rs index 7885c3a7b2..d8c9a74c12 100644 --- a/console/program/src/data/future/find.rs +++ b/console/program/src/data/future/find.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/future/mod.rs b/console/program/src/data/future/mod.rs index 437b01d96b..d4cfb621ef 100644 --- a/console/program/src/data/future/mod.rs +++ b/console/program/src/data/future/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/future/parse.rs b/console/program/src/data/future/parse.rs index c54356afed..ed0f071d24 100644 --- a/console/program/src/data/future/parse.rs +++ b/console/program/src/data/future/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -213,9 +214,9 @@ impl Future { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse_future() -> Result<()> { diff --git a/console/program/src/data/future/serialize.rs b/console/program/src/data/future/serialize.rs index 134e358e00..ca8173b366 100644 --- a/console/program/src/data/future/serialize.rs +++ b/console/program/src/data/future/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/future/to_bits.rs b/console/program/src/data/future/to_bits.rs index c91ce27734..adfc260e80 100644 --- a/console/program/src/data/future/to_bits.rs +++ b/console/program/src/data/future/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/future/to_fields.rs b/console/program/src/data/future/to_fields.rs index e24c85d3f8..031a8d98e2 100644 --- a/console/program/src/data/future/to_fields.rs +++ b/console/program/src/data/future/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/identifier/bytes.rs b/console/program/src/data/identifier/bytes.rs index 757f27ba40..d0b979cceb 100644 --- a/console/program/src/data/identifier/bytes.rs +++ b/console/program/src/data/identifier/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -56,9 +57,9 @@ impl ToBytes for Identifier { mod tests { use super::*; use crate::data::identifier::tests::sample_identifier; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/program/src/data/identifier/equal.rs b/console/program/src/data/identifier/equal.rs index 4c4586da7a..0d7f6db331 100644 --- a/console/program/src/data/identifier/equal.rs +++ b/console/program/src/data/identifier/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/identifier/from_bits.rs b/console/program/src/data/identifier/from_bits.rs index e4a81c7811..97757be808 100644 --- a/console/program/src/data/identifier/from_bits.rs +++ b/console/program/src/data/identifier/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -46,9 +47,9 @@ impl FromBits for Identifier { mod tests { use super::*; use crate::data::identifier::tests::sample_identifier; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/program/src/data/identifier/from_field.rs b/console/program/src/data/identifier/from_field.rs index f5b597b37f..bd667b3f52 100644 --- a/console/program/src/data/identifier/from_field.rs +++ b/console/program/src/data/identifier/from_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -28,9 +29,9 @@ impl FromField for Identifier { mod tests { use super::*; use crate::data::identifier::tests::sample_identifier; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/program/src/data/identifier/mod.rs b/console/program/src/data/identifier/mod.rs index 22a1bec117..fa064fc5ed 100644 --- a/console/program/src/data/identifier/mod.rs +++ b/console/program/src/data/identifier/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -23,7 +24,7 @@ mod to_bits; mod to_field; use snarkvm_console_network::Network; -use snarkvm_console_types::{prelude::*, Field}; +use snarkvm_console_types::{Field, prelude::*}; /// An identifier is an **immutable** UTF-8 string, /// represented as a **constant** field element in the CurrentNetwork. @@ -74,9 +75,9 @@ impl TryFrom<&str> for Identifier { #[cfg(test)] pub(crate) mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/program/src/data/identifier/parse.rs b/console/program/src/data/identifier/parse.rs index 94de468b24..ce58a86e0e 100644 --- a/console/program/src/data/identifier/parse.rs +++ b/console/program/src/data/identifier/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -52,6 +53,12 @@ impl FromStr for Identifier { bail!("Identifier is too large. Identifiers must be <= {max_bytes} bytes long") } + // Ensure that the identifier is not a literal. + ensure!( + !enum_iterator::all::().any(|lt| lt.type_name() == identifier), + "Identifier '{identifier}' is a reserved literal type" + ); + // Note: The string bytes themselves are **not** little-endian. Rather, they are order-preserving // for reconstructing the string when recovering the field element back into bytes. Ok(Self( @@ -93,9 +100,9 @@ impl Display for Identifier { mod tests { use super::*; use crate::data::identifier::tests::{sample_identifier, sample_identifier_as_string}; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/program/src/data/identifier/serialize.rs b/console/program/src/data/identifier/serialize.rs index eadddc2a9d..5b3a0a65b9 100644 --- a/console/program/src/data/identifier/serialize.rs +++ b/console/program/src/data/identifier/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -38,9 +39,9 @@ impl<'de, N: Network> Deserialize<'de> for Identifier { mod tests { use super::*; use crate::data::identifier::tests::sample_identifier; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/program/src/data/identifier/size_in_bits.rs b/console/program/src/data/identifier/size_in_bits.rs index 506b253ae4..c677fc42e7 100644 --- a/console/program/src/data/identifier/size_in_bits.rs +++ b/console/program/src/data/identifier/size_in_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -28,9 +29,9 @@ impl Identifier { mod tests { use super::*; use crate::data::identifier::tests::sample_identifier_as_string; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/program/src/data/identifier/to_bits.rs b/console/program/src/data/identifier/to_bits.rs index 2a22dc3234..8909c486ff 100644 --- a/console/program/src/data/identifier/to_bits.rs +++ b/console/program/src/data/identifier/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -46,9 +47,9 @@ impl ToBits for &Identifier { mod tests { use super::*; use crate::data::identifier::tests::sample_identifier_as_string; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/program/src/data/identifier/to_field.rs b/console/program/src/data/identifier/to_field.rs index 5eb11072b2..c8dc8df285 100644 --- a/console/program/src/data/identifier/to_field.rs +++ b/console/program/src/data/identifier/to_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -36,9 +37,9 @@ impl ToField for &Identifier { mod tests { use super::*; use crate::data::identifier::tests::sample_identifier_as_string; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/program/src/data/literal/bytes.rs b/console/program/src/data/literal/bytes.rs index 1f77bf3430..d93bc1c405 100644 --- a/console/program/src/data/literal/bytes.rs +++ b/console/program/src/data/literal/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -122,9 +123,9 @@ impl ToBytes for Literal { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u32 = 1000; diff --git a/console/program/src/data/literal/cast/boolean.rs b/console/program/src/data/literal/cast/boolean.rs index 2ea3d30d8d..12bc5ef1d5 100644 --- a/console/program/src/data/literal/cast/boolean.rs +++ b/console/program/src/data/literal/cast/boolean.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/cast/field.rs b/console/program/src/data/literal/cast/field.rs index 3329c84e9d..91334cbcf0 100644 --- a/console/program/src/data/literal/cast/field.rs +++ b/console/program/src/data/literal/cast/field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/cast/integer.rs b/console/program/src/data/literal/cast/integer.rs index d262aaad4d..d34c012fcb 100644 --- a/console/program/src/data/literal/cast/integer.rs +++ b/console/program/src/data/literal/cast/integer.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/cast/mod.rs b/console/program/src/data/literal/cast/mod.rs index a673740786..77cde083e9 100644 --- a/console/program/src/data/literal/cast/mod.rs +++ b/console/program/src/data/literal/cast/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,7 +20,7 @@ mod scalar; use crate::{Literal, LiteralType}; use snarkvm_console_network::Network; -use snarkvm_console_types::{integers::Integer, prelude::*, Boolean}; +use snarkvm_console_types::{Boolean, integers::Integer, prelude::*}; /// Unary operator for casting values of one type to another. pub trait Cast { @@ -40,6 +41,7 @@ impl Literal { /// - (`Address`, `Group`) <-> `Field` <-> `Scalar` <-> `Integer` <-> `Boolean` /// - `Signature` (not supported) /// - `String` (not supported) + /// /// Note that casting to left along the hierarchy always preserves information. pub fn cast(&self, to_type: LiteralType) -> Result { match self { diff --git a/console/program/src/data/literal/cast/scalar.rs b/console/program/src/data/literal/cast/scalar.rs index 140bb7a52f..c240c480e8 100644 --- a/console/program/src/data/literal/cast/scalar.rs +++ b/console/program/src/data/literal/cast/scalar.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/cast_lossy/boolean.rs b/console/program/src/data/literal/cast_lossy/boolean.rs index 56c655cede..64301d3ba2 100644 --- a/console/program/src/data/literal/cast_lossy/boolean.rs +++ b/console/program/src/data/literal/cast_lossy/boolean.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/cast_lossy/field.rs b/console/program/src/data/literal/cast_lossy/field.rs index f5b7a15339..9677978455 100644 --- a/console/program/src/data/literal/cast_lossy/field.rs +++ b/console/program/src/data/literal/cast_lossy/field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/cast_lossy/integer.rs b/console/program/src/data/literal/cast_lossy/integer.rs index efd351ad58..76c3bfd1b7 100644 --- a/console/program/src/data/literal/cast_lossy/integer.rs +++ b/console/program/src/data/literal/cast_lossy/integer.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/cast_lossy/mod.rs b/console/program/src/data/literal/cast_lossy/mod.rs index 997ecd7774..0b6c11eeef 100644 --- a/console/program/src/data/literal/cast_lossy/mod.rs +++ b/console/program/src/data/literal/cast_lossy/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,7 +21,7 @@ mod scalar; use crate::{Literal, LiteralType}; use snarkvm_console_algorithms::Elligator2; use snarkvm_console_network::Network; -use snarkvm_console_types::{integers::Integer, prelude::*, Boolean}; +use snarkvm_console_types::{Boolean, integers::Integer, prelude::*}; /// Unary operator for casting values of one type to another, with lossy truncation. pub trait CastLossy { @@ -41,6 +42,7 @@ impl Literal { /// - (`Address`, `Group`) <-> `Field` <-> `Scalar` <-> `Integer` <-> `Boolean` /// - `Signature` (not supported) /// - `String` (not supported) + /// /// Note that casting to left along the hierarchy always preserves information. pub fn cast_lossy(&self, to_type: LiteralType) -> Result { match self { @@ -114,10 +116,7 @@ fn cast_lossy_group_to_type(input: &Group, to_type: LiteralType) } /// Casts an integer literal to the given literal type, with lossy truncation. -fn cast_lossy_integer_to_type( - input: &Integer, - to_type: LiteralType, -) -> Result> +fn cast_lossy_integer_to_type(input: &Integer, to_type: LiteralType) -> Result> where I: AsPrimitive + AsPrimitive @@ -128,7 +127,8 @@ where + AsPrimitive + AsPrimitive + AsPrimitive - + AsPrimitive, + + AsPrimitive + + IntegerType, { impl_cast_lossy_body!(integer, cast_lossy, input, to_type) } diff --git a/console/program/src/data/literal/cast_lossy/scalar.rs b/console/program/src/data/literal/cast_lossy/scalar.rs index 24cb95db4f..3e5b51c5b0 100644 --- a/console/program/src/data/literal/cast_lossy/scalar.rs +++ b/console/program/src/data/literal/cast_lossy/scalar.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/equal.rs b/console/program/src/data/literal/equal.rs index a1c4cf61be..7718a78561 100644 --- a/console/program/src/data/literal/equal.rs +++ b/console/program/src/data/literal/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/from_bits.rs b/console/program/src/data/literal/from_bits.rs index e7b26f5f95..8f6798941b 100644 --- a/console/program/src/data/literal/from_bits.rs +++ b/console/program/src/data/literal/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -95,9 +96,9 @@ impl Literal { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u32 = 1000; diff --git a/console/program/src/data/literal/mod.rs b/console/program/src/data/literal/mod.rs index 5b904165ca..4f33462ef6 100644 --- a/console/program/src/data/literal/mod.rs +++ b/console/program/src/data/literal/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,6 +25,7 @@ mod parse; mod sample; mod serialize; mod size_in_bits; +mod size_in_bytes; mod to_bits; mod to_type; mod variant; @@ -31,7 +33,7 @@ mod variant; use crate::{LiteralType, ProgramID}; use snarkvm_console_account::{ComputeKey, PrivateKey, Signature}; use snarkvm_console_network::Network; -use snarkvm_console_types::{prelude::*, Boolean}; +use snarkvm_console_types::{Boolean, prelude::*}; /// The literal enum represents all supported types in snarkVM. #[derive(Clone)] diff --git a/console/program/src/data/literal/parse.rs b/console/program/src/data/literal/parse.rs index 0a02b7200d..2290e93dbc 100644 --- a/console/program/src/data/literal/parse.rs +++ b/console/program/src/data/literal/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -93,9 +94,9 @@ impl Display for Literal { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse_program_id() -> Result<()> { diff --git a/console/program/src/data/literal/sample.rs b/console/program/src/data/literal/sample.rs index dd8f2876ec..9d197c298a 100644 --- a/console/program/src/data/literal/sample.rs +++ b/console/program/src/data/literal/sample.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/serialize.rs b/console/program/src/data/literal/serialize.rs index 2bf01a9154..56ac64e0f1 100644 --- a/console/program/src/data/literal/serialize.rs +++ b/console/program/src/data/literal/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for Literal { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/program/src/data/literal/size_in_bits.rs b/console/program/src/data/literal/size_in_bits.rs index b07ac4083e..b22e42a614 100644 --- a/console/program/src/data/literal/size_in_bits.rs +++ b/console/program/src/data/literal/size_in_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/size_in_bytes.rs b/console/program/src/data/literal/size_in_bytes.rs new file mode 100644 index 0000000000..212b32ceda --- /dev/null +++ b/console/program/src/data/literal/size_in_bytes.rs @@ -0,0 +1,27 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl Literal { + /// Returns the size in bytes of this literal. + #[allow(clippy::cast_possible_truncation)] + pub fn size_in_bytes(&self) -> u16 { + // Note: This upcast to u32 and downcast to u16 is safe because the size of a literal is + // always less than or equal to u16::MAX bits, and we are dividing by 8, so the result will + // always fit in a u16. + (((self.size_in_bits() as u32) + 7) / 8) as u16 + } +} diff --git a/console/program/src/data/literal/to_bits.rs b/console/program/src/data/literal/to_bits.rs index 4951011b8f..07b9f88d02 100644 --- a/console/program/src/data/literal/to_bits.rs +++ b/console/program/src/data/literal/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/to_type.rs b/console/program/src/data/literal/to_type.rs index 220fb571dd..d325132560 100644 --- a/console/program/src/data/literal/to_type.rs +++ b/console/program/src/data/literal/to_type.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/literal/variant.rs b/console/program/src/data/literal/variant.rs index da1470cf86..5a6fb64c6d 100644 --- a/console/program/src/data/literal/variant.rs +++ b/console/program/src/data/literal/variant.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/mod.rs b/console/program/src/data/mod.rs index 231cb6437a..944afd57e2 100644 --- a/console/program/src/data/mod.rs +++ b/console/program/src/data/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/plaintext/bytes.rs b/console/program/src/data/plaintext/bytes.rs index 8fa2f1dba1..e537b52bdc 100644 --- a/console/program/src/data/plaintext/bytes.rs +++ b/console/program/src/data/plaintext/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -123,9 +124,9 @@ impl ToBytes for Plaintext { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u32 = 1000; diff --git a/console/program/src/data/plaintext/encrypt.rs b/console/program/src/data/plaintext/encrypt.rs index e0fb3da814..32828b2ec6 100644 --- a/console/program/src/data/plaintext/encrypt.rs +++ b/console/program/src/data/plaintext/encrypt.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/plaintext/equal.rs b/console/program/src/data/plaintext/equal.rs index 3432735d10..38a090383d 100644 --- a/console/program/src/data/plaintext/equal.rs +++ b/console/program/src/data/plaintext/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -84,9 +85,9 @@ impl Equal for Plaintext { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; fn sample_plaintext() -> Plaintext { Plaintext::::from_str( diff --git a/console/program/src/data/plaintext/find.rs b/console/program/src/data/plaintext/find.rs index ea8843d881..5f8008e62e 100644 --- a/console/program/src/data/plaintext/find.rs +++ b/console/program/src/data/plaintext/find.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/plaintext/from_bits.rs b/console/program/src/data/plaintext/from_bits.rs index a705b778ac..b40a00f7fb 100644 --- a/console/program/src/data/plaintext/from_bits.rs +++ b/console/program/src/data/plaintext/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/plaintext/from_fields.rs b/console/program/src/data/plaintext/from_fields.rs index ac8a0d604c..0578ce13c6 100644 --- a/console/program/src/data/plaintext/from_fields.rs +++ b/console/program/src/data/plaintext/from_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/plaintext/mod.rs b/console/program/src/data/plaintext/mod.rs index aea42f16b9..bb0b85f6c5 100644 --- a/console/program/src/data/plaintext/mod.rs +++ b/console/program/src/data/plaintext/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -59,12 +60,12 @@ impl From<&Literal> for Plaintext { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; use snarkvm_console_types::Field; use core::str::FromStr; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_plaintext() -> Result<()> { diff --git a/console/program/src/data/plaintext/num_randomizers.rs b/console/program/src/data/plaintext/num_randomizers.rs index cca77e1252..40ed5a6f81 100644 --- a/console/program/src/data/plaintext/num_randomizers.rs +++ b/console/program/src/data/plaintext/num_randomizers.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/plaintext/parse.rs b/console/program/src/data/plaintext/parse.rs index 7a395f4291..b3aeaa5467 100644 --- a/console/program/src/data/plaintext/parse.rs +++ b/console/program/src/data/plaintext/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -205,9 +206,9 @@ impl Plaintext { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse_literal() -> Result<()> { diff --git a/console/program/src/data/plaintext/serialize.rs b/console/program/src/data/plaintext/serialize.rs index 0ad4131272..797ad71df5 100644 --- a/console/program/src/data/plaintext/serialize.rs +++ b/console/program/src/data/plaintext/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for Plaintext { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 2; diff --git a/console/program/src/data/plaintext/size_in_fields.rs b/console/program/src/data/plaintext/size_in_fields.rs index 5a1bcf13f4..5be2be4255 100644 --- a/console/program/src/data/plaintext/size_in_fields.rs +++ b/console/program/src/data/plaintext/size_in_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/plaintext/to_bits.rs b/console/program/src/data/plaintext/to_bits.rs index 7b53f02b83..53b73f4041 100644 --- a/console/program/src/data/plaintext/to_bits.rs +++ b/console/program/src/data/plaintext/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/plaintext/to_fields.rs b/console/program/src/data/plaintext/to_fields.rs index ae4a101ff5..8741e8cf59 100644 --- a/console/program/src/data/plaintext/to_fields.rs +++ b/console/program/src/data/plaintext/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/bytes.rs b/console/program/src/data/record/bytes.rs index 6b4bcc0687..0cd1dd62e7 100644 --- a/console/program/src/data/record/bytes.rs +++ b/console/program/src/data/record/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -82,9 +83,9 @@ impl ToBytes for Record { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { diff --git a/console/program/src/data/record/decrypt.rs b/console/program/src/data/record/decrypt.rs index 31fb963db2..d84fb9c695 100644 --- a/console/program/src/data/record/decrypt.rs +++ b/console/program/src/data/record/decrypt.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -96,10 +97,10 @@ mod tests { use super::*; use crate::Literal; use snarkvm_console_account::PrivateKey; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; use snarkvm_console_types::Field; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; diff --git a/console/program/src/data/record/encrypt.rs b/console/program/src/data/record/encrypt.rs index bcfce3e770..28a8ce39d4 100644 --- a/console/program/src/data/record/encrypt.rs +++ b/console/program/src/data/record/encrypt.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/entry/bytes.rs b/console/program/src/data/record/entry/bytes.rs index d38bfc17a3..221232fb64 100644 --- a/console/program/src/data/record/entry/bytes.rs +++ b/console/program/src/data/record/entry/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/entry/equal.rs b/console/program/src/data/record/entry/equal.rs index 748858d58b..6ceb8a4ee9 100644 --- a/console/program/src/data/record/entry/equal.rs +++ b/console/program/src/data/record/entry/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/entry/find.rs b/console/program/src/data/record/entry/find.rs index 94985f4d83..3a912298d2 100644 --- a/console/program/src/data/record/entry/find.rs +++ b/console/program/src/data/record/entry/find.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/entry/mod.rs b/console/program/src/data/record/entry/mod.rs index ea2585ccdd..3bc197836e 100644 --- a/console/program/src/data/record/entry/mod.rs +++ b/console/program/src/data/record/entry/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/entry/num_randomizers.rs b/console/program/src/data/record/entry/num_randomizers.rs index b03062ad7f..fd7534fe7e 100644 --- a/console/program/src/data/record/entry/num_randomizers.rs +++ b/console/program/src/data/record/entry/num_randomizers.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/entry/parse.rs b/console/program/src/data/record/entry/parse.rs index ec7a125da3..8a76daae75 100644 --- a/console/program/src/data/record/entry/parse.rs +++ b/console/program/src/data/record/entry/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -288,9 +289,9 @@ impl Entry> { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { diff --git a/console/program/src/data/record/entry/to_bits.rs b/console/program/src/data/record/entry/to_bits.rs index 9fe72b678d..0bedc64a50 100644 --- a/console/program/src/data/record/entry/to_bits.rs +++ b/console/program/src/data/record/entry/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/equal.rs b/console/program/src/data/record/equal.rs index 61bf58b714..77e976a76a 100644 --- a/console/program/src/data/record/equal.rs +++ b/console/program/src/data/record/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -60,9 +61,9 @@ impl>> Equal for Reco #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; fn sample_record() -> Record> { Record::>::from_str( diff --git a/console/program/src/data/record/find.rs b/console/program/src/data/record/find.rs index 8a3a922101..9101686e70 100644 --- a/console/program/src/data/record/find.rs +++ b/console/program/src/data/record/find.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/helpers/mod.rs b/console/program/src/data/record/helpers/mod.rs index 1770e4373a..16918fea74 100644 --- a/console/program/src/data/record/helpers/mod.rs +++ b/console/program/src/data/record/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/helpers/owner.rs b/console/program/src/data/record/helpers/owner.rs index f4eff1b1fd..4a7472585a 100644 --- a/console/program/src/data/record/helpers/owner.rs +++ b/console/program/src/data/record/helpers/owner.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/is_owner.rs b/console/program/src/data/record/is_owner.rs index 54df9c6958..a9f9153923 100644 --- a/console/program/src/data/record/is_owner.rs +++ b/console/program/src/data/record/is_owner.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,6 +16,7 @@ use super::*; impl Record> { + /// Returns `true` if the given view key corresponds to the owner of the record. /// Decrypts `self` into plaintext using the given view key. pub fn is_owner(&self, view_key: &ViewKey) -> bool { // Compute the address. @@ -23,6 +25,7 @@ impl Record> { self.is_owner_with_address_x_coordinate(view_key, &address.to_x_coordinate()) } + /// Returns `true` if the given view key and address x-coordinate corresponds to the owner of the record. /// Decrypts `self` into plaintext using the x-coordinate of the address corresponding to the given view key. pub fn is_owner_with_address_x_coordinate(&self, view_key: &ViewKey, address_x_coordinate: &Field) -> bool { // In debug mode, check that the address corresponds to the given view key. @@ -62,10 +65,10 @@ mod tests { use super::*; use crate::Literal; use snarkvm_console_account::PrivateKey; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; use snarkvm_console_types::Field; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1_000; diff --git a/console/program/src/data/record/mod.rs b/console/program/src/data/record/mod.rs index 33bc202189..9700e5e3e2 100644 --- a/console/program/src/data/record/mod.rs +++ b/console/program/src/data/record/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/num_randomizers.rs b/console/program/src/data/record/num_randomizers.rs index fd4f7d12a1..4a53245e5a 100644 --- a/console/program/src/data/record/num_randomizers.rs +++ b/console/program/src/data/record/num_randomizers.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/parse_ciphertext.rs b/console/program/src/data/record/parse_ciphertext.rs index c0ee86c91f..d4b70955a9 100644 --- a/console/program/src/data/record/parse_ciphertext.rs +++ b/console/program/src/data/record/parse_ciphertext.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/parse_plaintext.rs b/console/program/src/data/record/parse_plaintext.rs index 0dfcdc4aa1..bec066f8e3 100644 --- a/console/program/src/data/record/parse_plaintext.rs +++ b/console/program/src/data/record/parse_plaintext.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -178,9 +179,9 @@ impl Record> { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse_without_data_entries() -> Result<()> { diff --git a/console/program/src/data/record/serial_number.rs b/console/program/src/data/record/serial_number.rs index b01676908d..5ec49c8684 100644 --- a/console/program/src/data/record/serial_number.rs +++ b/console/program/src/data/record/serial_number.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/serialize.rs b/console/program/src/data/record/serialize.rs index 00f4331007..e94dcaca2f 100644 --- a/console/program/src/data/record/serialize.rs +++ b/console/program/src/data/record/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -57,9 +58,9 @@ impl<'de, N: Network> Deserialize<'de> for Record> { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1; diff --git a/console/program/src/data/record/tag.rs b/console/program/src/data/record/tag.rs index e5ca9dc235..3b72d2e090 100644 --- a/console/program/src/data/record/tag.rs +++ b/console/program/src/data/record/tag.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/to_bits.rs b/console/program/src/data/record/to_bits.rs index 63c39c9cb3..a726d9374c 100644 --- a/console/program/src/data/record/to_bits.rs +++ b/console/program/src/data/record/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/to_commitment.rs b/console/program/src/data/record/to_commitment.rs index 1a85677675..b9a9743cc3 100644 --- a/console/program/src/data/record/to_commitment.rs +++ b/console/program/src/data/record/to_commitment.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/record/to_fields.rs b/console/program/src/data/record/to_fields.rs index 3a33a36e4f..a247bb3036 100644 --- a/console/program/src/data/record/to_fields.rs +++ b/console/program/src/data/record/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/register/bytes.rs b/console/program/src/data/register/bytes.rs index 0d24be259e..cca45a6224 100644 --- a/console/program/src/data/register/bytes.rs +++ b/console/program/src/data/register/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/register/mod.rs b/console/program/src/data/register/mod.rs index 7b17c38b90..adbd9bb7bd 100644 --- a/console/program/src/data/register/mod.rs +++ b/console/program/src/data/register/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -57,9 +58,9 @@ impl PartialOrd for Register { mod tests { use super::*; use crate::{Identifier, U32}; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_register_partial_ord() -> Result<()> { diff --git a/console/program/src/data/register/parse.rs b/console/program/src/data/register/parse.rs index 714bf0a700..d784867d42 100644 --- a/console/program/src/data/register/parse.rs +++ b/console/program/src/data/register/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -88,9 +89,9 @@ impl Display for Register { mod tests { use super::*; use crate::{Identifier, U32}; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_register_display() -> Result<()> { // Register::Locator diff --git a/console/program/src/data/register/serialize.rs b/console/program/src/data/register/serialize.rs index a2835884ff..e7c541299c 100644 --- a/console/program/src/data/register/serialize.rs +++ b/console/program/src/data/register/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for Register { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; fn check_serde_json< T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes, diff --git a/console/program/src/data/value/bytes.rs b/console/program/src/data/value/bytes.rs index 50e8567f05..a3b800a2ea 100644 --- a/console/program/src/data/value/bytes.rs +++ b/console/program/src/data/value/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -53,9 +54,9 @@ impl ToBytes for Value { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_value_plaintext_bytes() -> Result<()> { diff --git a/console/program/src/data/value/equal.rs b/console/program/src/data/value/equal.rs index b872f9953a..4aaaded955 100644 --- a/console/program/src/data/value/equal.rs +++ b/console/program/src/data/value/equal.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/value/find.rs b/console/program/src/data/value/find.rs index d5852bd95f..e0f8334c02 100644 --- a/console/program/src/data/value/find.rs +++ b/console/program/src/data/value/find.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/value/mod.rs b/console/program/src/data/value/mod.rs index c63ae9a87e..cac22c45a0 100644 --- a/console/program/src/data/value/mod.rs +++ b/console/program/src/data/value/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/value/parse.rs b/console/program/src/data/value/parse.rs index 9186c5bae4..681cd194ce 100644 --- a/console/program/src/data/value/parse.rs +++ b/console/program/src/data/value/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -66,9 +67,9 @@ impl Display for Value { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_value_plaintext_parse() { diff --git a/console/program/src/data/value/serialize.rs b/console/program/src/data/value/serialize.rs index ed8d175b2c..0773c45be8 100644 --- a/console/program/src/data/value/serialize.rs +++ b/console/program/src/data/value/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for Value { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_serde_json() -> Result<()> { diff --git a/console/program/src/data/value/to_bits.rs b/console/program/src/data/value/to_bits.rs index a11f7d27b4..0783a9ed93 100644 --- a/console/program/src/data/value/to_bits.rs +++ b/console/program/src/data/value/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data/value/to_fields.rs b/console/program/src/data/value/to_fields.rs index 8c8898a430..3124772ff2 100644 --- a/console/program/src/data/value/to_fields.rs +++ b/console/program/src/data/value/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/array_type/bytes.rs b/console/program/src/data_types/array_type/bytes.rs index b01482ad4d..83b8bdd693 100644 --- a/console/program/src/data_types/array_type/bytes.rs +++ b/console/program/src/data_types/array_type/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -103,7 +104,7 @@ impl ToBytes for ArrayType { mod tests { use super::*; - type CurrentNetwork = snarkvm_console_network::Testnet3; + type CurrentNetwork = snarkvm_console_network::MainnetV0; #[test] fn test_array_maximum_depth() { diff --git a/console/program/src/data_types/array_type/mod.rs b/console/program/src/data_types/array_type/mod.rs index 9680c28517..618d547dae 100644 --- a/console/program/src/data_types/array_type/mod.rs +++ b/console/program/src/data_types/array_type/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -91,11 +92,11 @@ impl ArrayType { mod tests { use super::*; use crate::{Identifier, LiteralType}; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; use core::str::FromStr; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_array_type() -> Result<()> { diff --git a/console/program/src/data_types/array_type/parse.rs b/console/program/src/data_types/array_type/parse.rs index 4f6fdc75c0..f3cefb3fb7 100644 --- a/console/program/src/data_types/array_type/parse.rs +++ b/console/program/src/data_types/array_type/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/array_type/serialize.rs b/console/program/src/data_types/array_type/serialize.rs index 425b243f58..4e7b3eb000 100644 --- a/console/program/src/data_types/array_type/serialize.rs +++ b/console/program/src/data_types/array_type/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,7 +38,7 @@ impl<'de, N: Network> Deserialize<'de> for ArrayType { #[cfg(test)] pub(crate) mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; /// Add test cases here to be checked for serialization. pub(crate) const TEST_CASES: &[&str] = &[ @@ -100,14 +101,14 @@ pub(crate) mod tests { #[test] fn test_serde_json() { for case in TEST_CASES.iter() { - check_serde_json(ArrayType::::from_str(case).unwrap()); + check_serde_json(ArrayType::::from_str(case).unwrap()); } } #[test] fn test_bincode() { for case in TEST_CASES.iter() { - check_bincode(ArrayType::::from_str(case).unwrap()); + check_bincode(ArrayType::::from_str(case).unwrap()); } } } diff --git a/console/program/src/data_types/finalize_type/bytes.rs b/console/program/src/data_types/finalize_type/bytes.rs index b8f21e770f..a49cf1ec8a 100644 --- a/console/program/src/data_types/finalize_type/bytes.rs +++ b/console/program/src/data_types/finalize_type/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/finalize_type/mod.rs b/console/program/src/data_types/finalize_type/mod.rs index 3e025482b3..2eb03d0f20 100644 --- a/console/program/src/data_types/finalize_type/mod.rs +++ b/console/program/src/data_types/finalize_type/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/finalize_type/parse.rs b/console/program/src/data_types/finalize_type/parse.rs index 7ab5ef9421..9724cf0c5b 100644 --- a/console/program/src/data_types/finalize_type/parse.rs +++ b/console/program/src/data_types/finalize_type/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -65,9 +66,9 @@ impl Display for FinalizeType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { diff --git a/console/program/src/data_types/finalize_type/serialize.rs b/console/program/src/data_types/finalize_type/serialize.rs index db0e58dfd1..4f9e745c5d 100644 --- a/console/program/src/data_types/finalize_type/serialize.rs +++ b/console/program/src/data_types/finalize_type/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for FinalizeType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Add test cases here to be checked for serialization. const TEST_CASES: &[&str] = &[ diff --git a/console/program/src/data_types/literal_type/bytes.rs b/console/program/src/data_types/literal_type/bytes.rs index 145b312db4..3442e9523d 100644 --- a/console/program/src/data_types/literal_type/bytes.rs +++ b/console/program/src/data_types/literal_type/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/literal_type/mod.rs b/console/program/src/data_types/literal_type/mod.rs index cb5e4dae49..8f1fcab4f0 100644 --- a/console/program/src/data_types/literal_type/mod.rs +++ b/console/program/src/data_types/literal_type/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,14 +16,19 @@ mod bytes; mod parse; mod serialize; +mod size_in_bits; +mod size_in_bytes; +use snarkvm_console_account::Signature; use snarkvm_console_network::prelude::*; +use snarkvm_console_types::{Boolean, prelude::*}; use core::fmt::{self, Debug, Display}; +use enum_iterator::Sequence; use num_derive::FromPrimitive; use num_traits::FromPrimitive; -#[derive(Copy, Clone, PartialEq, Eq, Hash, FromPrimitive)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, FromPrimitive, Sequence)] pub enum LiteralType { /// The Aleo address type. Address, @@ -62,7 +68,7 @@ pub enum LiteralType { impl LiteralType { /// Returns the literal type name. - pub fn type_name(&self) -> &str { + pub const fn type_name(&self) -> &str { match self { Self::Address => "address", Self::Boolean => "boolean", diff --git a/console/program/src/data_types/literal_type/parse.rs b/console/program/src/data_types/literal_type/parse.rs index 806eee0dc2..ecb1347bfe 100644 --- a/console/program/src/data_types/literal_type/parse.rs +++ b/console/program/src/data_types/literal_type/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,23 +21,23 @@ impl Parser for LiteralType { fn parse(string: &str) -> ParserResult { // Parse the type from the string. alt(( - map(tag("address"), |_| Self::Address), - map(tag("boolean"), |_| Self::Boolean), - map(tag("field"), |_| Self::Field), - map(tag("group"), |_| Self::Group), - map(tag("i8"), |_| Self::I8), - map(tag("i16"), |_| Self::I16), - map(tag("i32"), |_| Self::I32), - map(tag("i64"), |_| Self::I64), - map(tag("i128"), |_| Self::I128), - map(tag("u8"), |_| Self::U8), - map(tag("u16"), |_| Self::U16), - map(tag("u32"), |_| Self::U32), - map(tag("u64"), |_| Self::U64), - map(tag("u128"), |_| Self::U128), - map(tag("scalar"), |_| Self::Scalar), - map(tag("signature"), |_| Self::Signature), - map(tag("string"), |_| Self::String), + map(tag(Self::Address.type_name()), |_| Self::Address), + map(tag(Self::Boolean.type_name()), |_| Self::Boolean), + map(tag(Self::Field.type_name()), |_| Self::Field), + map(tag(Self::Group.type_name()), |_| Self::Group), + map(tag(Self::I8.type_name()), |_| Self::I8), + map(tag(Self::I16.type_name()), |_| Self::I16), + map(tag(Self::I32.type_name()), |_| Self::I32), + map(tag(Self::I64.type_name()), |_| Self::I64), + map(tag(Self::I128.type_name()), |_| Self::I128), + map(tag(Self::U8.type_name()), |_| Self::U8), + map(tag(Self::U16.type_name()), |_| Self::U16), + map(tag(Self::U32.type_name()), |_| Self::U32), + map(tag(Self::U64.type_name()), |_| Self::U64), + map(tag(Self::U128.type_name()), |_| Self::U128), + map(tag(Self::Scalar.type_name()), |_| Self::Scalar), + map(tag(Self::Signature.type_name()), |_| Self::Signature), + map(tag(Self::String.type_name()), |_| Self::String), ))(string) } } diff --git a/console/program/src/data_types/literal_type/serialize.rs b/console/program/src/data_types/literal_type/serialize.rs index 4bc21d6376..22ae04f7f0 100644 --- a/console/program/src/data_types/literal_type/serialize.rs +++ b/console/program/src/data_types/literal_type/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/literal_type/size_in_bits.rs b/console/program/src/data_types/literal_type/size_in_bits.rs new file mode 100644 index 0000000000..7b64d2fb22 --- /dev/null +++ b/console/program/src/data_types/literal_type/size_in_bits.rs @@ -0,0 +1,44 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl LiteralType { + /// Returns the number of bits of this literal type. + /// + /// For string literals, this method returns the maximum number of bits that can be stored in the string. + pub fn size_in_bits(&self) -> u16 { + let size = match self { + Self::Address => Address::::size_in_bits(), + Self::Boolean => Boolean::::size_in_bits(), + Self::Field => Field::::size_in_bits(), + Self::Group => Group::::size_in_bits(), + Self::I8 => I8::::size_in_bits(), + Self::I16 => I16::::size_in_bits(), + Self::I32 => I32::::size_in_bits(), + Self::I64 => I64::::size_in_bits(), + Self::I128 => I128::::size_in_bits(), + Self::U8 => U8::::size_in_bits(), + Self::U16 => U16::::size_in_bits(), + Self::U32 => U32::::size_in_bits(), + Self::U64 => U64::::size_in_bits(), + Self::U128 => U128::::size_in_bits(), + Self::Scalar => Scalar::::size_in_bits(), + Self::Signature => Signature::::size_in_bits(), + Self::String => N::MAX_STRING_BYTES.saturating_mul(8) as usize, + }; + u16::try_from(size).or_halt_with::("Literal exceeds u16::MAX bits.") + } +} diff --git a/console/program/src/data_types/literal_type/size_in_bytes.rs b/console/program/src/data_types/literal_type/size_in_bytes.rs new file mode 100644 index 0000000000..28d064b415 --- /dev/null +++ b/console/program/src/data_types/literal_type/size_in_bytes.rs @@ -0,0 +1,29 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl LiteralType { + /// Returns the number of bytes of this literal. + /// + /// For string literals, this method returns the maximum number of bytes that can be stored in the string. + #[allow(clippy::cast_possible_truncation)] + pub fn size_in_bytes(&self) -> u16 { + // Note: This upcast to u32 and downcast to u16 is safe because the size of a literal is + // always less than or equal to u16::MAX bits, and we are dividing by 8, so the result will + // always fit in a u16. + (((self.size_in_bits::() as u32) + 7) / 8) as u16 + } +} diff --git a/console/program/src/data_types/mod.rs b/console/program/src/data_types/mod.rs index f86dee506d..acc93c9a4f 100644 --- a/console/program/src/data_types/mod.rs +++ b/console/program/src/data_types/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -34,4 +35,4 @@ mod struct_type; pub use struct_type::StructType; mod value_type; -pub use value_type::ValueType; +pub use value_type::{ValueType, Variant}; diff --git a/console/program/src/data_types/plaintext_type/bytes.rs b/console/program/src/data_types/plaintext_type/bytes.rs index 0b3d5c92d2..c2ed22f16e 100644 --- a/console/program/src/data_types/plaintext_type/bytes.rs +++ b/console/program/src/data_types/plaintext_type/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/plaintext_type/mod.rs b/console/program/src/data_types/plaintext_type/mod.rs index dfc6e05f76..24603d6a56 100644 --- a/console/program/src/data_types/plaintext_type/mod.rs +++ b/console/program/src/data_types/plaintext_type/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/plaintext_type/parse.rs b/console/program/src/data_types/plaintext_type/parse.rs index 21474fc5e6..83a1850f1e 100644 --- a/console/program/src/data_types/plaintext_type/parse.rs +++ b/console/program/src/data_types/plaintext_type/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,8 +22,8 @@ impl Parser for PlaintextType { // Parse to determine the plaintext type (order matters). alt(( map(ArrayType::parse, |type_| Self::Array(type_)), - map(LiteralType::parse, |type_| Self::Literal(type_)), map(Identifier::parse, |identifier| Self::Struct(identifier)), + map(LiteralType::parse, |type_| Self::Literal(type_)), ))(string) } } @@ -68,9 +69,9 @@ impl Display for PlaintextType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { @@ -86,6 +87,10 @@ mod tests { PlaintextType::parse("foo"), Ok(("", PlaintextType::::Struct(Identifier::from_str("foo")?))) ); + assert_eq!( + PlaintextType::parse("u8jdsklaj"), + Ok(("", PlaintextType::::Struct(Identifier::from_str("u8jdsklaj")?))) + ); assert_eq!( PlaintextType::parse("[field; 1u32]"), Ok(("", PlaintextType::::Array(ArrayType::from_str("[field; 1u32]")?))) diff --git a/console/program/src/data_types/plaintext_type/serialize.rs b/console/program/src/data_types/plaintext_type/serialize.rs index c9d602016c..0b9fe5f5ac 100644 --- a/console/program/src/data_types/plaintext_type/serialize.rs +++ b/console/program/src/data_types/plaintext_type/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for PlaintextType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Add test cases here to be checked for serialization. const TEST_CASES: &[&str] = &[ diff --git a/console/program/src/data_types/record_type/bytes.rs b/console/program/src/data_types/record_type/bytes.rs index 0848fd93ef..5d36224ebb 100644 --- a/console/program/src/data_types/record_type/bytes.rs +++ b/console/program/src/data_types/record_type/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -88,9 +89,9 @@ impl ToBytes for RecordType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { diff --git a/console/program/src/data_types/record_type/entry_type/bytes.rs b/console/program/src/data_types/record_type/entry_type/bytes.rs index 4ae5e9c76e..8d8b7bade7 100644 --- a/console/program/src/data_types/record_type/entry_type/bytes.rs +++ b/console/program/src/data_types/record_type/entry_type/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/record_type/entry_type/mod.rs b/console/program/src/data_types/record_type/entry_type/mod.rs index 03d2657cab..411ed34250 100644 --- a/console/program/src/data_types/record_type/entry_type/mod.rs +++ b/console/program/src/data_types/record_type/entry_type/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/record_type/entry_type/parse.rs b/console/program/src/data_types/record_type/entry_type/parse.rs index 587517b1f0..6eb364a5d2 100644 --- a/console/program/src/data_types/record_type/entry_type/parse.rs +++ b/console/program/src/data_types/record_type/entry_type/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -65,9 +66,9 @@ impl Display for EntryType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { diff --git a/console/program/src/data_types/record_type/entry_type/serialize.rs b/console/program/src/data_types/record_type/entry_type/serialize.rs index a042781a7f..e6f14211b1 100644 --- a/console/program/src/data_types/record_type/entry_type/serialize.rs +++ b/console/program/src/data_types/record_type/entry_type/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for EntryType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Add test cases here to be checked for serialization. const TEST_CASES: &[&str] = &[ diff --git a/console/program/src/data_types/record_type/helpers/mod.rs b/console/program/src/data_types/record_type/helpers/mod.rs index 74f9493c56..ac523beb4a 100644 --- a/console/program/src/data_types/record_type/helpers/mod.rs +++ b/console/program/src/data_types/record_type/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/record_type/mod.rs b/console/program/src/data_types/record_type/mod.rs index d78438e843..263491dd11 100644 --- a/console/program/src/data_types/record_type/mod.rs +++ b/console/program/src/data_types/record_type/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/record_type/parse.rs b/console/program/src/data_types/record_type/parse.rs index fae51218c2..2cae3cd801 100644 --- a/console/program/src/data_types/record_type/parse.rs +++ b/console/program/src/data_types/record_type/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -134,9 +135,9 @@ impl Display for RecordType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { diff --git a/console/program/src/data_types/record_type/serialize.rs b/console/program/src/data_types/record_type/serialize.rs index ea56b08bee..b546518174 100644 --- a/console/program/src/data_types/record_type/serialize.rs +++ b/console/program/src/data_types/record_type/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for RecordType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Add test cases here to be checked for serialization. const TEST_CASES: &[&str] = diff --git a/console/program/src/data_types/register_type/bytes.rs b/console/program/src/data_types/register_type/bytes.rs index c2d939ca1b..345aeda4cf 100644 --- a/console/program/src/data_types/register_type/bytes.rs +++ b/console/program/src/data_types/register_type/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/register_type/mod.rs b/console/program/src/data_types/register_type/mod.rs index f8a0c856ca..9e745263e6 100644 --- a/console/program/src/data_types/register_type/mod.rs +++ b/console/program/src/data_types/register_type/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/register_type/parse.rs b/console/program/src/data_types/register_type/parse.rs index ec4bbcef58..9e9ea58ddd 100644 --- a/console/program/src/data_types/register_type/parse.rs +++ b/console/program/src/data_types/register_type/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -71,9 +72,9 @@ impl Display for RegisterType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { @@ -88,6 +89,10 @@ mod tests { Ok(("", RegisterType::::Plaintext(PlaintextType::from_str("signature")?))), RegisterType::::parse("signature") ); + assert_eq!( + Ok(("", RegisterType::::Plaintext(PlaintextType::from_str("u8kldsafj")?))), + RegisterType::::parse("u8kldsafj") + ); // Record type. assert_eq!( diff --git a/console/program/src/data_types/register_type/serialize.rs b/console/program/src/data_types/register_type/serialize.rs index b4b526ef36..bb244a8513 100644 --- a/console/program/src/data_types/register_type/serialize.rs +++ b/console/program/src/data_types/register_type/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for RegisterType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Add test cases here to be checked for serialization. const TEST_CASES: &[&str] = &[ diff --git a/console/program/src/data_types/struct_type/bytes.rs b/console/program/src/data_types/struct_type/bytes.rs index e7b9c31856..da237669b5 100644 --- a/console/program/src/data_types/struct_type/bytes.rs +++ b/console/program/src/data_types/struct_type/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -73,9 +74,9 @@ impl ToBytes for StructType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { diff --git a/console/program/src/data_types/struct_type/mod.rs b/console/program/src/data_types/struct_type/mod.rs index 1529ed7634..ca6b7e691f 100644 --- a/console/program/src/data_types/struct_type/mod.rs +++ b/console/program/src/data_types/struct_type/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/struct_type/parse.rs b/console/program/src/data_types/struct_type/parse.rs index 1b606a749f..66d80fe347 100644 --- a/console/program/src/data_types/struct_type/parse.rs +++ b/console/program/src/data_types/struct_type/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -114,9 +115,9 @@ impl Display for StructType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { diff --git a/console/program/src/data_types/struct_type/serialize.rs b/console/program/src/data_types/struct_type/serialize.rs index 4d813a02f7..96660170bf 100644 --- a/console/program/src/data_types/struct_type/serialize.rs +++ b/console/program/src/data_types/struct_type/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for StructType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Add test cases here to be checked for serialization. const TEST_CASES: &[&str] = &["struct message: owner as address; is_new as boolean; total_supply as u64;"]; diff --git a/console/program/src/data_types/value_type/bytes.rs b/console/program/src/data_types/value_type/bytes.rs index 5fa6cdce9c..1b9504386c 100644 --- a/console/program/src/data_types/value_type/bytes.rs +++ b/console/program/src/data_types/value_type/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/data_types/value_type/mod.rs b/console/program/src/data_types/value_type/mod.rs index 9e0c8350d8..136f593b98 100644 --- a/console/program/src/data_types/value_type/mod.rs +++ b/console/program/src/data_types/value_type/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,6 +22,8 @@ use snarkvm_console_network::prelude::*; use enum_index::EnumIndex; +pub type Variant = u8; + #[derive(Clone, PartialEq, Eq, Hash, EnumIndex)] pub enum ValueType { /// A constant type. @@ -37,6 +40,20 @@ pub enum ValueType { Future(Locator), } +impl ValueType { + /// Returns the variant of the value type. + pub const fn variant(&self) -> Variant { + match self { + ValueType::Constant(..) => 0, + ValueType::Public(..) => 1, + ValueType::Private(..) => 2, + ValueType::Record(..) => 3, + ValueType::ExternalRecord(..) => 4, + ValueType::Future(..) => 5, + } + } +} + impl From> for ValueType { fn from(entry: EntryType) -> Self { match entry { diff --git a/console/program/src/data_types/value_type/parse.rs b/console/program/src/data_types/value_type/parse.rs index a9198179d4..c744ee84b0 100644 --- a/console/program/src/data_types/value_type/parse.rs +++ b/console/program/src/data_types/value_type/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -72,9 +73,9 @@ impl Display for ValueType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { @@ -105,6 +106,10 @@ mod tests { Ok(("", ValueType::::from_str("signature.private")?)), ValueType::::parse("signature.private") ); + assert_eq!( + Ok(("", ValueType::::from_str("i8abc.constant")?)), + ValueType::::parse("i8abc.constant") + ); // Record type. assert_eq!( diff --git a/console/program/src/data_types/value_type/serialize.rs b/console/program/src/data_types/value_type/serialize.rs index d57c7c170f..3975a9f2d9 100644 --- a/console/program/src/data_types/value_type/serialize.rs +++ b/console/program/src/data_types/value_type/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for ValueType { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Add test cases here to be checked for serialization. const TEST_CASES: &[&str] = &[ diff --git a/console/program/src/function_id/mod.rs b/console/program/src/function_id/mod.rs new file mode 100644 index 0000000000..6848822afc --- /dev/null +++ b/console/program/src/function_id/mod.rs @@ -0,0 +1,40 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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::{Identifier, ProgramID}; +use snarkvm_console_account::ToBits; +use snarkvm_console_algorithms::Result; +use snarkvm_console_network::Network; +use snarkvm_console_types::{Field, U8, U16}; + +/// Compute the function ID as `Hash(network_id, program_id.len(), program_id, function_name.len(), function_name)`. +pub fn compute_function_id( + network_id: &U16, + program_id: &ProgramID, + function_name: &Identifier, +) -> Result> { + N::hash_bhp1024( + &( + *network_id, + U8::::new(program_id.name().size_in_bits()), + program_id.name(), + U8::::new(program_id.network().size_in_bits()), + program_id.network(), + U8::::new(function_name.size_in_bits()), + function_name, + ) + .to_bits_le(), + ) +} diff --git a/console/program/src/id/bytes.rs b/console/program/src/id/bytes.rs index a3f50c772c..0245ec3e72 100644 --- a/console/program/src/id/bytes.rs +++ b/console/program/src/id/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/id/mod.rs b/console/program/src/id/mod.rs index 4bab9a0886..2941febab9 100644 --- a/console/program/src/id/mod.rs +++ b/console/program/src/id/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -151,9 +152,9 @@ impl Equal for ProgramID { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_partial_ord() -> Result<()> { diff --git a/console/program/src/id/parse.rs b/console/program/src/id/parse.rs index 86e3498fc0..9f1f58fc72 100644 --- a/console/program/src/id/parse.rs +++ b/console/program/src/id/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -61,9 +62,9 @@ impl Display for ProgramID { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { diff --git a/console/program/src/id/serialize.rs b/console/program/src/id/serialize.rs index 76180a25a7..debab9eb1c 100644 --- a/console/program/src/id/serialize.rs +++ b/console/program/src/id/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for ProgramID { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Add test cases here to be checked for serialization. const TEST_CASES: &[&str] = &["testing.aleo", "hello.aleo", "abc_def.aleo", "a1234.aleo"]; diff --git a/console/program/src/id/to_address.rs b/console/program/src/id/to_address.rs index 9eceaac445..665aa34338 100644 --- a/console/program/src/id/to_address.rs +++ b/console/program/src/id/to_address.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/id/to_bits.rs b/console/program/src/id/to_bits.rs index a34dcd689d..8ed486dad7 100644 --- a/console/program/src/id/to_bits.rs +++ b/console/program/src/id/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -44,9 +45,9 @@ impl ToBits for &ProgramID { mod tests { use super::*; use crate::data::identifier::tests::sample_lowercase_identifier_as_string; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/program/src/id/to_fields.rs b/console/program/src/id/to_fields.rs index 85b1c9aac0..b3af51185d 100644 --- a/console/program/src/id/to_fields.rs +++ b/console/program/src/id/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/lib.rs b/console/program/src/lib.rs index 8547b46694..c648a3c703 100644 --- a/console/program/src/lib.rs +++ b/console/program/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -30,6 +31,9 @@ pub use data::*; mod data_types; pub use data_types::*; +mod function_id; +pub use function_id::*; + mod id; pub use id::*; diff --git a/console/program/src/locator/bytes.rs b/console/program/src/locator/bytes.rs index f10aca712a..2f2268a965 100644 --- a/console/program/src/locator/bytes.rs +++ b/console/program/src/locator/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/locator/mod.rs b/console/program/src/locator/mod.rs index f4552b613c..da7f133628 100644 --- a/console/program/src/locator/mod.rs +++ b/console/program/src/locator/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/locator/parse.rs b/console/program/src/locator/parse.rs index 129bd89e0f..12a8d326a4 100644 --- a/console/program/src/locator/parse.rs +++ b/console/program/src/locator/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -62,9 +63,9 @@ impl Display for Locator { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_import_parse() -> Result<()> { diff --git a/console/program/src/locator/serialize.rs b/console/program/src/locator/serialize.rs index ab25677216..bb9932eedd 100644 --- a/console/program/src/locator/serialize.rs +++ b/console/program/src/locator/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for Locator { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Add test cases here to be checked for serialization. const TEST_CASES: &[&str] = &["testing.aleo/abc", "hello.aleo/u1r02r", "hello_world.aleo/foo", "foo123.aleo/run"]; diff --git a/console/program/src/locator/to_fields.rs b/console/program/src/locator/to_fields.rs index d60472b481..69e92fbfb7 100644 --- a/console/program/src/locator/to_fields.rs +++ b/console/program/src/locator/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/owner/bytes.rs b/console/program/src/owner/bytes.rs index edffec5844..0328ed9cc8 100644 --- a/console/program/src/owner/bytes.rs +++ b/console/program/src/owner/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -49,9 +50,9 @@ impl ToBytes for ProgramOwner { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { diff --git a/console/program/src/owner/mod.rs b/console/program/src/owner/mod.rs index 96a532cd4c..6a3fe985e0 100644 --- a/console/program/src/owner/mod.rs +++ b/console/program/src/owner/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -63,11 +64,11 @@ impl ProgramOwner { #[cfg(test)] pub(crate) mod test_helpers { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; use once_cell::sync::OnceCell; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; pub(crate) fn sample_program_owner() -> ProgramOwner { static INSTANCE: OnceCell> = OnceCell::new(); diff --git a/console/program/src/owner/serialize.rs b/console/program/src/owner/serialize.rs index da1cb92f90..3b9cf8ddb5 100644 --- a/console/program/src/owner/serialize.rs +++ b/console/program/src/owner/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/owner/string.rs b/console/program/src/owner/string.rs index 9f0719ef44..28a0f222ef 100644 --- a/console/program/src/owner/string.rs +++ b/console/program/src/owner/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/request/bytes.rs b/console/program/src/request/bytes.rs index ec664b9c48..0dd91fa9d0 100644 --- a/console/program/src/request/bytes.rs +++ b/console/program/src/request/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -48,8 +49,22 @@ impl FromBytes for Request { let tvk = FromBytes::read_le(&mut reader)?; // Read the transition commitment. let tcm = FromBytes::read_le(&mut reader)?; - - Ok(Self::from((signer, network_id, program_id, function_name, input_ids, inputs, signature, sk_tag, tvk, tcm))) + // Read the signer commitment. + let scm = FromBytes::read_le(&mut reader)?; + + Ok(Self::from(( + signer, + network_id, + program_id, + function_name, + input_ids, + inputs, + signature, + sk_tag, + tvk, + tcm, + scm, + ))) } } @@ -93,7 +108,9 @@ impl ToBytes for Request { // Write the transition view key. self.tvk.write_le(&mut writer)?; // Write the transition commitment. - self.tcm.write_le(&mut writer) + self.tcm.write_le(&mut writer)?; + // Write the signer commitment. + self.scm.write_le(&mut writer) } } diff --git a/console/program/src/request/input_id/bytes.rs b/console/program/src/request/input_id/bytes.rs index e0fafca73a..e55562c1a4 100644 --- a/console/program/src/request/input_id/bytes.rs +++ b/console/program/src/request/input_id/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/request/input_id/mod.rs b/console/program/src/request/input_id/mod.rs index dbca723728..72151123d5 100644 --- a/console/program/src/request/input_id/mod.rs +++ b/console/program/src/request/input_id/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/request/input_id/serialize.rs b/console/program/src/request/input_id/serialize.rs index 0a74b0874e..94414f5a89 100644 --- a/console/program/src/request/input_id/serialize.rs +++ b/console/program/src/request/input_id/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -93,9 +94,9 @@ impl<'de, N: Network> Deserialize<'de> for InputID { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Add test cases here to be checked for serialization. const TEST_CASES: &[&str] = &[ diff --git a/console/program/src/request/input_id/string.rs b/console/program/src/request/input_id/string.rs index b0cfc53652..c2f759e0ed 100644 --- a/console/program/src/request/input_id/string.rs +++ b/console/program/src/request/input_id/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/request/mod.rs b/console/program/src/request/mod.rs index 9fa69a0d95..b9ca501e45 100644 --- a/console/program/src/request/mod.rs +++ b/console/program/src/request/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,7 +22,7 @@ mod sign; mod string; mod verify; -use crate::{Identifier, Plaintext, ProgramID, Record, Value, ValueType}; +use crate::{Identifier, Plaintext, ProgramID, Record, Value, ValueType, compute_function_id}; use snarkvm_console_account::{Address, ComputeKey, GraphKey, PrivateKey, Signature, ViewKey}; use snarkvm_console_network::Network; use snarkvm_console_types::prelude::*; @@ -48,6 +49,8 @@ pub struct Request { tvk: Field, /// The transition commitment. tcm: Field, + /// The signer commitment. + scm: Field, } impl @@ -62,11 +65,12 @@ impl Field, Field, Field, + Field, )> for Request { /// Note: See `Request::sign` to create the request. This method is used to eject from a circuit. fn from( - (signer, network_id, program_id, function_name, input_ids, inputs, signature, sk_tag, tvk, tcm): ( + (signer, network_id, program_id, function_name, input_ids, inputs, signature, sk_tag, tvk, tcm, scm): ( Address, U16, ProgramID, @@ -77,13 +81,14 @@ impl Field, Field, Field, + Field, ), ) -> Self { // Ensure the network ID is correct. if *network_id != N::ID { N::halt(format!("Invalid network ID. Expected {}, found {}", N::ID, *network_id)) } else { - Self { signer, network_id, program_id, function_name, input_ids, inputs, signature, sk_tag, tvk, tcm } + Self { signer, network_id, program_id, function_name, input_ids, inputs, signature, sk_tag, tvk, tcm, scm } } } } @@ -150,14 +155,19 @@ impl Request { pub const fn tcm(&self) -> &Field { &self.tcm } + + /// Returns the signer commitment `scm`. + pub const fn scm(&self) -> &Field { + &self.scm + } } #[cfg(test)] mod test_helpers { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1000; @@ -184,6 +194,9 @@ mod test_helpers { let input_external_record = Value::from_str(&record_string).unwrap(); let inputs = vec![input_constant, input_public, input_private, input_record, input_external_record]; + // Construct 'is_root'. + let is_root = false; + // Construct the input types. let input_types = [ ValueType::from_str("amount.constant").unwrap(), @@ -193,10 +206,13 @@ mod test_helpers { ValueType::from_str("token.aleo/token.record").unwrap(), ]; + // Sample root_tvk. + let root_tvk = None; + // Compute the signed request. let request = - Request::sign(&private_key, program_id, function_name, inputs.into_iter(), &input_types, rng).unwrap(); - assert!(request.verify(&input_types)); + Request::sign(&private_key, program_id, function_name, inputs.into_iter(), &input_types, root_tvk, is_root, rng).unwrap(); + assert!(request.verify(&input_types, is_root)); request }) .collect() diff --git a/console/program/src/request/serialize.rs b/console/program/src/request/serialize.rs index 905b67d991..dff86791fa 100644 --- a/console/program/src/request/serialize.rs +++ b/console/program/src/request/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,7 +22,7 @@ impl Serialize for Request { fn serialize(&self, serializer: S) -> Result { match serializer.is_human_readable() { true => { - let mut transition = serializer.serialize_struct("Request", 10)?; + let mut transition = serializer.serialize_struct("Request", 11)?; transition.serialize_field("signer", &self.signer)?; transition.serialize_field("network", &self.network_id)?; transition.serialize_field("program", &self.program_id)?; @@ -32,6 +33,7 @@ impl Serialize for Request { transition.serialize_field("sk_tag", &self.sk_tag)?; transition.serialize_field("tvk", &self.tvk)?; transition.serialize_field("tcm", &self.tcm)?; + transition.serialize_field("scm", &self.scm)?; transition.end() } false => ToBytesSerializer::serialize_with_size_encoding(self, serializer), @@ -68,6 +70,8 @@ impl<'de, N: Network> Deserialize<'de> for Request { DeserializeExt::take_from_value::(&mut request, "tvk")?, // Retrieve the `tcm`. DeserializeExt::take_from_value::(&mut request, "tcm")?, + // Retrieve the `scm`. + DeserializeExt::take_from_value::(&mut request, "scm")?, ))) } false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "request"), diff --git a/console/program/src/request/sign.rs b/console/program/src/request/sign.rs index c71c7fa56a..a886d64acd 100644 --- a/console/program/src/request/sign.rs +++ b/console/program/src/request/sign.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,6 +25,8 @@ impl Request { function_name: Identifier, inputs: impl ExactSizeIterator>>, input_types: &[ValueType], + root_tvk: Option>, + is_root: bool, rng: &mut R, ) -> Result { // Ensure the number of inputs matches the number of input types. @@ -63,16 +66,21 @@ impl Request { let tvk = (*signer * r).to_x_coordinate(); // Compute the transition commitment `tcm` as `Hash(tvk)`. let tcm = N::hash_psd2(&[tvk])?; + // Compute the signer commitment `scm` as `Hash(signer || root_tvk)`. + let root_tvk = root_tvk.unwrap_or(tvk); + let scm = N::hash_psd2(&[signer.deref().to_x_coordinate(), root_tvk])?; + // Compute 'is_root' as a field element. + let is_root = if is_root { Field::::one() } else { Field::::zero() }; - // Compute the function ID as `Hash(network_id, program_id, function_name)`. - let function_id = N::hash_bhp1024( - &(U16::::new(N::ID), program_id.name(), program_id.network(), function_name).to_bits_le(), - )?; + // Retrieve the network ID. + let network_id = U16::new(N::ID); + // Compute the function ID. + let function_id = compute_function_id(&network_id, &program_id, &function_name)?; // Construct the hash input as `(r * G, pk_sig, pr_sig, signer, [tvk, tcm, function ID, input IDs])`. let mut message = Vec::with_capacity(9 + 2 * inputs.len()); message.extend([g_r, pk_sig, pr_sig, *signer].map(|point| point.to_x_coordinate())); - message.extend([tvk, tcm, function_id]); + message.extend([tvk, tcm, function_id, is_root]); // Initialize a vector to store the prepared inputs. let mut prepared_inputs = Vec::with_capacity(inputs.len()); @@ -222,7 +230,7 @@ impl Request { Ok(Self { signer, - network_id: U16::new(N::ID), + network_id, program_id, function_name, input_ids, @@ -231,6 +239,7 @@ impl Request { sk_tag, tvk, tcm, + scm, }) } } diff --git a/console/program/src/request/string.rs b/console/program/src/request/string.rs index d7179721cf..1165cd86e0 100644 --- a/console/program/src/request/string.rs +++ b/console/program/src/request/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/request/verify.rs b/console/program/src/request/verify.rs index c1004818c4..15570ee289 100644 --- a/console/program/src/request/verify.rs +++ b/console/program/src/request/verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,7 +20,7 @@ impl Request { /// /// Verifies (challenge == challenge') && (address == address') && (serial_numbers == serial_numbers') where: /// challenge' := HashToScalar(r * G, pk_sig, pr_sig, signer, \[tvk, tcm, function ID, input IDs\]) - pub fn verify(&self, input_types: &[ValueType]) -> bool { + pub fn verify(&self, input_types: &[ValueType], is_root: bool) -> bool { // Verify the transition public key, transition view key, and transition commitment are well-formed. { // Compute the transition commitment `tcm` as `Hash(tvk)`. @@ -43,11 +44,8 @@ impl Request { // Retrieve the response from the signature. let response = self.signature.response(); - // Compute the function ID as `Hash(network_id, program_id, function_name)`. - let function_id = match N::hash_bhp1024( - &(U16::::new(N::ID), self.program_id.name(), self.program_id.network(), &self.function_name) - .to_bits_le(), - ) { + // Compute the function ID. + let function_id = match compute_function_id(&self.network_id, &self.program_id, &self.function_name) { Ok(function_id) => function_id, Err(error) => { eprintln!("Failed to construct the function ID: {error}"); @@ -55,11 +53,15 @@ impl Request { } }; + // Compute the 'is_root' field. + let is_root = if is_root { Field::::one() } else { Field::::zero() }; + // Construct the signature message as `[tvk, tcm, function ID, input IDs]`. let mut message = Vec::with_capacity(3 + self.input_ids.len()); message.push(self.tvk); message.push(self.tcm); message.push(function_id); + message.push(is_root); if let Err(error) = self.input_ids.iter().zip_eq(&self.inputs).zip_eq(input_types).enumerate().try_for_each( |(index, ((input_id, input), input_type))| { @@ -210,9 +212,9 @@ impl Request { mod tests { use super::*; use snarkvm_console_account::PrivateKey; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; pub(crate) const ITERATIONS: usize = 1000; @@ -251,10 +253,24 @@ mod tests { ValueType::from_str("token.aleo/token.record").unwrap(), ]; + // Sample 'root_tvk'. + let root_tvk = None; + // Sample 'is_root'. + let is_root = Uniform::rand(rng); + // Compute the signed request. - let request = - Request::sign(&private_key, program_id, function_name, inputs.into_iter(), &input_types, rng).unwrap(); - assert!(request.verify(&input_types)); + let request = Request::sign( + &private_key, + program_id, + function_name, + inputs.into_iter(), + &input_types, + root_tvk, + is_root, + rng, + ) + .unwrap(); + assert!(request.verify(&input_types, is_root)); } } } diff --git a/console/program/src/response/mod.rs b/console/program/src/response/mod.rs index 1c3d774b0b..6454192a36 100644 --- a/console/program/src/response/mod.rs +++ b/console/program/src/response/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{Identifier, ProgramID, Register, Value, ValueType}; +use crate::{Identifier, ProgramID, Register, Value, ValueType, compute_function_id}; use snarkvm_console_network::Network; use snarkvm_console_types::prelude::*; @@ -60,9 +61,8 @@ impl Response { output_types: &[ValueType], output_operands: &[Option>], ) -> Result { - // Compute the function ID as `Hash(network_id, program_id, function_name)`. - let function_id = - N::hash_bhp1024(&(*network_id, program_id.name(), program_id.network(), function_name).to_bits_le())?; + // Compute the function ID. + let function_id = compute_function_id(network_id, program_id, function_name)?; // Compute the output IDs. let output_ids = outputs diff --git a/console/program/src/state_path/bytes.rs b/console/program/src/state_path/bytes.rs index 13a42f96ff..fb98999329 100644 --- a/console/program/src/state_path/bytes.rs +++ b/console/program/src/state_path/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -94,9 +95,9 @@ impl ToBytes for StatePath { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/program/src/state_path/configuration/mod.rs b/console/program/src/state_path/configuration/mod.rs index b8ddef30cf..bc6939fa63 100644 --- a/console/program/src/state_path/configuration/mod.rs +++ b/console/program/src/state_path/configuration/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,14 +20,18 @@ use snarkvm_console_network::BHPMerkleTree; pub const BLOCKS_DEPTH: u8 = 32; /// The depth of the Merkle tree for the block header. pub const HEADER_DEPTH: u8 = 3; +/// The depth of the Merkle tree for finalize operations in a transaction. +pub const FINALIZE_ID_DEPTH: u8 = TRANSACTION_DEPTH + 4; // '+ 4' is to support 16 finalize operations per transition. /// The depth of the Merkle tree for finalize operations in a block. -pub const FINALIZE_OPERATIONS_DEPTH: u8 = 20; +pub const FINALIZE_OPERATIONS_DEPTH: u8 = TRANSACTIONS_DEPTH; /// The depth of the Merkle tree for the ratifications in a block. pub const RATIFICATIONS_DEPTH: u8 = 16; /// The depth the Merkle tree for the subdag certificates in a block. pub const SUBDAG_CERTIFICATES_DEPTH: u8 = 16; /// The depth of the Merkle tree for transactions in a block. -pub const TRANSACTIONS_DEPTH: u8 = 16; +/// Note: The technical limit is 2^20 - 1 transactions, to allow compatibility with the +/// finalize operations tree, which requires 1 leaf for the ratified finalize ID. +pub const TRANSACTIONS_DEPTH: u8 = 20; /// The depth of the Merkle tree for the transaction. pub const TRANSACTION_DEPTH: u8 = 5; /// The depth of the Merkle tree for the transition. @@ -67,7 +72,7 @@ mod tests { use super::*; use snarkvm_console_network::Network; - type CurrentNetwork = snarkvm_console_network::Testnet3; + type CurrentNetwork = snarkvm_console_network::MainnetV0; #[test] fn test_transaction_depth_is_correct() { diff --git a/console/program/src/state_path/header_leaf/bytes.rs b/console/program/src/state_path/header_leaf/bytes.rs index 16f2b03bca..2d4d85e546 100644 --- a/console/program/src/state_path/header_leaf/bytes.rs +++ b/console/program/src/state_path/header_leaf/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/header_leaf/mod.rs b/console/program/src/state_path/header_leaf/mod.rs index 1768af8046..b6ee91d308 100644 --- a/console/program/src/state_path/header_leaf/mod.rs +++ b/console/program/src/state_path/header_leaf/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -49,9 +50,9 @@ impl HeaderLeaf { #[cfg(test)] mod test_helpers { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; pub(super) fn sample_leaf(rng: &mut TestRng) -> HeaderLeaf { // Construct a new leaf. diff --git a/console/program/src/state_path/header_leaf/serialize.rs b/console/program/src/state_path/header_leaf/serialize.rs index 67dc881397..c332db8ad7 100644 --- a/console/program/src/state_path/header_leaf/serialize.rs +++ b/console/program/src/state_path/header_leaf/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/header_leaf/string.rs b/console/program/src/state_path/header_leaf/string.rs index e26ee3e8cb..d80da15dbe 100644 --- a/console/program/src/state_path/header_leaf/string.rs +++ b/console/program/src/state_path/header_leaf/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/header_leaf/to_bits.rs b/console/program/src/state_path/header_leaf/to_bits.rs index d12871ace3..d88b36a076 100644 --- a/console/program/src/state_path/header_leaf/to_bits.rs +++ b/console/program/src/state_path/header_leaf/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/mod.rs b/console/program/src/state_path/mod.rs index ce3b719d88..9666d0ef1b 100644 --- a/console/program/src/state_path/mod.rs +++ b/console/program/src/state_path/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/parse.rs b/console/program/src/state_path/parse.rs index de701da6b7..21edd0b8de 100644 --- a/console/program/src/state_path/parse.rs +++ b/console/program/src/state_path/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -74,9 +75,9 @@ impl Display for StatePath { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; @@ -113,7 +114,7 @@ mod tests { // Check the string representation. let candidate = format!("{expected}"); assert_eq!(expected, StatePath::from_str(&candidate).unwrap()); - assert_eq!(STATE_PATH_PREFIX, candidate.to_string().split('1').next().unwrap()); + assert_eq!(STATE_PATH_PREFIX, candidate.split('1').next().unwrap()); } } diff --git a/console/program/src/state_path/serialize.rs b/console/program/src/state_path/serialize.rs index 119104105a..817b543186 100644 --- a/console/program/src/state_path/serialize.rs +++ b/console/program/src/state_path/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -37,9 +38,9 @@ impl<'de, N: Network> Deserialize<'de> for StatePath { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/program/src/state_path/transaction_leaf/bytes.rs b/console/program/src/state_path/transaction_leaf/bytes.rs index db10cf1f90..c9e63f2017 100644 --- a/console/program/src/state_path/transaction_leaf/bytes.rs +++ b/console/program/src/state_path/transaction_leaf/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/transaction_leaf/mod.rs b/console/program/src/state_path/transaction_leaf/mod.rs index 1f3da92793..d94cfcb507 100644 --- a/console/program/src/state_path/transaction_leaf/mod.rs +++ b/console/program/src/state_path/transaction_leaf/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -71,9 +72,9 @@ impl TransactionLeaf { #[cfg(test)] mod test_helpers { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; pub(super) fn sample_leaf(rng: &mut TestRng) -> TransactionLeaf { // Construct a new leaf. diff --git a/console/program/src/state_path/transaction_leaf/serialize.rs b/console/program/src/state_path/transaction_leaf/serialize.rs index bff48a4718..06192df5a4 100644 --- a/console/program/src/state_path/transaction_leaf/serialize.rs +++ b/console/program/src/state_path/transaction_leaf/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/transaction_leaf/string.rs b/console/program/src/state_path/transaction_leaf/string.rs index 6cf3d93ca5..f343073f62 100644 --- a/console/program/src/state_path/transaction_leaf/string.rs +++ b/console/program/src/state_path/transaction_leaf/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/transaction_leaf/to_bits.rs b/console/program/src/state_path/transaction_leaf/to_bits.rs index eaa826f280..ead342d395 100644 --- a/console/program/src/state_path/transaction_leaf/to_bits.rs +++ b/console/program/src/state_path/transaction_leaf/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/transition_leaf/bytes.rs b/console/program/src/state_path/transition_leaf/bytes.rs index b06f9def4e..d5c571b8b3 100644 --- a/console/program/src/state_path/transition_leaf/bytes.rs +++ b/console/program/src/state_path/transition_leaf/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/transition_leaf/mod.rs b/console/program/src/state_path/transition_leaf/mod.rs index 53e84eac0b..f5f3cfb4ee 100644 --- a/console/program/src/state_path/transition_leaf/mod.rs +++ b/console/program/src/state_path/transition_leaf/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -71,9 +72,9 @@ impl TransitionLeaf { #[cfg(test)] mod test_helpers { use super::*; - use snarkvm_console_network::Testnet3; + use snarkvm_console_network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; pub(super) fn sample_leaf(rng: &mut TestRng) -> TransitionLeaf { // Construct a new leaf. diff --git a/console/program/src/state_path/transition_leaf/serialize.rs b/console/program/src/state_path/transition_leaf/serialize.rs index 6dbf3a2fd5..e9297ff2f7 100644 --- a/console/program/src/state_path/transition_leaf/serialize.rs +++ b/console/program/src/state_path/transition_leaf/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/transition_leaf/string.rs b/console/program/src/state_path/transition_leaf/string.rs index 8a6368ad26..e7984e9360 100644 --- a/console/program/src/state_path/transition_leaf/string.rs +++ b/console/program/src/state_path/transition_leaf/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/transition_leaf/to_bits.rs b/console/program/src/state_path/transition_leaf/to_bits.rs index 9943d1a999..a421b29e5e 100644 --- a/console/program/src/state_path/transition_leaf/to_bits.rs +++ b/console/program/src/state_path/transition_leaf/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/program/src/state_path/verify.rs b/console/program/src/state_path/verify.rs index fe44638b89..debada94cb 100644 --- a/console/program/src/state_path/verify.rs +++ b/console/program/src/state_path/verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -133,9 +134,9 @@ impl StatePath { #[cfg(test)] mod tests { use super::*; - use snarkvm_console_network::{prelude::TestRng, Testnet3}; + use snarkvm_console_network::{MainnetV0, prelude::TestRng}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: usize = 100; diff --git a/console/src/lib.rs b/console/src/lib.rs index b1b274234c..e638caf351 100644 --- a/console/src/lib.rs +++ b/console/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/Cargo.toml b/console/types/Cargo.toml index f2b0d934ed..7e8e8cf762 100644 --- a/console/types/Cargo.toml +++ b/console/types/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "snarkvm-console-types" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Console types for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" @@ -13,41 +15,41 @@ harness = false [dependencies.snarkvm-console-network-environment] path = "../network/environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-address] path = "./address" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-console-types-boolean] path = "./boolean" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-console-types-field] path = "./field" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-console-types-group] path = "./group" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-console-types-integers] path = "./integers" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-console-types-scalar] path = "./scalar" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-console-types-string] path = "./string" -version = "=0.16.19" +version = "=1.1.0" optional = true [dev-dependencies.criterion] diff --git a/console/types/address/Cargo.toml b/console/types/address/Cargo.toml index 92fa744b6d..3bebd5ca40 100644 --- a/console/types/address/Cargo.toml +++ b/console/types/address/Cargo.toml @@ -1,26 +1,28 @@ [package] name = "snarkvm-console-types-address" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Type operations for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.snarkvm-console-network-environment] path = "../../network/environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-boolean] path = "../boolean" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-field] path = "../field" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-group] path = "../group" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.bincode] version = "1.3" diff --git a/console/types/address/src/bitwise.rs b/console/types/address/src/bitwise.rs index 498ca44207..d180490303 100644 --- a/console/types/address/src/bitwise.rs +++ b/console/types/address/src/bitwise.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/bytes.rs b/console/types/address/src/bytes.rs index b76d6649b3..137a86c84d 100644 --- a/console/types/address/src/bytes.rs +++ b/console/types/address/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/from_bits.rs b/console/types/address/src/from_bits.rs index f344d1252c..a9b164b45d 100644 --- a/console/types/address/src/from_bits.rs +++ b/console/types/address/src/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/from_field.rs b/console/types/address/src/from_field.rs index 790a263bbe..0b4e522678 100644 --- a/console/types/address/src/from_field.rs +++ b/console/types/address/src/from_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/from_fields.rs b/console/types/address/src/from_fields.rs index 494de653d2..a8dc89d902 100644 --- a/console/types/address/src/from_fields.rs +++ b/console/types/address/src/from_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/lib.rs b/console/types/address/src/lib.rs index 8daa110c04..ba14b9a7ee 100644 --- a/console/types/address/src/lib.rs +++ b/console/types/address/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/parse.rs b/console/types/address/src/parse.rs index 29601042bd..d76461a559 100644 --- a/console/types/address/src/parse.rs +++ b/console/types/address/src/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -116,7 +117,7 @@ mod tests { // Check the string representation. let candidate = format!("{expected}"); assert_eq!(expected, Address::from_str(&candidate)?); - assert_eq!(ADDRESS_PREFIX, candidate.to_string().split('1').next().unwrap()); + assert_eq!(ADDRESS_PREFIX, candidate.split('1').next().unwrap()); } Ok(()) } diff --git a/console/types/address/src/random.rs b/console/types/address/src/random.rs index 405f1f28ff..f82d8877e3 100644 --- a/console/types/address/src/random.rs +++ b/console/types/address/src/random.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/serialize.rs b/console/types/address/src/serialize.rs index a2931fc5d0..0689b3f46b 100644 --- a/console/types/address/src/serialize.rs +++ b/console/types/address/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/size_in_bits.rs b/console/types/address/src/size_in_bits.rs index 34d341a9ab..f6b26c0b92 100644 --- a/console/types/address/src/size_in_bits.rs +++ b/console/types/address/src/size_in_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/size_in_bytes.rs b/console/types/address/src/size_in_bytes.rs index 6c05007488..b9d791096e 100644 --- a/console/types/address/src/size_in_bytes.rs +++ b/console/types/address/src/size_in_bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/to_bits.rs b/console/types/address/src/to_bits.rs index dacb00462e..ebda5db4ec 100644 --- a/console/types/address/src/to_bits.rs +++ b/console/types/address/src/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/to_field.rs b/console/types/address/src/to_field.rs index e64515c763..6dee513171 100644 --- a/console/types/address/src/to_field.rs +++ b/console/types/address/src/to_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/to_fields.rs b/console/types/address/src/to_fields.rs index ac204d231f..a9088b7256 100644 --- a/console/types/address/src/to_fields.rs +++ b/console/types/address/src/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/address/src/to_group.rs b/console/types/address/src/to_group.rs index 3bad477f03..1e2e2a088f 100644 --- a/console/types/address/src/to_group.rs +++ b/console/types/address/src/to_group.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/benches/group.rs b/console/types/benches/group.rs index 97782f3881..a4687e7a73 100644 --- a/console/types/benches/group.rs +++ b/console/types/benches/group.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,10 +17,10 @@ extern crate criterion; use criterion::Criterion; -use snarkvm_console_network::{environment::prelude::*, Testnet3}; +use snarkvm_console_network::{MainnetV0, environment::prelude::*}; use snarkvm_console_types::{Field, Group}; -type CurrentNetwork = Testnet3; +type CurrentNetwork = MainnetV0; fn group_from_field(c: &mut Criterion) { let rng = &mut TestRng::default(); diff --git a/console/types/boolean/Cargo.toml b/console/types/boolean/Cargo.toml index 7403db92e6..423cb6e62a 100644 --- a/console/types/boolean/Cargo.toml +++ b/console/types/boolean/Cargo.toml @@ -1,14 +1,16 @@ [package] name = "snarkvm-console-types-boolean" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Type operations for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.snarkvm-console-network-environment] path = "../../network/environment" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.bincode] version = "1.3" diff --git a/console/types/boolean/src/bitwise.rs b/console/types/boolean/src/bitwise.rs index b7f3432bfa..970518a9ae 100644 --- a/console/types/boolean/src/bitwise.rs +++ b/console/types/boolean/src/bitwise.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/boolean/src/bytes.rs b/console/types/boolean/src/bytes.rs index 5fe594418e..0461945141 100644 --- a/console/types/boolean/src/bytes.rs +++ b/console/types/boolean/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/boolean/src/from_bits.rs b/console/types/boolean/src/from_bits.rs index 173572f188..5a77d603b9 100644 --- a/console/types/boolean/src/from_bits.rs +++ b/console/types/boolean/src/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/boolean/src/lib.rs b/console/types/boolean/src/lib.rs index 42b7dfff51..85a6057730 100644 --- a/console/types/boolean/src/lib.rs +++ b/console/types/boolean/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/boolean/src/parse.rs b/console/types/boolean/src/parse.rs index 5a89318eb4..a3f431e074 100644 --- a/console/types/boolean/src/parse.rs +++ b/console/types/boolean/src/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/boolean/src/random.rs b/console/types/boolean/src/random.rs index 3b27178df0..6f882f26ee 100644 --- a/console/types/boolean/src/random.rs +++ b/console/types/boolean/src/random.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/boolean/src/serialize.rs b/console/types/boolean/src/serialize.rs index 2d5e3b063f..ffa2d87730 100644 --- a/console/types/boolean/src/serialize.rs +++ b/console/types/boolean/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/boolean/src/size_in_bits.rs b/console/types/boolean/src/size_in_bits.rs index 40dade5bc4..7f0518081e 100644 --- a/console/types/boolean/src/size_in_bits.rs +++ b/console/types/boolean/src/size_in_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/boolean/src/size_in_bytes.rs b/console/types/boolean/src/size_in_bytes.rs index f7c51b36ef..6c32b4c992 100644 --- a/console/types/boolean/src/size_in_bytes.rs +++ b/console/types/boolean/src/size_in_bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/boolean/src/to_bits.rs b/console/types/boolean/src/to_bits.rs index 9879656dbd..bef762ca40 100644 --- a/console/types/boolean/src/to_bits.rs +++ b/console/types/boolean/src/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/Cargo.toml b/console/types/field/Cargo.toml index c8be7daf1d..6fc0731091 100644 --- a/console/types/field/Cargo.toml +++ b/console/types/field/Cargo.toml @@ -1,18 +1,20 @@ [package] name = "snarkvm-console-types-field" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Type operations for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.snarkvm-console-network-environment] path = "../../network/environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-boolean] path = "../boolean" -version = "=0.16.19" +version = "=1.1.0" [dependencies.zeroize] version = "1" diff --git a/console/types/field/src/arithmetic.rs b/console/types/field/src/arithmetic.rs index ef102ff27f..f687f7a665 100644 --- a/console/types/field/src/arithmetic.rs +++ b/console/types/field/src/arithmetic.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/bitwise.rs b/console/types/field/src/bitwise.rs index 779404718c..e3cc7dff5d 100644 --- a/console/types/field/src/bitwise.rs +++ b/console/types/field/src/bitwise.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/bytes.rs b/console/types/field/src/bytes.rs index e20dc6a8fe..ff4d7b8f49 100644 --- a/console/types/field/src/bytes.rs +++ b/console/types/field/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/compare.rs b/console/types/field/src/compare.rs index e89fe32da6..be945659da 100644 --- a/console/types/field/src/compare.rs +++ b/console/types/field/src/compare.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/from_bits.rs b/console/types/field/src/from_bits.rs index ad79a3685e..49c33caf66 100644 --- a/console/types/field/src/from_bits.rs +++ b/console/types/field/src/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/lib.rs b/console/types/field/src/lib.rs index e63aafc883..63e2563cda 100644 --- a/console/types/field/src/lib.rs +++ b/console/types/field/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/one.rs b/console/types/field/src/one.rs index b6ed10deda..c1656ceceb 100644 --- a/console/types/field/src/one.rs +++ b/console/types/field/src/one.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/parse.rs b/console/types/field/src/parse.rs index 7718540875..940ef5c568 100644 --- a/console/types/field/src/parse.rs +++ b/console/types/field/src/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/random.rs b/console/types/field/src/random.rs index d5618f9009..603206e93e 100644 --- a/console/types/field/src/random.rs +++ b/console/types/field/src/random.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/serialize.rs b/console/types/field/src/serialize.rs index 56bc2b7e38..d4d4b0a8a5 100644 --- a/console/types/field/src/serialize.rs +++ b/console/types/field/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/size_in_bits.rs b/console/types/field/src/size_in_bits.rs index 4b5b83c1ef..89c6fc7763 100644 --- a/console/types/field/src/size_in_bits.rs +++ b/console/types/field/src/size_in_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/size_in_bytes.rs b/console/types/field/src/size_in_bytes.rs index 6b6764a82b..fdb3d1e1b3 100644 --- a/console/types/field/src/size_in_bytes.rs +++ b/console/types/field/src/size_in_bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/to_bits.rs b/console/types/field/src/to_bits.rs index 748d021c0a..55dcf223b2 100644 --- a/console/types/field/src/to_bits.rs +++ b/console/types/field/src/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/field/src/zero.rs b/console/types/field/src/zero.rs index 0e4e2adc95..1afb176ea1 100644 --- a/console/types/field/src/zero.rs +++ b/console/types/field/src/zero.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/Cargo.toml b/console/types/group/Cargo.toml index fd4bfc7611..a3d82c05ec 100644 --- a/console/types/group/Cargo.toml +++ b/console/types/group/Cargo.toml @@ -1,26 +1,28 @@ [package] name = "snarkvm-console-types-group" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Type operations for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.snarkvm-console-network-environment] path = "../../network/environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-boolean] path = "../boolean" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-field] path = "../field" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-scalar] path = "../scalar" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.bincode] version = "1.3" diff --git a/console/types/group/src/arithmetic.rs b/console/types/group/src/arithmetic.rs index 818efba0da..4f47770faa 100644 --- a/console/types/group/src/arithmetic.rs +++ b/console/types/group/src/arithmetic.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/bitwise.rs b/console/types/group/src/bitwise.rs index ba1b30d51a..2b6a1e08d8 100644 --- a/console/types/group/src/bitwise.rs +++ b/console/types/group/src/bitwise.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/bytes.rs b/console/types/group/src/bytes.rs index 04d6c8c3e5..78ad939e41 100644 --- a/console/types/group/src/bytes.rs +++ b/console/types/group/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/from_bits.rs b/console/types/group/src/from_bits.rs index d5c9188d54..d6a02d20b7 100644 --- a/console/types/group/src/from_bits.rs +++ b/console/types/group/src/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/from_field.rs b/console/types/group/src/from_field.rs index 6d48b22137..612a751f78 100644 --- a/console/types/group/src/from_field.rs +++ b/console/types/group/src/from_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/from_fields.rs b/console/types/group/src/from_fields.rs index 10ab239e1a..70addcc826 100644 --- a/console/types/group/src/from_fields.rs +++ b/console/types/group/src/from_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/from_x_coordinate.rs b/console/types/group/src/from_x_coordinate.rs index f8be208f71..04f0ed9edd 100644 --- a/console/types/group/src/from_x_coordinate.rs +++ b/console/types/group/src/from_x_coordinate.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/from_xy_coordinates.rs b/console/types/group/src/from_xy_coordinates.rs index c4f3376003..a802eb0f0b 100644 --- a/console/types/group/src/from_xy_coordinates.rs +++ b/console/types/group/src/from_xy_coordinates.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/lib.rs b/console/types/group/src/lib.rs index db81d377dd..ef21f6a6fb 100644 --- a/console/types/group/src/lib.rs +++ b/console/types/group/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/parse.rs b/console/types/group/src/parse.rs index 09fe6e8bbc..83d348aecf 100644 --- a/console/types/group/src/parse.rs +++ b/console/types/group/src/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/random.rs b/console/types/group/src/random.rs index 0510f172b7..7875df1d6b 100644 --- a/console/types/group/src/random.rs +++ b/console/types/group/src/random.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/serialize.rs b/console/types/group/src/serialize.rs index 2c172d0edd..bf4ea426de 100644 --- a/console/types/group/src/serialize.rs +++ b/console/types/group/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/size_in_bits.rs b/console/types/group/src/size_in_bits.rs index d3260a8065..6643e3c3ab 100644 --- a/console/types/group/src/size_in_bits.rs +++ b/console/types/group/src/size_in_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/size_in_bytes.rs b/console/types/group/src/size_in_bytes.rs index 33c2292e95..e1221599eb 100644 --- a/console/types/group/src/size_in_bytes.rs +++ b/console/types/group/src/size_in_bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/to_bits.rs b/console/types/group/src/to_bits.rs index 4de9d06155..9510939e4a 100644 --- a/console/types/group/src/to_bits.rs +++ b/console/types/group/src/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/to_field.rs b/console/types/group/src/to_field.rs index ffd8166fc8..a89fbf9bba 100644 --- a/console/types/group/src/to_field.rs +++ b/console/types/group/src/to_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/to_fields.rs b/console/types/group/src/to_fields.rs index 7d0b8ebda9..2327247088 100644 --- a/console/types/group/src/to_fields.rs +++ b/console/types/group/src/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/to_x_coordinate.rs b/console/types/group/src/to_x_coordinate.rs index 22b86e9708..143000dc6a 100644 --- a/console/types/group/src/to_x_coordinate.rs +++ b/console/types/group/src/to_x_coordinate.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/to_xy_coordinates.rs b/console/types/group/src/to_xy_coordinates.rs index 041f6d5088..a6d9b83841 100644 --- a/console/types/group/src/to_xy_coordinates.rs +++ b/console/types/group/src/to_xy_coordinates.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/to_y_coordinate.rs b/console/types/group/src/to_y_coordinate.rs index fd5e3c3347..7933a40258 100644 --- a/console/types/group/src/to_y_coordinate.rs +++ b/console/types/group/src/to_y_coordinate.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/group/src/zero.rs b/console/types/group/src/zero.rs index ec977396f9..8079b82587 100644 --- a/console/types/group/src/zero.rs +++ b/console/types/group/src/zero.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/Cargo.toml b/console/types/integers/Cargo.toml index 1da2502c68..8ea4bf3c2a 100644 --- a/console/types/integers/Cargo.toml +++ b/console/types/integers/Cargo.toml @@ -1,26 +1,28 @@ [package] name = "snarkvm-console-types-integers" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Type operations for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.snarkvm-console-network-environment] path = "../../network/environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-boolean] path = "../boolean" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-field] path = "../field" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-scalar] path = "../scalar" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.bincode] version = "1.3" diff --git a/console/types/integers/src/arithmetic.rs b/console/types/integers/src/arithmetic.rs index 66a780a7c0..fddca57b4d 100644 --- a/console/types/integers/src/arithmetic.rs +++ b/console/types/integers/src/arithmetic.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/bitwise.rs b/console/types/integers/src/bitwise.rs index 899c585ee4..8dfa007dbb 100644 --- a/console/types/integers/src/bitwise.rs +++ b/console/types/integers/src/bitwise.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/bytes.rs b/console/types/integers/src/bytes.rs index 76cadcf2fa..3bccbab156 100644 --- a/console/types/integers/src/bytes.rs +++ b/console/types/integers/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/compare.rs b/console/types/integers/src/compare.rs index 691f92971b..133d170bb9 100644 --- a/console/types/integers/src/compare.rs +++ b/console/types/integers/src/compare.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/from_bits.rs b/console/types/integers/src/from_bits.rs index 87290176de..d0cfc27546 100644 --- a/console/types/integers/src/from_bits.rs +++ b/console/types/integers/src/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/from_field.rs b/console/types/integers/src/from_field.rs index 7292b6e189..3222728452 100644 --- a/console/types/integers/src/from_field.rs +++ b/console/types/integers/src/from_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/from_field_lossy.rs b/console/types/integers/src/from_field_lossy.rs index bc3894cfa7..50c77a251e 100644 --- a/console/types/integers/src/from_field_lossy.rs +++ b/console/types/integers/src/from_field_lossy.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/from_fields.rs b/console/types/integers/src/from_fields.rs index 1908a4e6d3..b977766842 100644 --- a/console/types/integers/src/from_fields.rs +++ b/console/types/integers/src/from_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/lib.rs b/console/types/integers/src/lib.rs index bfc0d0b2b7..64e48f28d0 100644 --- a/console/types/integers/src/lib.rs +++ b/console/types/integers/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/one.rs b/console/types/integers/src/one.rs index 039da5e333..8c403cdde9 100644 --- a/console/types/integers/src/one.rs +++ b/console/types/integers/src/one.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/parse.rs b/console/types/integers/src/parse.rs index 01a6214280..84277bb2ae 100644 --- a/console/types/integers/src/parse.rs +++ b/console/types/integers/src/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/random.rs b/console/types/integers/src/random.rs index 7f12fb9b4c..3b8292ae35 100644 --- a/console/types/integers/src/random.rs +++ b/console/types/integers/src/random.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/serialize.rs b/console/types/integers/src/serialize.rs index 6f2584c0d8..51f2335081 100644 --- a/console/types/integers/src/serialize.rs +++ b/console/types/integers/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/size_in_bits.rs b/console/types/integers/src/size_in_bits.rs index d520a0b1ab..d2c549d02d 100644 --- a/console/types/integers/src/size_in_bits.rs +++ b/console/types/integers/src/size_in_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/size_in_bytes.rs b/console/types/integers/src/size_in_bytes.rs index 887327c61a..d2756d76fd 100644 --- a/console/types/integers/src/size_in_bytes.rs +++ b/console/types/integers/src/size_in_bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/to_bits.rs b/console/types/integers/src/to_bits.rs index 4d36f91b76..33c5fea463 100644 --- a/console/types/integers/src/to_bits.rs +++ b/console/types/integers/src/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/to_field.rs b/console/types/integers/src/to_field.rs index b51d4b7931..5771f07f83 100644 --- a/console/types/integers/src/to_field.rs +++ b/console/types/integers/src/to_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/to_fields.rs b/console/types/integers/src/to_fields.rs index a98d0808c8..c265920b31 100644 --- a/console/types/integers/src/to_fields.rs +++ b/console/types/integers/src/to_fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/to_scalar.rs b/console/types/integers/src/to_scalar.rs index 4a69bb5010..a64ab5b678 100644 --- a/console/types/integers/src/to_scalar.rs +++ b/console/types/integers/src/to_scalar.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/integers/src/zero.rs b/console/types/integers/src/zero.rs index 4dfeefe070..3c3f25ca97 100644 --- a/console/types/integers/src/zero.rs +++ b/console/types/integers/src/zero.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/Cargo.toml b/console/types/scalar/Cargo.toml index 944a20d5d4..9f2e70b28a 100644 --- a/console/types/scalar/Cargo.toml +++ b/console/types/scalar/Cargo.toml @@ -1,22 +1,24 @@ [package] name = "snarkvm-console-types-scalar" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Type operations for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.snarkvm-console-network-environment] path = "../../network/environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-boolean] path = "../boolean" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-field] path = "../field" -version = "=0.16.19" +version = "=1.1.0" [dependencies.zeroize] version = "1" diff --git a/console/types/scalar/src/arithmetic.rs b/console/types/scalar/src/arithmetic.rs index 0f3c3281f9..25f7c21a8f 100644 --- a/console/types/scalar/src/arithmetic.rs +++ b/console/types/scalar/src/arithmetic.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/bitwise.rs b/console/types/scalar/src/bitwise.rs index a6a10fdec4..86f9a017f1 100644 --- a/console/types/scalar/src/bitwise.rs +++ b/console/types/scalar/src/bitwise.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/bytes.rs b/console/types/scalar/src/bytes.rs index 4fd3185c86..8f2c0bc990 100644 --- a/console/types/scalar/src/bytes.rs +++ b/console/types/scalar/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/compare.rs b/console/types/scalar/src/compare.rs index d3aca171f5..99fcaeaac7 100644 --- a/console/types/scalar/src/compare.rs +++ b/console/types/scalar/src/compare.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/from_bits.rs b/console/types/scalar/src/from_bits.rs index 4f9a123bfb..aa7ff2b416 100644 --- a/console/types/scalar/src/from_bits.rs +++ b/console/types/scalar/src/from_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/from_field.rs b/console/types/scalar/src/from_field.rs index cbed014120..1f13d9e283 100644 --- a/console/types/scalar/src/from_field.rs +++ b/console/types/scalar/src/from_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -22,8 +23,8 @@ impl FromField for Scalar { /// This method guarantees the following: /// 1. If the field element is larger than the scalar field modulus, then the operation will fail. /// 2. If the field element is smaller than the scalar field modulus, then the operation will succeed. - /// - This is particularly useful for the case where a user called, `Scalar::from_field(scalar.to_field())`, - /// and the scalar bit representation is between `size_in_data_bits < bits.len() < size_in_bits`. + /// - This is particularly useful for the case where a user called, `Scalar::from_field(scalar.to_field())`, + /// and the scalar bit representation is between `size_in_data_bits < bits.len() < size_in_bits`. fn from_field(field: &Self::Field) -> Result { // Note: We are reconstituting the base field into a scalar field. // This is safe as the scalar field modulus is less than the base field modulus, diff --git a/console/types/scalar/src/from_field_lossy.rs b/console/types/scalar/src/from_field_lossy.rs index 072c93325b..038988ebda 100644 --- a/console/types/scalar/src/from_field_lossy.rs +++ b/console/types/scalar/src/from_field_lossy.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/lib.rs b/console/types/scalar/src/lib.rs index 859b26ccb0..eeeba9d354 100644 --- a/console/types/scalar/src/lib.rs +++ b/console/types/scalar/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/one.rs b/console/types/scalar/src/one.rs index 9012ae060d..493a38bfb3 100644 --- a/console/types/scalar/src/one.rs +++ b/console/types/scalar/src/one.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/parse.rs b/console/types/scalar/src/parse.rs index 40b58259f2..d29b8f29d3 100644 --- a/console/types/scalar/src/parse.rs +++ b/console/types/scalar/src/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/random.rs b/console/types/scalar/src/random.rs index e967c8d455..b26d1ee4ef 100644 --- a/console/types/scalar/src/random.rs +++ b/console/types/scalar/src/random.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/serialize.rs b/console/types/scalar/src/serialize.rs index 2732ab62f6..f7abb1768f 100644 --- a/console/types/scalar/src/serialize.rs +++ b/console/types/scalar/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/size_in_bits.rs b/console/types/scalar/src/size_in_bits.rs index 066a007bab..c95f00a65a 100644 --- a/console/types/scalar/src/size_in_bits.rs +++ b/console/types/scalar/src/size_in_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/size_in_bytes.rs b/console/types/scalar/src/size_in_bytes.rs index a157aa6df1..de14c06835 100644 --- a/console/types/scalar/src/size_in_bytes.rs +++ b/console/types/scalar/src/size_in_bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/to_bits.rs b/console/types/scalar/src/to_bits.rs index e312b8f1c7..e8a749ee99 100644 --- a/console/types/scalar/src/to_bits.rs +++ b/console/types/scalar/src/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/to_field.rs b/console/types/scalar/src/to_field.rs index 0357a2ce47..c94b7ce99a 100644 --- a/console/types/scalar/src/to_field.rs +++ b/console/types/scalar/src/to_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/scalar/src/zero.rs b/console/types/scalar/src/zero.rs index f45666c061..1be3a3587f 100644 --- a/console/types/scalar/src/zero.rs +++ b/console/types/scalar/src/zero.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/src/lib.rs b/console/types/src/lib.rs index 7c4d8f919a..7b7cf16ef5 100644 --- a/console/types/src/lib.rs +++ b/console/types/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -49,7 +50,7 @@ pub mod modules { #[cfg(feature = "integers")] pub use snarkvm_console_types_integers as integers; #[cfg(feature = "integers")] - pub use snarkvm_console_types_integers::{I128, I16, I32, I64, I8, U128, U16, U32, U64, U8}; + pub use snarkvm_console_types_integers::{I8, I16, I32, I64, I128, U8, U16, U32, U64, U128}; #[cfg(feature = "scalar")] pub use snarkvm_console_types_scalar as scalar; diff --git a/console/types/string/Cargo.toml b/console/types/string/Cargo.toml index aea2da4af3..33c9a3e39a 100644 --- a/console/types/string/Cargo.toml +++ b/console/types/string/Cargo.toml @@ -1,26 +1,28 @@ [package] name = "snarkvm-console-types-string" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Type operations for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" license = "Apache-2.0" edition = "2021" [dependencies.snarkvm-console-network-environment] path = "../../network/environment" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-boolean] path = "../boolean" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-field] path = "../field" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-console-types-integers] path = "../integers" -version = "=0.16.19" +version = "=1.1.0" [dev-dependencies.bincode] version = "1.3" diff --git a/console/types/string/src/bitwise.rs b/console/types/string/src/bitwise.rs index 5947598c88..97e8daec1f 100644 --- a/console/types/string/src/bitwise.rs +++ b/console/types/string/src/bitwise.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/string/src/bytes.rs b/console/types/string/src/bytes.rs index 46fd7fcf33..bfb9f760e0 100644 --- a/console/types/string/src/bytes.rs +++ b/console/types/string/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/string/src/lib.rs b/console/types/string/src/lib.rs index 550d96c3ee..91b2f92c62 100644 --- a/console/types/string/src/lib.rs +++ b/console/types/string/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/string/src/parse.rs b/console/types/string/src/parse.rs index c02f57f0bd..f67ff36f53 100644 --- a/console/types/string/src/parse.rs +++ b/console/types/string/src/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/console/types/string/src/random.rs b/console/types/string/src/random.rs index 68179ec1db..309a668a2b 100644 --- a/console/types/string/src/random.rs +++ b/console/types/string/src/random.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -29,7 +30,7 @@ mod tests { use super::*; use snarkvm_console_network_environment::Console; - use std::collections::HashSet; + use std::collections::HashMap; type CurrentEnvironment = Console; @@ -37,19 +38,21 @@ mod tests { #[test] fn test_random() { - // Initialize a set to store all seen random elements. - let mut set = HashSet::with_capacity(ITERATIONS); + // Initialize a map[string]=>occurences to store all seen random elements. + let mut map = HashMap::with_capacity(ITERATIONS); let mut rng = TestRng::default(); - // Note: This test technically has a `(1 + 2 + ... + ITERATIONS) / MODULUS` probability of being flaky. for _ in 0..ITERATIONS { // Sample a random value. let string: StringType = Uniform::rand(&mut rng); - assert!(!set.contains(&string), "{}", string); // Add the new random value to the set. - set.insert(string); + map.entry(string).and_modify(|count| *count += 1).or_insert(1); + } + for (string, count) in map { + let allowed_occurences = 1 + ITERATIONS / (string.len() * 10); + assert!(count <= allowed_occurences, "Encountered an element with a count of {}: {}", count, string); } } } diff --git a/console/types/string/src/serialize.rs b/console/types/string/src/serialize.rs index da2cded2fd..813c9fb6c7 100644 --- a/console/types/string/src/serialize.rs +++ b/console/types/string/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/Cargo.toml b/curves/Cargo.toml index 8d4c7c3dd0..643f4c00d7 100644 --- a/curves/Cargo.toml +++ b/curves/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-curves" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Curves for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -36,12 +36,12 @@ harness = false [dependencies.snarkvm-fields] path = "../fields" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-utilities] path = "../utilities" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.rand] diff --git a/curves/benches/bls12_377/ec.rs b/curves/benches/bls12_377/ec.rs index 3b0b28ccf4..c9fe867d87 100644 --- a/curves/benches/bls12_377/ec.rs +++ b/curves/benches/bls12_377/ec.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,9 +15,9 @@ pub(crate) mod g1 { use snarkvm_curves::{ + AffineCurve, bls12_377::{Fr, G1Affine, G1Projective as G1}, traits::ProjectiveCurve, - AffineCurve, }; use snarkvm_utilities::rand::{TestRng, Uniform}; diff --git a/curves/benches/bls12_377/fq.rs b/curves/benches/bls12_377/fq.rs index 02195b2175..ad81c65bbe 100644 --- a/curves/benches/bls12_377/fq.rs +++ b/curves/benches/bls12_377/fq.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/benches/bls12_377/fq12.rs b/curves/benches/bls12_377/fq12.rs index dd357ad923..34ccddd4d6 100644 --- a/curves/benches/bls12_377/fq12.rs +++ b/curves/benches/bls12_377/fq12.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/benches/bls12_377/fq2.rs b/curves/benches/bls12_377/fq2.rs index 3beff2af60..2e50232e43 100644 --- a/curves/benches/bls12_377/fq2.rs +++ b/curves/benches/bls12_377/fq2.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/benches/bls12_377/fr.rs b/curves/benches/bls12_377/fr.rs index c9cf826335..37e64d0452 100644 --- a/curves/benches/bls12_377/fr.rs +++ b/curves/benches/bls12_377/fr.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/benches/bls12_377/mod.rs b/curves/benches/bls12_377/mod.rs index 145f6aabb7..3692f87e23 100644 --- a/curves/benches/bls12_377/mod.rs +++ b/curves/benches/bls12_377/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/benches/bls12_377/pairing.rs b/curves/benches/bls12_377/pairing.rs index 41bdd5114d..ff541a7ddd 100644 --- a/curves/benches/bls12_377/pairing.rs +++ b/curves/benches/bls12_377/pairing.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/benches/curves.rs b/curves/benches/curves.rs index cd173c4377..8f0f57ebfa 100644 --- a/curves/benches/curves.rs +++ b/curves/benches/curves.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/build.rs b/curves/build.rs index 6b3f8458d7..81fb6894f5 100644 --- a/curves/build.rs +++ b/curves/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. // Detect the rustc channel -use rustc_version::{version_meta, Channel}; +use rustc_version::{Channel, version_meta}; fn main() { // Set cfg flags depending on release channel diff --git a/curves/src/bls12_377/fq.rs b/curves/src/bls12_377/fq.rs index 1bcd522597..54fd3b9348 100644 --- a/curves/src/bls12_377/fq.rs +++ b/curves/src/bls12_377/fq.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/bls12_377/fq12.rs b/curves/src/bls12_377/fq12.rs index 165599a37f..00a98ecd9d 100644 --- a/curves/src/bls12_377/fq12.rs +++ b/curves/src/bls12_377/fq12.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use snarkvm_fields::{field, Fp12, Fp12Parameters}; +use snarkvm_fields::{Fp12, Fp12Parameters, field}; use snarkvm_utilities::biginteger::BigInteger384 as BigInteger; use crate::bls12_377::{Fq, Fq2, Fq6Parameters}; diff --git a/curves/src/bls12_377/fq2.rs b/curves/src/bls12_377/fq2.rs index fbaffb2c7e..d939091e0d 100644 --- a/curves/src/bls12_377/fq2.rs +++ b/curves/src/bls12_377/fq2.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use serde::{Deserialize, Serialize}; -use snarkvm_fields::{field, Field, Fp2, Fp2Parameters}; +use snarkvm_fields::{Field, Fp2, Fp2Parameters, field}; use snarkvm_utilities::biginteger::BigInteger384 as BigInteger; use crate::bls12_377::Fq; diff --git a/curves/src/bls12_377/fq6.rs b/curves/src/bls12_377/fq6.rs index 841c81dabc..464e5d1e96 100644 --- a/curves/src/bls12_377/fq6.rs +++ b/curves/src/bls12_377/fq6.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,9 +14,9 @@ // limitations under the License. use snarkvm_fields::{ + Fp2Parameters, field, fp6_3over2::{Fp6, Fp6Parameters}, - Fp2Parameters, }; use snarkvm_utilities::biginteger::BigInteger384; diff --git a/curves/src/bls12_377/fr.rs b/curves/src/bls12_377/fr.rs index 67de1ab1ad..a3a654e12d 100644 --- a/curves/src/bls12_377/fr.rs +++ b/curves/src/bls12_377/fr.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/bls12_377/g1.rs b/curves/src/bls12_377/g1.rs index 34f6379dcc..f7c23bdfd5 100644 --- a/curves/src/bls12_377/g1.rs +++ b/curves/src/bls12_377/g1.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,19 +13,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -use snarkvm_fields::{field, Field, One, PrimeField, Zero}; +use snarkvm_fields::{Field, One, PrimeField, Zero, field}; use snarkvm_utilities::{ - biginteger::{BigInteger256, BigInteger384}, BigInteger, BitIteratorBE, + biginteger::{BigInteger256, BigInteger384}, }; use crate::{ + AffineCurve, + ProjectiveCurve, bls12_377::{Fq, Fr}, templates::bls12::Bls12Parameters, traits::{ModelParameters, ShortWeierstrassParameters}, - AffineCurve, - ProjectiveCurve, }; use std::ops::Neg; diff --git a/curves/src/bls12_377/g2.rs b/curves/src/bls12_377/g2.rs index 06b130e62e..ff2f1a8d9f 100644 --- a/curves/src/bls12_377/g2.rs +++ b/curves/src/bls12_377/g2.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,18 +13,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -use snarkvm_fields::{field, Field, PrimeField, Zero}; +use snarkvm_fields::{Field, PrimeField, Zero, field}; use snarkvm_utilities::{ - biginteger::{BigInteger256, BigInteger384}, BigInteger, BitIteratorBE, + biginteger::{BigInteger256, BigInteger384}, }; use crate::{ - bls12_377::{g1::Bls12_377G1Parameters, Fq, Fq2, Fr}, - traits::{ModelParameters, ShortWeierstrassParameters}, AffineCurve, ProjectiveCurve, + bls12_377::{Fq, Fq2, Fr, g1::Bls12_377G1Parameters}, + traits::{ModelParameters, ShortWeierstrassParameters}, }; use std::ops::Neg; diff --git a/curves/src/bls12_377/mod.rs b/curves/src/bls12_377/mod.rs index 934990ad56..2667c9a3bc 100644 --- a/curves/src/bls12_377/mod.rs +++ b/curves/src/bls12_377/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#![cfg_attr(nightly, doc = include_str!("../../documentation/the_aleo_curves/02_bls12-377.md"))] +#![doc = include_str!("../../documentation/the_aleo_curves/02_bls12-377.md")] pub mod fr; #[doc(inline)] diff --git a/curves/src/bls12_377/parameters.rs b/curves/src/bls12_377/parameters.rs index f731fc22d0..dd3f489142 100644 --- a/curves/src/bls12_377/parameters.rs +++ b/curves/src/bls12_377/parameters.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,13 +15,13 @@ use crate::{ bls12_377::{ - g1::Bls12_377G1Parameters, - g2::Bls12_377G2Parameters, Fq, - Fq12, - Fq12Parameters, Fq2Parameters, Fq6Parameters, + Fq12, + Fq12Parameters, + g1::Bls12_377G1Parameters, + g2::Bls12_377G2Parameters, }, templates::bls12::{ Bls12, diff --git a/curves/src/bls12_377/tests.rs b/curves/src/bls12_377/tests.rs index d68364c213..9c63aa4044 100644 --- a/curves/src/bls12_377/tests.rs +++ b/curves/src/bls12_377/tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,15 +16,13 @@ #![allow(unused_imports)] use crate::{ bls12_377::{ - g1::Bls12_377G1Parameters, - g2::Bls12_377G2Parameters, Bls12_377, Fq, - Fq12, Fq2, Fq2Parameters, Fq6, Fq6Parameters, + Fq12, FqParameters, Fr, FrParameters, @@ -31,9 +30,15 @@ use crate::{ G1Projective, G2Affine, G2Projective, + g1::Bls12_377G1Parameters, + g2::Bls12_377G2Parameters, }, templates::{short_weierstrass_jacobian::tests::sw_tests, twisted_edwards_extended::tests::edwards_test}, traits::{ + AffineCurve, + PairingEngine, + ProjectiveCurve, + ShortWeierstrassParameters, tests_field::{ bench_sqrt, field_serialization_test, @@ -45,14 +50,9 @@ use crate::{ }, tests_group::*, tests_projective::curve_tests, - AffineCurve, - PairingEngine, - ProjectiveCurve, - ShortWeierstrassParameters, }, }; use snarkvm_fields::{ - fp6_3over2::Fp6Parameters, FftField, FftParameters, Field, @@ -63,11 +63,12 @@ use snarkvm_fields::{ PrimeField, SquareRootField, Zero, + fp6_3over2::Fp6Parameters, }; use snarkvm_utilities::{ + BitIteratorBE, biginteger::{BigInteger, BigInteger256, BigInteger384}, rand::{TestRng, Uniform}, - BitIteratorBE, }; use rand::Rng; diff --git a/curves/src/edwards_bls12/fq.rs b/curves/src/edwards_bls12/fq.rs index 279b0795e4..665579ceae 100644 --- a/curves/src/edwards_bls12/fq.rs +++ b/curves/src/edwards_bls12/fq.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/edwards_bls12/fr.rs b/curves/src/edwards_bls12/fr.rs index 0ed9d8e233..b40307e9f8 100644 --- a/curves/src/edwards_bls12/fr.rs +++ b/curves/src/edwards_bls12/fr.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/edwards_bls12/mod.rs b/curves/src/edwards_bls12/mod.rs index c51efebd49..7ba8acc6c6 100644 --- a/curves/src/edwards_bls12/mod.rs +++ b/curves/src/edwards_bls12/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#![cfg_attr(nightly, doc = include_str!("../../documentation/the_aleo_curves/01_edwards_bls12.md"))] +#![doc = include_str!("../../documentation/the_aleo_curves/01_edwards_bls12.md")] pub mod fq; #[doc(inline)] diff --git a/curves/src/edwards_bls12/parameters.rs b/curves/src/edwards_bls12/parameters.rs index 138e3e1252..c03024dfaa 100644 --- a/curves/src/edwards_bls12/parameters.rs +++ b/curves/src/edwards_bls12/parameters.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -103,7 +104,7 @@ impl FromStr for EdwardsAffine { return Err(GroupError::InvalidString); } let mut point = Vec::new(); - for substr in s.split(|c| c == '(' || c == ')' || c == ',' || c == ' ') { + for substr in s.split(['(', ')', ',', ' ']) { if !substr.is_empty() { point.push(Fq::from_str(substr)?); } diff --git a/curves/src/edwards_bls12/tests.rs b/curves/src/edwards_bls12/tests.rs index 6b33288f36..9e77d4da40 100644 --- a/curves/src/edwards_bls12/tests.rs +++ b/curves/src/edwards_bls12/tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,20 +17,20 @@ use crate::{ edwards_bls12::*, templates::twisted_edwards_extended::tests::{edwards_test, montgomery_conversion_test}, traits::{ - tests_field::{field_serialization_test, field_test, primefield_test}, - tests_group::*, - tests_projective::curve_tests, AffineCurve, MontgomeryParameters, ProjectiveCurve, TwistedEdwardsParameters, + tests_field::{field_serialization_test, field_test, primefield_test}, + tests_group::*, + tests_projective::curve_tests, }, }; use snarkvm_fields::{Field, LegendreSymbol, One, SquareRootField, Zero}; use snarkvm_utilities::{ + ToBytes, rand::{TestRng, Uniform}, to_bytes_le, - ToBytes, }; use rand::Rng; diff --git a/curves/src/errors.rs b/curves/src/errors.rs index 748fa6657a..50c126d687 100644 --- a/curves/src/errors.rs +++ b/curves/src/errors.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/lib.rs b/curves/src/lib.rs index 659ef01c31..d78de0a46a 100644 --- a/curves/src/lib.rs +++ b/curves/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/templates/bls12/bls12.rs b/curves/src/templates/bls12/bls12.rs index 71a57c22e9..d275040ec2 100644 --- a/curves/src/templates/bls12/bls12.rs +++ b/curves/src/templates/bls12/bls12.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,6 +14,7 @@ // limitations under the License. use crate::{ + AffineCurve, templates::{ bls12::{ g1::{G1Affine, G1Prepared, G1Projective}, @@ -21,19 +23,18 @@ use crate::{ short_weierstrass_jacobian, }, traits::{ModelParameters, PairingCurve, PairingEngine, ShortWeierstrassParameters}, - AffineCurve, }; use snarkvm_fields::{ - fp6_3over2::Fp6Parameters, Field, - Fp12, - Fp12Parameters, Fp2, Fp2Parameters, + Fp12, + Fp12Parameters, One, PrimeField, SquareRootField, Zero, + fp6_3over2::Fp6Parameters, }; use snarkvm_utilities::bititerator::BitIteratorBE; diff --git a/curves/src/templates/bls12/g1.rs b/curves/src/templates/bls12/g1.rs index ca7c7b40f4..fdea8e7445 100644 --- a/curves/src/templates/bls12/g1.rs +++ b/curves/src/templates/bls12/g1.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,7 +21,7 @@ use crate::{ traits::AffineCurve, }; use snarkvm_fields::Zero; -use snarkvm_utilities::{serialize::*, FromBytes, ToBytes}; +use snarkvm_utilities::{FromBytes, ToBytes, serialize::*}; use std::io::{Read, Result as IoResult, Write}; diff --git a/curves/src/templates/bls12/g2.rs b/curves/src/templates/bls12/g2.rs index 5c27d12909..1cb3c4e54d 100644 --- a/curves/src/templates/bls12/g2.rs +++ b/curves/src/templates/bls12/g2.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,7 +21,7 @@ use crate::{ traits::{AffineCurve, ShortWeierstrassParameters}, }; use snarkvm_fields::{Field, Fp2, One, Zero}; -use snarkvm_utilities::{bititerator::BitIteratorBE, serialize::*, ToBytes}; +use snarkvm_utilities::{ToBytes, bititerator::BitIteratorBE, serialize::*}; use std::io::{Result as IoResult, Write}; diff --git a/curves/src/templates/bls12/mod.rs b/curves/src/templates/bls12/mod.rs index c5f0ae8885..84d5343d63 100644 --- a/curves/src/templates/bls12/mod.rs +++ b/curves/src/templates/bls12/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/templates/macros.rs b/curves/src/templates/macros.rs index 2447aa03ae..7d0e08bd25 100644 --- a/curves/src/templates/macros.rs +++ b/curves/src/templates/macros.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/templates/mod.rs b/curves/src/templates/mod.rs index 22d0ef5e6c..4a43044eec 100644 --- a/curves/src/templates/mod.rs +++ b/curves/src/templates/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/templates/short_weierstrass_jacobian/affine.rs b/curves/src/templates/short_weierstrass_jacobian/affine.rs index d5cbe730f5..b339bae637 100644 --- a/curves/src/templates/short_weierstrass_jacobian/affine.rs +++ b/curves/src/templates/short_weierstrass_jacobian/affine.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,12 +20,12 @@ use crate::{ }; use snarkvm_fields::{Field, One, SquareRootField, Zero}; use snarkvm_utilities::{ + FromBytes, + ToBytes, bititerator::BitIteratorBE, io::{Error, ErrorKind, Read, Result as IoResult, Write}, rand::Uniform, serialize::*, - FromBytes, - ToBytes, }; use core::{ @@ -32,8 +33,8 @@ use core::{ ops::{Mul, Neg}, }; use rand::{ - distributions::{Distribution, Standard}, Rng, + distributions::{Distribution, Standard}, }; use serde::{Deserialize, Serialize}; diff --git a/curves/src/templates/short_weierstrass_jacobian/mod.rs b/curves/src/templates/short_weierstrass_jacobian/mod.rs index 8edbcabf67..6516ecbb3b 100644 --- a/curves/src/templates/short_weierstrass_jacobian/mod.rs +++ b/curves/src/templates/short_weierstrass_jacobian/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/templates/short_weierstrass_jacobian/projective.rs b/curves/src/templates/short_weierstrass_jacobian/projective.rs index c45d4ec2d3..3b0f5b34fb 100644 --- a/curves/src/templates/short_weierstrass_jacobian/projective.rs +++ b/curves/src/templates/short_weierstrass_jacobian/projective.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,8 +17,8 @@ use crate::{ templates::short_weierstrass_jacobian::Affine, traits::{AffineCurve, ProjectiveCurve, ShortWeierstrassParameters as Parameters}, }; -use snarkvm_fields::{impl_add_sub_from_field_ref, Field, One, Zero}; -use snarkvm_utilities::{cfg_iter_mut, rand::Uniform, serialize::*, FromBytes, ToBytes}; +use snarkvm_fields::{Field, One, Zero, impl_add_sub_from_field_ref}; +use snarkvm_utilities::{FromBytes, ToBytes, cfg_iter_mut, rand::Uniform, serialize::*}; use core::{ fmt::{Display, Formatter, Result as FmtResult}, @@ -25,8 +26,8 @@ use core::{ ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; use rand::{ - distributions::{Distribution, Standard}, Rng, + distributions::{Distribution, Standard}, }; #[cfg(not(feature = "serial"))] use rayon::prelude::*; diff --git a/curves/src/templates/short_weierstrass_jacobian/tests.rs b/curves/src/templates/short_weierstrass_jacobian/tests.rs index b8f94bbd23..74b473183e 100644 --- a/curves/src/templates/short_weierstrass_jacobian/tests.rs +++ b/curves/src/templates/short_weierstrass_jacobian/tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,12 +17,12 @@ use super::{Affine, Projective}; use crate::{AffineCurve, ProjectiveCurve, ShortWeierstrassParameters}; use snarkvm_fields::Zero; use snarkvm_utilities::{ - io::Cursor, - rand::Uniform, - serialize::{CanonicalDeserialize, CanonicalSerialize}, Compress, TestRng, Validate, + io::Cursor, + rand::Uniform, + serialize::{CanonicalDeserialize, CanonicalSerialize}, }; pub const ITERATIONS: usize = 10; diff --git a/curves/src/templates/to_field_vec.rs b/curves/src/templates/to_field_vec.rs index 758422de87..c5a8ea18a1 100644 --- a/curves/src/templates/to_field_vec.rs +++ b/curves/src/templates/to_field_vec.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/templates/twisted_edwards_extended/affine.rs b/curves/src/templates/twisted_edwards_extended/affine.rs index d850729e4b..a6712a3303 100644 --- a/curves/src/templates/twisted_edwards_extended/affine.rs +++ b/curves/src/templates/twisted_edwards_extended/affine.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,12 +20,12 @@ use crate::{ }; use snarkvm_fields::{Field, One, PrimeField, SquareRootField, Zero}; use snarkvm_utilities::{ + FromBytes, + ToBytes, bititerator::BitIteratorBE, io::{Read, Result as IoResult, Write}, rand::Uniform, serialize::*, - FromBytes, - ToBytes, }; use core::{ @@ -32,8 +33,8 @@ use core::{ ops::{Mul, Neg}, }; use rand::{ - distributions::{Distribution, Standard}, Rng, + distributions::{Distribution, Standard}, }; use serde::{Deserialize, Serialize}; diff --git a/curves/src/templates/twisted_edwards_extended/mod.rs b/curves/src/templates/twisted_edwards_extended/mod.rs index 8edbcabf67..6516ecbb3b 100644 --- a/curves/src/templates/twisted_edwards_extended/mod.rs +++ b/curves/src/templates/twisted_edwards_extended/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/templates/twisted_edwards_extended/projective.rs b/curves/src/templates/twisted_edwards_extended/projective.rs index 5db7a6830c..0cdc2f7d3c 100644 --- a/curves/src/templates/twisted_edwards_extended/projective.rs +++ b/curves/src/templates/twisted_edwards_extended/projective.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,8 +17,8 @@ use crate::{ templates::twisted_edwards_extended::Affine, traits::{AffineCurve, ProjectiveCurve, TwistedEdwardsParameters as Parameters}, }; -use snarkvm_fields::{impl_add_sub_from_field_ref, Field, One, PrimeField, Zero}; -use snarkvm_utilities::{bititerator::BitIteratorBE, rand::Uniform, serialize::*, FromBytes, ToBytes}; +use snarkvm_fields::{Field, One, PrimeField, Zero, impl_add_sub_from_field_ref}; +use snarkvm_utilities::{FromBytes, ToBytes, bititerator::BitIteratorBE, rand::Uniform, serialize::*}; use core::{ fmt::{Display, Formatter, Result as FmtResult}, @@ -25,8 +26,8 @@ use core::{ ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; use rand::{ - distributions::{Distribution, Standard}, Rng, + distributions::{Distribution, Standard}, }; use std::io::{Read, Result as IoResult, Write}; diff --git a/curves/src/templates/twisted_edwards_extended/tests.rs b/curves/src/templates/twisted_edwards_extended/tests.rs index e1ccbded0d..0412c2595a 100644 --- a/curves/src/templates/twisted_edwards_extended/tests.rs +++ b/curves/src/templates/twisted_edwards_extended/tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,14 +16,14 @@ use super::{Affine, Projective}; use snarkvm_utilities::{ - io::Cursor, - rand::Uniform, - serialize::{CanonicalDeserialize, CanonicalSerialize}, - to_bytes_le, Compress, TestRng, ToBytes, Validate, + io::Cursor, + rand::Uniform, + serialize::{CanonicalDeserialize, CanonicalSerialize}, + to_bytes_le, }; use crate::traits::{AffineCurve, MontgomeryParameters, ProjectiveCurve, TwistedEdwardsParameters}; diff --git a/curves/src/traits/group.rs b/curves/src/traits/group.rs index 47f8bdcc69..c7ca15a80e 100644 --- a/curves/src/traits/group.rs +++ b/curves/src/traits/group.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,9 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{templates::short_weierstrass_jacobian, PairingEngine}; +use crate::{PairingEngine, templates::short_weierstrass_jacobian}; use snarkvm_fields::{Field, PrimeField, SquareRootField, Zero}; -use snarkvm_utilities::{rand::Uniform, serialize::*, FromBytes, ToBytes}; +use snarkvm_utilities::{FromBytes, ToBytes, rand::Uniform, serialize::*}; use core::{ fmt::{Debug, Display}, @@ -22,7 +23,7 @@ use core::{ iter, ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; -use serde::{de::DeserializeOwned, Serialize}; +use serde::{Serialize, de::DeserializeOwned}; /// Projective representation of an elliptic curve point guaranteed to be in the prime order subgroup. pub trait ProjectiveCurve: diff --git a/curves/src/traits/mod.rs b/curves/src/traits/mod.rs index dad95a76ad..5d9d49b4f3 100644 --- a/curves/src/traits/mod.rs +++ b/curves/src/traits/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/traits/pairing_engine.rs b/curves/src/traits/pairing_engine.rs index d422580f58..0a8d62ca97 100644 --- a/curves/src/traits/pairing_engine.rs +++ b/curves/src/traits/pairing_engine.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/traits/tests_field.rs b/curves/src/traits/tests_field.rs index d1d5ac9b09..76137b31af 100644 --- a/curves/src/traits/tests_field.rs +++ b/curves/src/traits/tests_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,12 +14,12 @@ // limitations under the License. use snarkvm_fields::{ - traits::{FftParameters, FieldParameters}, FftField, Field, LegendreSymbol, PrimeField, SquareRootField, + traits::{FftParameters, FieldParameters}, }; use snarkvm_utilities::{ io::Cursor, diff --git a/curves/src/traits/tests_group.rs b/curves/src/traits/tests_group.rs index 2530a7b474..271a16faeb 100644 --- a/curves/src/traits/tests_group.rs +++ b/curves/src/traits/tests_group.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/curves/src/traits/tests_projective.rs b/curves/src/traits/tests_projective.rs index b48d55d9a3..be7a206c8e 100644 --- a/curves/src/traits/tests_projective.rs +++ b/curves/src/traits/tests_projective.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/Cargo.toml b/fields/Cargo.toml index df9474d09e..d7935f7845 100644 --- a/fields/Cargo.toml +++ b/fields/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-fields" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Fields for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -30,7 +30,7 @@ harness = false [dependencies.snarkvm-utilities] path = "../utilities" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.aleo-std] diff --git a/fields/benches/fields.rs b/fields/benches/fields.rs index f58e4f6a64..81af5be729 100644 --- a/fields/benches/fields.rs +++ b/fields/benches/fields.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/errors/constraint_field.rs b/fields/src/errors/constraint_field.rs index 49273d3c3c..d7de1ffaed 100644 --- a/fields/src/errors/constraint_field.rs +++ b/fields/src/errors/constraint_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/errors/field.rs b/fields/src/errors/field.rs index 382158bede..9f8f3e3847 100644 --- a/fields/src/errors/field.rs +++ b/fields/src/errors/field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/errors/mod.rs b/fields/src/errors/mod.rs index b946147a53..6a14889b41 100644 --- a/fields/src/errors/mod.rs +++ b/fields/src/errors/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/fp12_2over3over2.rs b/fields/src/fp12_2over3over2.rs index e7da3be7cd..f890ae6c1b 100644 --- a/fields/src/fp12_2over3over2.rs +++ b/fields/src/fp12_2over3over2.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,12 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{fp6_3over2::*, Field, Fp2, Fp2Parameters, One, Zero}; -use snarkvm_utilities::{bititerator::BitIteratorBE, rand::Uniform, serialize::*, FromBytes, ToBits, ToBytes}; +use crate::{Field, Fp2, Fp2Parameters, One, Zero, fp6_3over2::*}; +use snarkvm_utilities::{FromBytes, ToBits, ToBytes, bititerator::BitIteratorBE, rand::Uniform, serialize::*}; use rand::{ - distributions::{Distribution, Standard}, Rng, + distributions::{Distribution, Standard}, }; use serde::{Deserialize, Serialize}; use std::{ diff --git a/fields/src/fp2.rs b/fields/src/fp2.rs index 528e5c3be7..72a260b85b 100644 --- a/fields/src/fp2.rs +++ b/fields/src/fp2.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,16 +15,16 @@ use crate::{Field, LegendreSymbol, One, PrimeField, SquareRootField, Zero}; use snarkvm_utilities::{ - rand::Uniform, - serialize::{SerializationError, *}, FromBytes, ToBits, ToBytes, + rand::Uniform, + serialize::{SerializationError, *}, }; use rand::{ - distributions::{Distribution, Standard}, Rng, + distributions::{Distribution, Standard}, }; use serde::{Deserialize, Serialize}; use std::{ diff --git a/fields/src/fp6_3over2.rs b/fields/src/fp6_3over2.rs index 5699630195..d7ba904c76 100644 --- a/fields/src/fp6_3over2.rs +++ b/fields/src/fp6_3over2.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,16 +15,16 @@ use crate::{Field, Fp2, Fp2Parameters, One, Zero}; use snarkvm_utilities::{ - rand::Uniform, - serialize::{SerializationError, *}, FromBytes, ToBits, ToBytes, + rand::Uniform, + serialize::{SerializationError, *}, }; use rand::{ - distributions::{Distribution, Standard}, Rng, + distributions::{Distribution, Standard}, }; use serde::{Deserialize, Serialize}; use std::{ diff --git a/fields/src/fp_256.rs b/fields/src/fp_256.rs index 80f69a635b..7d6cc1495d 100644 --- a/fields/src/fp_256.rs +++ b/fields/src/fp_256.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,8 +14,6 @@ // limitations under the License. use crate::{ - impl_add_sub_from_field_ref, - impl_mul_div_from_field_ref, FftField, Field, FieldError, @@ -26,13 +25,15 @@ use crate::{ PrimeField, SquareRootField, Zero, + impl_add_sub_from_field_ref, + impl_mul_div_from_field_ref, }; use snarkvm_utilities::{ - biginteger::{arithmetic as fa, BigInteger as _BigInteger, BigInteger256 as BigInteger}, - serialize::CanonicalDeserialize, FromBytes, ToBits, ToBytes, + biginteger::{BigInteger as _BigInteger, BigInteger256 as BigInteger, arithmetic as fa}, + serialize::CanonicalDeserialize, }; use std::{ diff --git a/fields/src/fp_384.rs b/fields/src/fp_384.rs index 1e60a18c2f..d1ff2ee895 100644 --- a/fields/src/fp_384.rs +++ b/fields/src/fp_384.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,8 +14,6 @@ // limitations under the License. use crate::{ - impl_add_sub_from_field_ref, - impl_mul_div_from_field_ref, FftField, Field, FieldError, @@ -26,13 +25,15 @@ use crate::{ PrimeField, SquareRootField, Zero, + impl_add_sub_from_field_ref, + impl_mul_div_from_field_ref, }; use snarkvm_utilities::{ - biginteger::{arithmetic as fa, BigInteger as _BigInteger, BigInteger384 as BigInteger}, - serialize::CanonicalDeserialize, FromBytes, ToBits, ToBytes, + biginteger::{BigInteger as _BigInteger, BigInteger384 as BigInteger, arithmetic as fa}, + serialize::CanonicalDeserialize, }; use std::{ diff --git a/fields/src/legendre.rs b/fields/src/legendre.rs index 9992fe7144..81fc0fd0cf 100644 --- a/fields/src/legendre.rs +++ b/fields/src/legendre.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/lib.rs b/fields/src/lib.rs index 52b1ac0c3d..c21d4f764b 100644 --- a/fields/src/lib.rs +++ b/fields/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -49,10 +50,10 @@ pub mod traits; pub use traits::*; use snarkvm_utilities::{ - biginteger::*, - serialize::{CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize, CanonicalSerializeWithFlags}, FromBytes, ToBytes, + biginteger::*, + serialize::{CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize, CanonicalSerializeWithFlags}, }; impl_field_to_biginteger!(Fp256, BigInteger256, Fp256Parameters); diff --git a/fields/src/macros.rs b/fields/src/macros.rs index 493745348a..3b09e90f89 100644 --- a/fields/src/macros.rs +++ b/fields/src/macros.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -44,7 +45,7 @@ macro_rules! impl_primefield_standard_sample { loop { let mut tmp = $field(rng.sample(rand::distributions::Standard), PhantomData); // Mask away the unused bits at the beginning. - tmp.0.as_mut().last_mut().map(|val| *val &= std::u64::MAX >> P::REPR_SHAVE_BITS); + tmp.0.as_mut().last_mut().map(|val| *val &= u64::MAX >> P::REPR_SHAVE_BITS); if tmp.is_valid() { return tmp; @@ -192,7 +193,7 @@ macro_rules! impl_primefield_serializer { mut writer: W, flags: F, ) -> Result<(), snarkvm_utilities::serialize::SerializationError> { - use snarkvm_utilities::serialize::{number_of_bits_and_bytes, SerializationError}; + use snarkvm_utilities::serialize::{SerializationError, number_of_bits_and_bytes}; // All reasonable `Flags` should be less than 8 bits in size // (256 values are enough for anyone!) if F::BIT_SIZE > 8 { diff --git a/fields/src/to_field_vec.rs b/fields/src/to_field_vec.rs index e790fb47ea..d8e65138e7 100644 --- a/fields/src/to_field_vec.rs +++ b/fields/src/to_field_vec.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/traits/fft_field.rs b/fields/src/traits/fft_field.rs index 6dad3522e3..17aa8a98c6 100644 --- a/fields/src/traits/fft_field.rs +++ b/fields/src/traits/fft_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/traits/fft_parameters.rs b/fields/src/traits/fft_parameters.rs index 9e52aafa80..875af189c4 100644 --- a/fields/src/traits/fft_parameters.rs +++ b/fields/src/traits/fft_parameters.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/traits/field.rs b/fields/src/traits/field.rs index cdad6ed9db..fe3309e162 100644 --- a/fields/src/traits/field.rs +++ b/fields/src/traits/field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,6 +15,9 @@ use crate::{One, PrimeField, Zero}; use snarkvm_utilities::{ + FromBytes, + ToBits, + ToBytes, bititerator::BitIteratorBE, rand::Uniform, serialize::{ @@ -24,9 +28,6 @@ use snarkvm_utilities::{ EmptyFlags, Flags, }, - FromBytes, - ToBits, - ToBytes, }; use std::{ diff --git a/fields/src/traits/field_parameters.rs b/fields/src/traits/field_parameters.rs index ba0c4a186a..d91a8f5d3b 100644 --- a/fields/src/traits/field_parameters.rs +++ b/fields/src/traits/field_parameters.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/traits/mod.rs b/fields/src/traits/mod.rs index a07b63a013..631e03fdc6 100644 --- a/fields/src/traits/mod.rs +++ b/fields/src/traits/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/traits/poseidon_default.rs b/fields/src/traits/poseidon_default.rs index a4d63dc405..0c5d3dd582 100644 --- a/fields/src/traits/poseidon_default.rs +++ b/fields/src/traits/poseidon_default.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,11 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{serial_batch_inversion_and_mul, PoseidonGrainLFSR, PrimeField}; +use crate::{PoseidonGrainLFSR, PrimeField, serial_batch_inversion_and_mul}; use aleo_std::{end_timer, start_timer}; use itertools::Itertools; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; /// Parameters and RNG used #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/fields/src/traits/poseidon_grain_lfsr.rs b/fields/src/traits/poseidon_grain_lfsr.rs index bcefe30fa6..e090096453 100644 --- a/fields/src/traits/poseidon_grain_lfsr.rs +++ b/fields/src/traits/poseidon_grain_lfsr.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,9 +16,9 @@ #![allow(dead_code)] use crate::{FieldParameters, PrimeField}; -use snarkvm_utilities::{vec::Vec, FromBits}; +use snarkvm_utilities::{FromBits, vec::Vec}; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; pub struct PoseidonGrainLFSR { pub field_size_in_bits: u64, diff --git a/fields/src/traits/prime_field.rs b/fields/src/traits/prime_field.rs index 35f5614148..d9ba38949f 100644 --- a/fields/src/traits/prime_field.rs +++ b/fields/src/traits/prime_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/traits/square_root_field.rs b/fields/src/traits/square_root_field.rs index a3d0e98520..2dfa0e3adb 100644 --- a/fields/src/traits/square_root_field.rs +++ b/fields/src/traits/square_root_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/traits/to_constraint_field.rs b/fields/src/traits/to_constraint_field.rs index dbd6012f8a..6a07a95d86 100644 --- a/fields/src/traits/to_constraint_field.rs +++ b/fields/src/traits/to_constraint_field.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/fields/src/traits/zero.rs b/fields/src/traits/zero.rs index 666898d56d..5ccf5e3254 100644 --- a/fields/src/traits/zero.rs +++ b/fields/src/traits/zero.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/Cargo.toml b/ledger/Cargo.toml index 6451d7b364..0b6502b0ce 100644 --- a/ledger/Cargo.toml +++ b/ledger/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A node ledger for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -21,6 +21,11 @@ name = "block" path = "benches/block.rs" harness = false +[[bench]] +name = "bonded_mapping" +path = "benches/bonded_mapping.rs" +harness = false + [[bench]] name = "transaction" path = "benches/transaction.rs" @@ -39,14 +44,14 @@ serial = [ "console/serial", "ledger-authority/serial", "ledger-block/serial", - "ledger-coinbase/serial", "ledger-committee/serial", "ledger-narwhal/serial", + "ledger-puzzle/serial", "ledger-query/serial", "ledger-store/serial", "synthesizer/serial" ] -test = [ "ledger-block/test", "ledger-store/test" ] +test = [ "console/test", "ledger-block/test", "ledger-store/test" ] test-helpers = [ "ledger-test-helpers", "ledger-committee/test-helpers", @@ -57,54 +62,54 @@ timer = [ "aleo-std/timer" ] [dependencies.console] package = "snarkvm-console" path = "../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-authority] package = "snarkvm-ledger-authority" path = "./authority" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-block] package = "snarkvm-ledger-block" path = "./block" -version = "=0.16.19" - -[dependencies.ledger-coinbase] -package = "snarkvm-ledger-coinbase" -path = "./coinbase" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-committee] package = "snarkvm-ledger-committee" path = "./committee" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-narwhal] package = "snarkvm-ledger-narwhal" path = "./narwhal" -version = "=0.16.19" +version = "=1.1.0" + +[dependencies.ledger-puzzle] +package = "snarkvm-ledger-puzzle" +path = "puzzle" +version = "=1.1.0" [dependencies.ledger-query] package = "snarkvm-ledger-query" path = "./query" -version = "=0.16.19" +version = "=1.1.0" features = [ "query" ] [dependencies.ledger-store] package = "snarkvm-ledger-store" path = "./store" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-test-helpers] package = "snarkvm-ledger-test-helpers" path = "./test-helpers" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.synthesizer] package = "snarkvm-synthesizer" path = "../synthesizer" -version = "=0.16.19" +version = "=1.1.0" [dependencies.aleo-std] version = "0.1.24" @@ -144,6 +149,16 @@ package = "snarkvm-ledger-block" path = "./block" features = [ "test" ] +[dev-dependencies.ledger-test-helpers] +package = "snarkvm-ledger-test-helpers" +path = "./test-helpers" + [dev-dependencies.serde_json] version = "1.0" features = [ "preserve_order" ] + +[dev-dependencies.snarkvm-circuit] +path = "../circuit" + +[dev-dependencies.snarkvm-utilities] +path = "../utilities" diff --git a/ledger/authority/Cargo.toml b/ledger/authority/Cargo.toml index bf1ce00d77..6774115c22 100644 --- a/ledger/authority/Cargo.toml +++ b/ledger/authority/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-authority" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Data structures for a block authority in a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -32,12 +32,12 @@ test-helpers = [ "narwhal-subdag/test-helpers" ] [dependencies.console] package = "snarkvm-console" path = "../../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.narwhal-subdag] package = "snarkvm-ledger-narwhal-subdag" path = "../narwhal/subdag" -version = "=0.16.19" +version = "=1.1.0" [dependencies.anyhow] version = "1" diff --git a/ledger/authority/src/bytes.rs b/ledger/authority/src/bytes.rs index 1d710be1c6..3935971bed 100644 --- a/ledger/authority/src/bytes.rs +++ b/ledger/authority/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/authority/src/lib.rs b/ledger/authority/src/lib.rs index a3fcf38adf..526be0cfc8 100644 --- a/ledger/authority/src/lib.rs +++ b/ledger/authority/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -23,10 +24,6 @@ use console::{ account::{Address, PrivateKey, Signature}, network::Network, prelude::{ - de, - error, - fmt, - ser, Debug, Deserialize, DeserializeExt, @@ -45,6 +42,10 @@ use console::{ ToBytes, ToBytesSerializer, Write, + de, + error, + fmt, + ser, }, types::Field, }; @@ -119,7 +120,7 @@ pub mod test_helpers { use super::*; use console::prelude::{TestRng, Uniform}; - pub type CurrentNetwork = console::network::Testnet3; + pub type CurrentNetwork = console::network::MainnetV0; /// Returns a sample beacon authority. pub fn sample_beacon_authority(rng: &mut TestRng) -> Authority { diff --git a/ledger/authority/src/serialize.rs b/ledger/authority/src/serialize.rs index 0abe9c49c7..72208f60c6 100644 --- a/ledger/authority/src/serialize.rs +++ b/ledger/authority/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -55,7 +56,7 @@ impl<'de, N: Network> Deserialize<'de> for Authority { "quorum" => Ok(Self::from_quorum( DeserializeExt::take_from_value::(&mut authority, "subdag").map_err(de::Error::custom)?, )), - _ => Err(error("Invalid authority type")).map_err(de::Error::custom), + _ => Err(de::Error::custom(error("Invalid authority type"))), } } false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "authority"), diff --git a/ledger/authority/src/string.rs b/ledger/authority/src/string.rs index 922c80025d..5e132d1e69 100644 --- a/ledger/authority/src/string.rs +++ b/ledger/authority/src/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/benches/block.rs b/ledger/benches/block.rs index 1ddacaf8ad..81b8a7f98f 100644 --- a/ledger/benches/block.rs +++ b/ledger/benches/block.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,12 +16,12 @@ #[macro_use] extern crate criterion; -use console::{network::Testnet3, prelude::*}; +use console::{network::MainnetV0, prelude::*}; use ledger_block::Block; use criterion::Criterion; -type CurrentNetwork = Testnet3; +type CurrentNetwork = MainnetV0; /// Loads the genesis block. fn load_genesis_block() -> Block { diff --git a/ledger/benches/bonded_mapping.rs b/ledger/benches/bonded_mapping.rs new file mode 100644 index 0000000000..15dcc5d82c --- /dev/null +++ b/ledger/benches/bonded_mapping.rs @@ -0,0 +1,112 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +#[macro_use] +extern crate criterion; + +use console::{ + account::{Address, Field, PrivateKey}, + collections::U64, + network::MainnetV0, + program::{Identifier, Literal, Plaintext, ProgramID, Value}, +}; +use ledger_committee::{MAX_DELEGATORS, MIN_DELEGATOR_STAKE}; +use ledger_store::ConsensusStore; +use synthesizer::VM; + +#[cfg(not(feature = "rocks"))] +use ledger_store::helpers::memory::ConsensusMemory; +#[cfg(feature = "rocks")] +use ledger_store::helpers::rocksdb::ConsensusDB; + +use criterion::Criterion; +use indexmap::indexmap; +use std::{str::FromStr, time::Duration}; + +pub type CurrentNetwork = MainnetV0; +#[cfg(feature = "rocks")] +pub type CurrentStorage = ConsensusDB; +#[cfg(not(feature = "rocks"))] +pub type CurrentStorage = ConsensusMemory; + +pub const BONDED_INTERVALS: &[usize; 7] = &[10, 5_000, 10_000, 20_000, 40_000, 80_000, 100_000]; + +fn bench_bonded_mappings(c: &mut Criterion) { + // Construct the credits.aleo program ID. + let credits_program_id = ProgramID::from_str("credits.aleo").unwrap(); + // Construct the bonded mapping name. + let bonded_mapping = Identifier::from_str("bonded").unwrap(); + // Construct the bond_state identifiers. + let validator_identifier = Identifier::from_str("validator").unwrap(); + let microcredits_identifier = Identifier::from_str("microcredits").unwrap(); + // Create a DB store for the consensus. + let store = ConsensusStore::::open(None).unwrap(); + // Create a VM from the store. + let vm = VM::from(store).unwrap(); + // Create a sample validator address. + let validator_address = + Address::from_str("aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px").unwrap(); + + // Generate 100_000 bonded mapping entries. + let bonded_map = (0..(MAX_DELEGATORS as u64)) + .map(|i| { + // Generate a staker address. + let private_key = PrivateKey::try_from(Field::from_u64(i)).unwrap(); + let staker_address = Address::::try_from(&private_key).unwrap(); + + // Create the bonded state. + let bonded_state = indexmap! { + validator_identifier => Plaintext::from(Literal::Address(validator_address)), + microcredits_identifier => Plaintext::from(Literal::U64(U64::new(MIN_DELEGATOR_STAKE))), + }; + ( + Plaintext::from(Literal::Address(staker_address)), + Value::Plaintext(Plaintext::Struct(bonded_state, Default::default())), + ) + }) + .collect::, Value)>>(); + + // Get a key that exists within the bonded mapping. + let private_key = PrivateKey::try_from(Field::from_u64(5)).unwrap(); + let staker_address = Address::::try_from(&private_key).unwrap(); + let key = Plaintext::from(Literal::Address(staker_address)); + + // Insert increasing numbers of entries into the bonded mapping and bench get_value_speculative and get_value_confirmed at each interval. + BONDED_INTERVALS.iter().for_each(|num_entries| { + let entries = bonded_map.iter().take(*num_entries).cloned().collect::>(); + vm.finalize_store().replace_mapping(credits_program_id, bonded_mapping, entries).unwrap(); + + // Benchmark get_value_speculative on the bonded mapping. + c.bench_function(&format!("bonded mapping - get_value_speculative - {num_entries} entries"), |b| { + b.iter(|| { + vm.finalize_store().get_value_speculative(credits_program_id, bonded_mapping, &key).unwrap(); + }) + }); + + // Benchmark get_value_confirmed on the bonded mapping. + c.bench_function(&format!("bonded mapping - get_value_confirmed - {num_entries} entries"), |b| { + b.iter(|| { + vm.finalize_store().get_value_confirmed(credits_program_id, bonded_mapping, &key).unwrap(); + }) + }); + }); +} + +criterion_group! { + name = mappings; + config = Criterion::default().sample_size(100).measurement_time(Duration::from_secs(10)); + targets = bench_bonded_mappings +} +criterion_main!(mappings); diff --git a/ledger/benches/transaction.rs b/ledger/benches/transaction.rs index 233e15aa37..933b0918c0 100644 --- a/ledger/benches/transaction.rs +++ b/ledger/benches/transaction.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,20 +20,21 @@ extern crate criterion; use console::{ account::*, - network::Testnet3, + network::{MainnetV0, Network}, program::{Plaintext, Record, Value}, }; use ledger_block::Transition; -use ledger_store::{helpers::memory::ConsensusMemory, ConsensusStore}; -use synthesizer::{program::Program, VM}; +use ledger_store::{ConsensusStore, helpers::memory::ConsensusMemory}; +use synthesizer::{VM, program::Program}; use criterion::Criterion; use indexmap::IndexMap; fn initialize_vm( - private_key: &PrivateKey, + private_key: &PrivateKey, rng: &mut R, -) -> (VM>, Vec>>) { +) -> (VM>, Vec>>) { + // Initialize the VM. let vm = VM::from(ConsensusStore::open(None).unwrap()).unwrap(); // Initialize the genesis block. @@ -55,13 +57,13 @@ fn deploy(c: &mut Criterion) { let rng = &mut TestRng::default(); // Sample a new private key and address. - let private_key = PrivateKey::::new(rng).unwrap(); + let private_key = PrivateKey::::new(rng).unwrap(); // Initialize the VM. let (vm, records) = initialize_vm(&private_key, rng); // Create a sample program. - let program = Program::::from_str( + let program = Program::::from_str( r" program helloworld.aleo; @@ -88,7 +90,7 @@ fn execute(c: &mut Criterion) { let rng = &mut TestRng::default(); // Sample a new private key and address. - let private_key = PrivateKey::::new(rng).unwrap(); + let private_key = PrivateKey::::new(rng).unwrap(); let address = Address::try_from(&private_key).unwrap(); // Initialize the VM. @@ -96,9 +98,11 @@ fn execute(c: &mut Criterion) { { // Prepare the inputs. - let inputs = - [Value::::from_str(&address.to_string()).unwrap(), Value::::from_str("1u64").unwrap()] - .into_iter(); + let inputs = [ + Value::::from_str(&address.to_string()).unwrap(), + Value::::from_str("1u64").unwrap(), + ] + .into_iter(); // Authorize the execution. let execute_authorization = vm.authorize(&private_key, "credits.aleo", "transfer_public", inputs, rng).unwrap(); @@ -123,6 +127,13 @@ fn execute(c: &mut Criterion) { .execute_authorization(execute_authorization.replicate(), Some(fee_authorization.replicate()), None, rng) .unwrap(); + // Bench the Transaction.write_le method using the LimitedWriter. + c.bench_function("LimitedWriter::new - transfer_public", |b| { + let mut buffer = Vec::with_capacity(3000); + b.iter(|| transaction.write_le(LimitedWriter::new(&mut buffer, MainnetV0::MAX_TRANSACTION_SIZE))) + }); + + // Bench the execution of transfer_public. c.bench_function("Transaction::Execute(transfer_public) - verify", |b| { b.iter(|| vm.check_transaction(&transaction, None, rng).unwrap()) }); @@ -131,9 +142,9 @@ fn execute(c: &mut Criterion) { { // Prepare the inputs. let inputs = [ - Value::::Record(records[0].clone()), - Value::::from_str(&address.to_string()).unwrap(), - Value::::from_str("1u64").unwrap(), + Value::::Record(records[0].clone()), + Value::::from_str(&address.to_string()).unwrap(), + Value::::from_str("1u64").unwrap(), ] .into_iter(); @@ -145,6 +156,7 @@ fn execute(c: &mut Criterion) { // Authorize the fee. let fee_authorization = vm.authorize_fee_public(&private_key, 300000, 1000, execution_id, rng).unwrap(); + // Bench the execution of transfer_private. c.bench_function("Transaction::Execute(transfer_private)", |b| { b.iter(|| { vm.execute_authorization( @@ -161,10 +173,106 @@ fn execute(c: &mut Criterion) { .execute_authorization(execute_authorization.replicate(), Some(fee_authorization.replicate()), None, rng) .unwrap(); + // Bench the Transaction.write_le method using the LimitedWriter. + c.bench_function("LimitedWriter::new - transfer_private", |b| { + let mut buffer = Vec::with_capacity(3000); + b.iter(|| transaction.write_le(LimitedWriter::new(&mut buffer, MainnetV0::MAX_TRANSACTION_SIZE))) + }); + + // Bench the check_transaction method. c.bench_function("Transaction::Execute(transfer_private) - verify", |b| { b.iter(|| vm.check_transaction(&transaction, None, rng).unwrap()) }); } + + // Bench Transaction.write_le + VM.check_transaction methods for transactions above the maximum transaction size. + { + // Define a program that will create an execution transaction larger than the maximum transaction size. + let program = Program::::from_str( + r" +program too_big.aleo; + +struct all_groups: + g1 as [[[group; 4u32]; 4u32]; 4u32]; + g2 as [[[group; 4u32]; 4u32]; 4u32]; + +struct nested_groups: + g1 as all_groups; + g2 as all_groups; + +function main: + // Input the amount of microcredits to unbond. + input r0 as group.public; + cast r0 r0 r0 r0 into r1 as [group; 4u32]; + cast r1 r1 r1 r1 into r2 as [[group; 4u32]; 4u32]; + cast r2 r2 r2 r2 into r3 as [[[group; 4u32]; 4u32]; 4u32]; + cast r3 r3 into r4 as all_groups; + cast r4 r4 into r5 as nested_groups; + cast r4 r4 into r6 as nested_groups; + cast r4 r4 into r7 as nested_groups; + cast r4 r4 into r8 as nested_groups; + cast r4 r4 into r9 as nested_groups; + cast r4 r4 into r10 as nested_groups; + cast r4 r4 into r11 as nested_groups; + cast r4 r4 into r12 as nested_groups; + cast r4 r4 into r13 as nested_groups; + cast r4 r4 into r14 as nested_groups; + cast r4 r4 into r15 as nested_groups; + cast r4 r4 into r16 as nested_groups; + cast r4 r4 into r17 as nested_groups; + cast r4 r4 into r18 as nested_groups; + cast r4 r4 into r19 as nested_groups; + cast r4 r4 into r20 as nested_groups; + cast r4 r4 into r21 as nested_groups; + cast r4 r4 into r22 as nested_groups; + cast r4 r4 into r23 as nested_groups; + cast r4 r4 into r24 as nested_groups; + cast r4 r4 into r25 as nested_groups; + cast r4 r4 into r26 as nested_groups; + cast r4 r4 into r27 as nested_groups; + cast r4 r4 into r28 as nested_groups; + cast r4 r4 into r29 as nested_groups; + cast r4 r4 into r30 as nested_groups; + cast r4 r4 into r31 as nested_groups; + output r7 as nested_groups.public; + output r8 as nested_groups.public; + output r9 as nested_groups.public; + output r10 as nested_groups.public; + output r11 as nested_groups.public; + output r12 as nested_groups.public; + output r13 as nested_groups.public; + output r14 as nested_groups.public; + output r15 as nested_groups.public; + output r16 as nested_groups.public; + output r17 as nested_groups.public; + output r18 as nested_groups.public; + output r19 as nested_groups.public; + output r20 as nested_groups.public; + output r21 as nested_groups.public; + output r22 as nested_groups.public; + ", + ) + .unwrap(); + // Prepare the inputs. + let inputs = [Value::from_str("2group").unwrap()].into_iter(); + + // Add the program to the VM. + vm.process().write().add_program(&program).unwrap(); + + // Create an execution transaction that is 164613 bytes in size. + let transaction = vm.execute(&private_key, ("too_big.aleo", "main"), inputs, None, 0, None, rng).unwrap(); + + // Bench the Transaction.write_le method using the LimitedWriter. + c.bench_function("LimitedWriter::new - too_big.aleo", |b| { + let mut buffer = Vec::with_capacity(MainnetV0::MAX_TRANSACTION_SIZE); + b.iter(|| transaction.write_le(LimitedWriter::new(&mut buffer, MainnetV0::MAX_TRANSACTION_SIZE))) + }); + + // Bench the check_transaction method. + c.bench_function("Transaction::Execute(too_big.aleo) - verify", |b| { + b.iter(|| vm.check_transaction(&transaction, None, rng)) + }); + } } criterion_group! { diff --git a/ledger/block/Cargo.toml b/ledger/block/Cargo.toml index 7174c09fbc..59ea5bb4bf 100644 --- a/ledger/block/Cargo.toml +++ b/ledger/block/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-block" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A block for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -21,7 +21,7 @@ default = [ "indexmap/rayon", "rayon" ] serial = [ "console/serial", "ledger-authority/serial", - "ledger-coinbase/serial", + "ledger-puzzle/serial", "ledger-committee/serial", "synthesizer-program/serial", "synthesizer-snark/serial" @@ -29,7 +29,7 @@ serial = [ wasm = [ "console/wasm", "ledger-authority/wasm", - "ledger-coinbase/wasm", + "ledger-puzzle/wasm", "ledger-committee/wasm", "synthesizer-program/wasm", "synthesizer-snark/wasm" @@ -39,47 +39,52 @@ test = [ ] [dependencies.console] package = "snarkvm-console" path = "../../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-authority] package = "snarkvm-ledger-authority" path = "../authority" -version = "=0.16.19" - -[dependencies.ledger-coinbase] -package = "snarkvm-ledger-coinbase" -path = "../../ledger/coinbase" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-committee] package = "snarkvm-ledger-committee" path = "../../ledger/committee" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-narwhal-batch-header] package = "snarkvm-ledger-narwhal-batch-header" path = "../narwhal/batch-header" -version = "=0.16.19" +version = "=1.1.0" + +[dependencies.ledger-narwhal-data] +package = "snarkvm-ledger-narwhal-data" +path = "../narwhal/data" +version = "=1.1.0" [dependencies.ledger-narwhal-subdag] package = "snarkvm-ledger-narwhal-subdag" path = "../narwhal/subdag" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-narwhal-transmission-id] package = "snarkvm-ledger-narwhal-transmission-id" path = "../narwhal/transmission-id" -version = "=0.16.19" +version = "=1.1.0" + +[dependencies.ledger-puzzle] +package = "snarkvm-ledger-puzzle" +path = "../puzzle" +version = "=1.1.0" [dependencies.synthesizer-program] package = "snarkvm-synthesizer-program" path = "../../synthesizer/program" -version = "=0.16.19" +version = "=1.1.0" [dependencies.synthesizer-snark] package = "snarkvm-synthesizer-snark" path = "../../synthesizer/snark" -version = "=0.16.19" +version = "=1.1.0" [dependencies.indexmap] version = "2.0" diff --git a/ledger/block/src/bytes.rs b/ledger/block/src/bytes.rs index 598731a696..bd258803b5 100644 --- a/ledger/block/src/bytes.rs +++ b/ledger/block/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -32,32 +33,39 @@ impl FromBytes for Block { // Read the header. let header = FromBytes::read_le(&mut reader)?; - // Write the authority. + // Read the authority. let authority = FromBytes::read_le(&mut reader)?; // Read the number of ratifications. let ratifications = Ratifications::read_le(&mut reader)?; // Read the solutions. - let solutions_variant = u8::read_le(&mut reader)?; - let solutions = match solutions_variant { - 0 => None, - 1 => Some(FromBytes::read_le(&mut reader)?), - _ => return Err(error("Invalid solutions variant in the block")), - }; + let solutions: Solutions = FromBytes::read_le(&mut reader)?; + + // Read the number of aborted solution IDs. + let num_aborted_solutions = u32::read_le(&mut reader)?; + // Ensure the number of aborted solutions IDs is within bounds (this is an early safety check). + if num_aborted_solutions as usize > Solutions::::MAX_ABORTED_SOLUTIONS { + return Err(error("Invalid number of aborted solutions IDs in the block")); + } + // Read the aborted solution IDs. + let mut aborted_solution_ids = Vec::with_capacity(num_aborted_solutions as usize); + for _ in 0..num_aborted_solutions { + aborted_solution_ids.push(FromBytes::read_le(&mut reader)?); + } // Read the transactions. let transactions = FromBytes::read_le(&mut reader)?; // Read the number of aborted transaction IDs. - let num_aborted = u32::read_le(&mut reader)?; + let num_aborted_transactions = u32::read_le(&mut reader)?; // Ensure the number of aborted transaction IDs is within bounds (this is an early safety check). - if num_aborted as usize > Transactions::::MAX_ABORTED_TRANSACTIONS { + if num_aborted_transactions as usize > Transactions::::MAX_ABORTED_TRANSACTIONS { return Err(error("Invalid number of aborted transaction IDs in the block")); } // Read the aborted transaction IDs. - let mut aborted_transaction_ids = Vec::with_capacity(num_aborted as usize); - for _ in 0..num_aborted { + let mut aborted_transaction_ids = Vec::with_capacity(num_aborted_transactions as usize); + for _ in 0..num_aborted_transactions { aborted_transaction_ids.push(FromBytes::read_le(&mut reader)?); } @@ -68,6 +76,7 @@ impl FromBytes for Block { authority, ratifications, solutions, + aborted_solution_ids, transactions, aborted_transaction_ids, ) @@ -102,13 +111,11 @@ impl ToBytes for Block { self.ratifications.write_le(&mut writer)?; // Write the solutions. - match self.solutions { - None => 0u8.write_le(&mut writer)?, - Some(ref solutions) => { - 1u8.write_le(&mut writer)?; - solutions.write_le(&mut writer)?; - } - } + self.solutions.write_le(&mut writer)?; + + // Write the aborted solution IDs. + (u32::try_from(self.aborted_solution_ids.len()).map_err(error))?.write_le(&mut writer)?; + self.aborted_solution_ids.write_le(&mut writer)?; // Write the transactions. self.transactions.write_le(&mut writer)?; @@ -122,9 +129,9 @@ impl ToBytes for Block { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { diff --git a/ledger/block/src/genesis.rs b/ledger/block/src/genesis.rs index 061c8ec370..1aa096e986 100644 --- a/ledger/block/src/genesis.rs +++ b/ledger/block/src/genesis.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -29,7 +30,7 @@ impl Block { // Ensure there is the correct number of ratification operations in the genesis block. && self.ratifications.len() == 1 // Ensure there are no solutions in the genesis block. - && self.solutions.is_none() + && self.solutions.is_empty() // Ensure there is the correct number of accepted transaction in the genesis block. && self.transactions.num_accepted() == Self::NUM_GENESIS_TRANSACTIONS // Ensure there is the correct number of rejected transaction in the genesis block. @@ -44,9 +45,9 @@ impl Block { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_genesis() { diff --git a/ledger/block/src/header/bytes.rs b/ledger/block/src/header/bytes.rs index 3ea781cfc2..37f3d55b32 100644 --- a/ledger/block/src/header/bytes.rs +++ b/ledger/block/src/header/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -69,9 +70,9 @@ impl ToBytes for Header { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { diff --git a/ledger/block/src/header/genesis.rs b/ledger/block/src/header/genesis.rs index 52c19e6ed8..ab351a0fe0 100644 --- a/ledger/block/src/header/genesis.rs +++ b/ledger/block/src/header/genesis.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -69,9 +70,9 @@ impl Header { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Returns the expected block header size by summing its subcomponent sizes. /// Update this method if the contents of a block header have changed. diff --git a/ledger/block/src/header/merkle.rs b/ledger/block/src/header/merkle.rs index bef088944f..98360dd934 100644 --- a/ledger/block/src/header/merkle.rs +++ b/ledger/block/src/header/merkle.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -89,9 +90,9 @@ impl Header { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u64 = 1_000; diff --git a/ledger/block/src/header/metadata/bytes.rs b/ledger/block/src/header/metadata/bytes.rs index f89a9046e3..0276bc6269 100644 --- a/ledger/block/src/header/metadata/bytes.rs +++ b/ledger/block/src/header/metadata/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -78,9 +79,9 @@ impl ToBytes for Metadata { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { diff --git a/ledger/block/src/header/metadata/genesis.rs b/ledger/block/src/header/metadata/genesis.rs index a3a107b228..63de6bcb11 100644 --- a/ledger/block/src/header/metadata/genesis.rs +++ b/ledger/block/src/header/metadata/genesis.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -72,9 +73,9 @@ impl Metadata { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Returns the expected metadata size by summing its subcomponent sizes. /// Update this method if the contents of the metadata have changed. diff --git a/ledger/block/src/header/metadata/mod.rs b/ledger/block/src/header/metadata/mod.rs index 842ecdccf7..568e7e0d9d 100644 --- a/ledger/block/src/header/metadata/mod.rs +++ b/ledger/block/src/header/metadata/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -172,7 +173,7 @@ impl Metadata { pub mod test_helpers { use super::*; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; /// Samples a block metadata. pub(crate) fn sample_block_metadata(rng: &mut TestRng) -> Metadata { diff --git a/ledger/block/src/header/metadata/serialize.rs b/ledger/block/src/header/metadata/serialize.rs index a756c2e55b..65ccd8b038 100644 --- a/ledger/block/src/header/metadata/serialize.rs +++ b/ledger/block/src/header/metadata/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -23,8 +24,8 @@ impl Serialize for Metadata { metadata.serialize_field("network", &self.network)?; metadata.serialize_field("round", &self.round)?; metadata.serialize_field("height", &self.height)?; - metadata.serialize_field("cumulative_weight", &self.cumulative_weight)?; - metadata.serialize_field("cumulative_proof_target", &self.cumulative_proof_target)?; + metadata.serialize_field("cumulative_weight", &self.cumulative_weight.to_string())?; + metadata.serialize_field("cumulative_proof_target", &self.cumulative_proof_target.to_string())?; metadata.serialize_field("coinbase_target", &self.coinbase_target)?; metadata.serialize_field("proof_target", &self.proof_target)?; metadata.serialize_field("last_coinbase_target", &self.last_coinbase_target)?; @@ -43,12 +44,18 @@ impl<'de, N: Network> Deserialize<'de> for Metadata { match deserializer.is_human_readable() { true => { let mut metadata = serde_json::Value::deserialize(deserializer)?; + let cumulative_weight: String = + DeserializeExt::take_from_value::(&mut metadata, "cumulative_weight")?; + let cumulative_proof_target: String = + DeserializeExt::take_from_value::(&mut metadata, "cumulative_proof_target")?; + let cumulative_weight = cumulative_weight.parse::().map_err(de::Error::custom)?; + let cumulative_proof_target = cumulative_proof_target.parse::().map_err(de::Error::custom)?; Ok(Self::new( DeserializeExt::take_from_value::(&mut metadata, "network")?, DeserializeExt::take_from_value::(&mut metadata, "round")?, DeserializeExt::take_from_value::(&mut metadata, "height")?, - DeserializeExt::take_from_value::(&mut metadata, "cumulative_weight")?, - DeserializeExt::take_from_value::(&mut metadata, "cumulative_proof_target")?, + cumulative_weight, + cumulative_proof_target, DeserializeExt::take_from_value::(&mut metadata, "coinbase_target")?, DeserializeExt::take_from_value::(&mut metadata, "proof_target")?, DeserializeExt::take_from_value::(&mut metadata, "last_coinbase_target")?, diff --git a/ledger/block/src/header/metadata/string.rs b/ledger/block/src/header/metadata/string.rs index 34f236f35e..5e890f2595 100644 --- a/ledger/block/src/header/metadata/string.rs +++ b/ledger/block/src/header/metadata/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/header/metadata/to_bits.rs b/ledger/block/src/header/metadata/to_bits.rs index ac89e5627a..82c9add277 100644 --- a/ledger/block/src/header/metadata/to_bits.rs +++ b/ledger/block/src/header/metadata/to_bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/header/metadata/to_hash.rs b/ledger/block/src/header/metadata/to_hash.rs index 03e8664937..01da9e2bb8 100644 --- a/ledger/block/src/header/metadata/to_hash.rs +++ b/ledger/block/src/header/metadata/to_hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/header/metadata/verify.rs b/ledger/block/src/header/metadata/verify.rs index aeff171c68..6ab2bb1ea7 100644 --- a/ledger/block/src/header/metadata/verify.rs +++ b/ledger/block/src/header/metadata/verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/header/mod.rs b/ledger/block/src/header/mod.rs index 0d29c81721..27ba50e113 100644 --- a/ledger/block/src/header/mod.rs +++ b/ledger/block/src/header/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -25,7 +26,7 @@ mod verify; use crate::{Ratifications, Transactions}; use console::{ network::prelude::*, - program::{HeaderLeaf, HeaderPath, HeaderTree, HEADER_DEPTH}, + program::{HEADER_DEPTH, HeaderLeaf, HeaderPath, HeaderTree}, types::Field, }; use synthesizer_program::FinalizeOperation; @@ -186,7 +187,7 @@ impl Header { pub mod test_helpers { use super::*; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; /// Samples a block header. pub(crate) fn sample_block_header(rng: &mut TestRng) -> Header { diff --git a/ledger/block/src/header/serialize.rs b/ledger/block/src/header/serialize.rs index 1736ff909b..4ab53983ce 100644 --- a/ledger/block/src/header/serialize.rs +++ b/ledger/block/src/header/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/header/string.rs b/ledger/block/src/header/string.rs index 8c53380bf0..be6866bc59 100644 --- a/ledger/block/src/header/string.rs +++ b/ledger/block/src/header/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/header/verify.rs b/ledger/block/src/header/verify.rs index 2ecef3bd5e..3f51e3b521 100644 --- a/ledger/block/src/header/verify.rs +++ b/ledger/block/src/header/verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/helpers/mod.rs b/ledger/block/src/helpers/mod.rs index 397d30577d..75c589b32b 100644 --- a/ledger/block/src/helpers/mod.rs +++ b/ledger/block/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/helpers/target.rs b/ledger/block/src/helpers/target.rs index ffb6265bd2..abff6b833e 100644 --- a/ledger/block/src/helpers/target.rs +++ b/ledger/block/src/helpers/target.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,18 +13,44 @@ // See the License for the specific language governing permissions and // limitations under the License. -use console::prelude::{ensure, Result}; +use console::prelude::{Network, Result, ensure}; /// A safety bound (sanity-check) for the coinbase reward. pub const MAX_COINBASE_REWARD: u64 = 190_258_739; // Coinbase reward at block 1. -/// Calculate the block reward, given the total supply, block time, coinbase reward, and transaction fees. -/// R_staking = floor((0.05 * S) / H_Y1) + CR / 2 + TX_F. +/// A the maximum block interval in seconds. This is used to upper bound the block interval in the V2 block reward calculation to +/// prevent the block reward from becoming too large in the event of a long block interval. +const V2_MAX_BLOCK_INTERVAL: i64 = 60; // 1 minute. +/// A the minimum block interval in seconds. This is used to lower bound the block interval in the V2 block reward calculation to +/// prevent the block reward from becoming too small in the event of an extremely short block interval. +const V2_MIN_BLOCK_INTERVAL: i64 = 1; // 1 second. + +/// The number of seconds in a year with 365 days. Leap years are ignored for simplicity. +const SECONDS_IN_A_YEAR: u32 = 60 * 60 * 24 * 365; + +/// Calculate the block reward based on the network’s consensus version, determined by the given block height. +pub fn block_reward( + block_height: u32, + total_supply: u64, + block_time: u16, + time_since_last_block: i64, + coinbase_reward: u64, + transaction_fees: u64, +) -> u64 { + // Determine which block reward version to use. + match block_height < N::CONSENSUS_V2_HEIGHT { + true => block_reward_v1(total_supply, block_time, coinbase_reward, transaction_fees), + false => block_reward_v2(total_supply, time_since_last_block, coinbase_reward, transaction_fees), + } +} + +/// Calculate the V1 block reward, given the total supply, block time, coinbase reward, and transaction fees. +/// R_staking = floor((0.05 * S) / H_Y1) + CR / 3 + TX_F. /// S = Total supply. /// H_Y1 = Expected block height at year 1. /// CR = Coinbase reward. /// TX_F = Transaction fees. -pub const fn block_reward(total_supply: u64, block_time: u16, coinbase_reward: u64, transaction_fees: u64) -> u64 { +pub const fn block_reward_v1(total_supply: u64, block_time: u16, coinbase_reward: u64, transaction_fees: u64) -> u64 { // Compute the expected block height at year 1. let block_height_at_year_1 = block_height_at_year(block_time, 1); // Compute the annual reward: (0.05 * S). @@ -31,24 +58,86 @@ pub const fn block_reward(total_supply: u64, block_time: u16, coinbase_reward: u // Compute the block reward: (0.05 * S) / H_Y1. let block_reward = annual_reward / block_height_at_year_1 as u64; // Return the sum of the block reward, coinbase reward, and transaction fees. - block_reward + (coinbase_reward / 2) + transaction_fees + block_reward + (coinbase_reward / 3) + transaction_fees +} + +/// Calculate the V2 block reward, given the total supply, block interval, coinbase reward, and transaction fees. +/// R_staking = floor((0.05 * S) * clamp(I, MIN_BI, MAX_BI) / S_Y) + CR / 3 + TX_F. +/// S = Total supply. +/// I = Seconds elapsed since last block. +/// S_Y = Seconds in a year (31536000). +/// CR = Coinbase reward. +/// TX_F = Transaction fees. +/// MIN_BI = Minimum block interval. +/// MAX_BI = Maximum block interval. +pub fn block_reward_v2( + total_supply: u64, + time_since_last_block: i64, + coinbase_reward: u64, + transaction_fees: u64, +) -> u64 { + // Compute the annual reward: (0.05 * S). + let annual_reward = total_supply / 20; + // Compute the seconds since last block with a maximum of `V2_MAX_BLOCK_INTERVAL` seconds and minimum of `V2_MIN_BLOCK_INTERVAL` seconds; + let time_since_last_block = time_since_last_block.clamp(V2_MIN_BLOCK_INTERVAL, V2_MAX_BLOCK_INTERVAL); + // Compute the block reward: (0.05 * S) * min(max(I, MIN_BLOCK_INTERVAL), MAX_BLOCK_INTERVAL) / S_Y. + let block_reward = annual_reward * time_since_last_block as u64 / SECONDS_IN_A_YEAR as u64; + // Return the sum of the block reward, coinbase reward, and transaction fees. + block_reward + (coinbase_reward / 3) + transaction_fees } /// Calculate the puzzle reward, given the coinbase reward. +/// The puzzle reward is 2/3 of the total coinbase reward and paid out to the provers. The other 1/3 of +/// the coinbase reward is included in the block reward and paid out to stakers. pub const fn puzzle_reward(coinbase_reward: u64) -> u64 { - // Return the coinbase reward divided by 2. - coinbase_reward / 2 + // Return the coinbase reward multiplied by 2 and divided by 3. + coinbase_reward.saturating_mul(2).saturating_div(3) } -/// Calculates the coinbase reward for a given block. -/// R_coinbase = max(0, H_Y10 - H) * R_anchor * min(P, C_R) / C -/// R_anchor = Anchor reward. -/// H_Y10 = Anchor block height at year 10. +/// Calculate the coinbase reward based on the network’s consensus version, determined by the given block height. +pub fn coinbase_reward( + block_height: u32, + block_timestamp: i64, + genesis_timestamp: i64, + starting_supply: u64, + anchor_time: u16, + anchor_height: u32, + block_time: u16, + combined_proof_target: u128, + cumulative_proof_target: u64, + coinbase_target: u64, +) -> Result { + // Determine which coinbase reward version to use. + match block_height < N::CONSENSUS_V2_HEIGHT { + true => coinbase_reward_v1( + block_height, + starting_supply, + anchor_height, + block_time, + combined_proof_target, + cumulative_proof_target, + coinbase_target, + ), + false => coinbase_reward_v2( + block_timestamp, + genesis_timestamp, + starting_supply, + anchor_time, + combined_proof_target, + cumulative_proof_target, + coinbase_target, + ), + } +} + +/// Calculates the V1 coinbase reward for a given block. +/// R_coinbase = R_anchor(H) * min(P, C_R) / C +/// R_anchor = Anchor reward at block height. /// H = Current block height. /// P = Combined proof target. /// C_R = Remaining coinbase target. /// C = Coinbase target. -pub fn coinbase_reward( +pub fn coinbase_reward_v1( block_height: u32, starting_supply: u64, anchor_height: u32, @@ -62,9 +151,6 @@ pub fn coinbase_reward( // Compute the remaining proof target. let remaining_proof_target = combined_proof_target.min(remaining_coinbase_target as u128); - /* Until the anchor block height at year 10, the coinbase reward is determined by this equation: */ - /* anchor_block_reward * remaining_proof_target / coinbase_target */ - // Compute the anchor block reward. let anchor_block_reward = anchor_block_reward_at_height(block_height, starting_supply, anchor_height, block_time); @@ -79,34 +165,142 @@ pub fn coinbase_reward( Ok(u64::try_from(reward).expect("Coinbase reward exceeds u64::MAX")) } +/// Calculates the V2 coinbase reward for a given block. +/// R_coinbase = R_anchor(H) * min(P, C_R) / C +/// R_anchor = Anchor reward at block height. +/// H = Current block height. +/// P = Combined proof target. +/// C_R = Remaining coinbase target. +/// C = Coinbase target. +pub fn coinbase_reward_v2( + block_timestamp: i64, + genesis_timestamp: i64, + starting_supply: u64, + anchor_time: u16, + combined_proof_target: u128, + cumulative_proof_target: u64, + coinbase_target: u64, +) -> Result { + // Compute the remaining coinbase target. + let remaining_coinbase_target = coinbase_target.saturating_sub(cumulative_proof_target); + // Compute the remaining proof target. + let remaining_proof_target = combined_proof_target.min(remaining_coinbase_target as u128); + + // Compute the anchor block reward. + let anchor_block_reward = + anchor_block_reward_at_timestamp(block_timestamp, genesis_timestamp, starting_supply, anchor_time); + + // Calculate the coinbase reward. + let reward = anchor_block_reward.saturating_mul(remaining_proof_target).saturating_div(coinbase_target as u128); + + // Ensure the coinbase reward is less than the maximum coinbase reward. + ensure!(reward <= MAX_COINBASE_REWARD as u128, "Coinbase reward ({reward}) exceeds maximum {MAX_COINBASE_REWARD}"); + + // Return the coinbase reward. + // Note: This '.expect' is guaranteed to be safe, as we ensure the reward is within a safe bound. + Ok(u64::try_from(reward).expect("Coinbase reward exceeds u64::MAX")) +} + /// Calculates the anchor block reward for the given block height. -/// R_anchor = floor((2 * S * H_A * H_R) / (H_Y10 * (H_Y10 + 1))). +/// The anchor block reward is upper bound of the coinbase reward for the given block before +/// calculating the final pro-rata coinbase reward based on the targets. +/// R_anchor = max(floor((2 * S * H_A * H_R) / (H_Y10 * (H_Y10 + 1))), R_Y9). /// S = Starting supply. /// H_A = Anchor block height. /// H_R = Remaining number of blocks until year 10. /// H_Y10 = Expected block height at year 10. -const fn anchor_block_reward_at_height( - block_height: u32, +/// R_Y9 = Reward at year 9. +fn anchor_block_reward_at_height(block_height: u32, starting_supply: u64, anchor_height: u32, block_time: u16) -> u128 { + // A helper function to calculate the reward at a given block height, without the year 9 baseline. + const fn block_reward_at_height(height: u32, starting_supply: u64, anchor_height: u32, block_time: u16) -> u128 { + // Calculate the block height at year 10. + let block_height_at_year_10 = block_height_at_year(block_time, 10) as u128; + // Compute the remaining blocks until year 10. + let num_remaining_blocks_to_year_10 = block_height_at_year_10.saturating_sub(height as u128); + // Compute the numerator. + let numerator = 2 * starting_supply as u128 * anchor_height as u128 * num_remaining_blocks_to_year_10; + // Compute the denominator. + let denominator = block_height_at_year_10 * (block_height_at_year_10 + 1); + // Compute the quotient. + numerator / denominator + } + + // Calculate the block height at year 9. + let block_height_at_year_9 = block_height_at_year(block_time, 9); + // Compute the unadjusted reward at year 9. + let reward_at_year_9 = block_reward_at_height(block_height_at_year_9, starting_supply, anchor_height, block_time); + // Compute the unadjusted reward at the given block height. + let reward_at_block_height = block_reward_at_height(block_height, starting_supply, anchor_height, block_time); + // Compute the anchor block reward. + reward_at_block_height.max(reward_at_year_9) +} + +/// Calculates the anchor block reward for the given block timestamp. +/// The anchor block reward is upper bound of the coinbase reward for the given block before +/// calculating the final pro-rata coinbase reward based on the targets. +/// This function uses timestamp rather than block height to determine the reward in order to combat +/// the volatility of block times and better align with human timescales. +/// R_anchor = max(floor((2 * S * T_A * T_R) / (T_Y10 * (T_Y10 + 1))), R_Y9). +/// S = Starting supply. +/// T_A = Anchor block time. +/// T_R = Remaining number of seconds until year 10. +/// T_Y10 = Number of seconds elapsed in 10 years. +/// R_Y9 = Reward at year 9. +fn anchor_block_reward_at_timestamp( + block_timestamp: i64, + genesis_timestamp: i64, starting_supply: u64, - anchor_height: u32, - block_time: u16, + anchor_time: u16, ) -> u128 { - // Calculate the block height at year 10. - let block_height_at_year_10 = block_height_at_year(block_time, 10) as u128; - // Compute the remaining blocks until year 10, as a u64. - let num_remaining_blocks_to_year_10 = block_height_at_year_10.saturating_sub(block_height as u128); - // Compute the numerator. - let numerator = 2 * starting_supply as u128 * anchor_height as u128 * num_remaining_blocks_to_year_10; - // Compute the denominator. - let denominator = block_height_at_year_10 * (block_height_at_year_10 + 1); - // Return the anchor block reward. - numerator / denominator + // A helper function to calculate the reward at a given block timestamp, without the year 9 baseline. + const fn block_reward_at_timestamp( + block_timestamp: i64, + genesis_timestamp: i64, + starting_supply: u64, + anchor_time: u16, + ) -> u128 { + // Calculate the timestamp at year 10. + let timestamp_at_year_10 = timestamp_at_year(genesis_timestamp, 10) as u128; + // Calculate the number of seconds elapsed in 10 years. + let number_of_seconds_in_10_years = (SECONDS_IN_A_YEAR as u128).saturating_mul(10); + // Compute the remaining seconds until year 10. + let num_remaining_seconds_to_year_10 = timestamp_at_year_10.saturating_sub(block_timestamp as u128); + + // Compute the numerator. + // Note that we perform a `saturating_div(10)` on the `anchor_time` in the numerator and the `number_of_seconds_in_10_years` denominator. + // This is done to to match the truncation of `anchor_block_reward_at_height` in an attempt to + // keep the reward more consistent between the two functions. + let numerator = + 2 * starting_supply as u128 * anchor_time.saturating_div(10) as u128 * num_remaining_seconds_to_year_10; + // Compute the denominator. + let denominator = number_of_seconds_in_10_years * (number_of_seconds_in_10_years.saturating_div(10) + 1); + // Compute the quotient. + numerator / denominator + } + + // Calculate the timestamp at year 9. + let timestamp_at_year_9 = timestamp_at_year(genesis_timestamp, 9); + // Compute the unadjusted reward at year 9. + let reward_at_year_9 = + block_reward_at_timestamp(timestamp_at_year_9, genesis_timestamp, starting_supply, anchor_time); + // Compute the unadjusted reward at the given block timestamp. + let reward_at_block_timestamp = + block_reward_at_timestamp(block_timestamp, genesis_timestamp, starting_supply, anchor_time); + // Compute the anchor block reward. + reward_at_block_timestamp.max(reward_at_year_9) +} + +/// Returns the timestamp for a given year, relative to the genesis timestamp. +/// We assume a year is 365 days and ignore leap years for simplicity. +const fn timestamp_at_year(genesis_timestamp: i64, num_years: u32) -> i64 { + // Calculate the number of seconds elapsed in `num_years`. + let seconds_elapsed = SECONDS_IN_A_YEAR.saturating_mul(num_years); + // Return the timestamp for the given year. + genesis_timestamp.saturating_add(seconds_elapsed as i64) } /// Returns the block height after a given number of years for a specific block time. -pub const fn block_height_at_year(block_time: u16, num_years: u32) -> u32 { - // Calculate the number of seconds in a year. - const SECONDS_IN_A_YEAR: u32 = 60 * 60 * 24 * 365; +const fn block_height_at_year(block_time: u16, num_years: u32) -> u32 { // Calculate the one-year block height. let block_height_at_year_1 = SECONDS_IN_A_YEAR / block_time as u32; // Return the block height for the given number of years. @@ -132,8 +326,11 @@ pub fn coinbase_target( } /// Calculate the minimum proof target for the given coinbase target. -pub fn proof_target(coinbase_target: u64, genesis_proof_target: u64) -> u64 { - coinbase_target.checked_shr(7).map(|target| target.saturating_add(1)).unwrap_or(genesis_proof_target) +pub fn proof_target(coinbase_target: u64, genesis_proof_target: u64, max_solutions_as_power_of_two: u8) -> u64 { + coinbase_target + .checked_shr(max_solutions_as_power_of_two as u32) + .map(|target| target.saturating_add(1)) + .unwrap_or(genesis_proof_target) } /// Retarget algorithm using fixed point arithmetic from https://www.reference.cash/protocol/forks/2020-11-15-asert. @@ -223,36 +420,134 @@ fn retarget( Ok(u64::try_from(candidate_target)?) } +/// This function calculates the next targets for the given attributes: +/// `latest_cumulative_proof_target`: The latest cumulative proof target. +/// `combined_proof_target`: The combined proof target of solutions in the block. +/// `latest_coinbase_target`: The latest coinbase target. +/// `last_coinbase_target`: The coinbase target for the last coinbase. +/// `last_coinbase_timestamp`: The timestamp for the last coinbase. +/// `next_timestamp`: The timestamp for the next block. +/// +/// Returns the following as a tuple: +/// `next_coinbase_target` - The next coinbase target. +/// `next_proof_target` - The next proof target. +/// `next_cumulative_proof_target` - The next cumulative proof target. +/// `next_cumulative_weight` - The next cumulative weight. +/// `next_last_coinbase_target` - The next last coinbase target. +/// `next_last_coinbase_timestamp` - The next last coinbase timestamp. +pub fn to_next_targets( + latest_cumulative_proof_target: u128, + combined_proof_target: u128, + latest_coinbase_target: u64, + latest_cumulative_weight: u128, + last_coinbase_target: u64, + last_coinbase_timestamp: i64, + next_timestamp: i64, +) -> Result<(u64, u64, u128, u128, u64, i64)> { + // Compute the coinbase target threshold. + let latest_coinbase_threshold = latest_coinbase_target.saturating_div(2) as u128; + // Compute the next cumulative proof target. + let next_cumulative_proof_target = latest_cumulative_proof_target.saturating_add(combined_proof_target); + // Determine if the coinbase target threshold is reached. + let is_coinbase_threshold_reached = next_cumulative_proof_target >= latest_coinbase_threshold; + // Construct the next coinbase target. + let next_coinbase_target = coinbase_target( + last_coinbase_target, + last_coinbase_timestamp, + next_timestamp, + N::ANCHOR_TIME, + N::NUM_BLOCKS_PER_EPOCH, + N::GENESIS_COINBASE_TARGET, + )?; + // Construct the next proof target. + let next_proof_target = + proof_target(next_coinbase_target, N::GENESIS_PROOF_TARGET, N::MAX_SOLUTIONS_AS_POWER_OF_TWO); + + // Update the next cumulative proof target, if necessary. + let next_cumulative_proof_target = match is_coinbase_threshold_reached { + true => 0, + false => next_cumulative_proof_target, + }; + + // Compute the next cumulative weight. + let next_cumulative_weight = latest_cumulative_weight.saturating_add(combined_proof_target); + + // Construct the next last coinbase target and next last coinbase timestamp. + let (next_last_coinbase_target, next_last_coinbase_timestamp) = match is_coinbase_threshold_reached { + true => (next_coinbase_target, next_timestamp), + false => (last_coinbase_target, last_coinbase_timestamp), + }; + + Ok(( + next_coinbase_target, + next_proof_target, + next_cumulative_proof_target, + next_cumulative_weight, + next_last_coinbase_target, + next_last_coinbase_timestamp, + )) +} + #[cfg(test)] mod tests { use super::*; - use console::network::{prelude::*, Testnet3}; + use console::network::{MainnetV0, TestnetV0, prelude::*}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u32 = 1000; const EXPECTED_ANCHOR_BLOCK_REWARD_AT_BLOCK_1: u128 = MAX_COINBASE_REWARD as u128; const EXPECTED_STAKING_REWARD: u64 = 23_782_343; const EXPECTED_COINBASE_REWARD_AT_BLOCK_1: u64 = MAX_COINBASE_REWARD; + const EXPECTED_MAX_STAKING_REWARD: u64 = 142_694_063; #[test] - fn test_anchor_block_reward() { - let reward = anchor_block_reward_at_height( + fn test_anchor_block_reward_v1() { + // Check the anchor block reward at block 1. + let reward_at_block_1 = anchor_block_reward_at_height( 1, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, CurrentNetwork::BLOCK_TIME, ); - assert_eq!(reward, EXPECTED_ANCHOR_BLOCK_REWARD_AT_BLOCK_1); + assert_eq!(reward_at_block_1, EXPECTED_ANCHOR_BLOCK_REWARD_AT_BLOCK_1); - // Calculate the block height at year 10. - let block_height_at_year_10 = block_height_at_year(CurrentNetwork::BLOCK_TIME, 10); + // A helper function to check the the reward at the first expected block of a given year. + fn check_reward_at_year(year: u32, expected_reward: u128) { + let reward_at_year = anchor_block_reward_at_height( + block_height_at_year(CurrentNetwork::BLOCK_TIME, year), + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_HEIGHT, + CurrentNetwork::BLOCK_TIME, + ); + assert_eq!(reward_at_year, expected_reward); + } - // Ensure that the reward is decreasing for blocks before year 10. - let mut previous_reward = reward; + // Check the anchor block reward at the start of years 1 through 15. + check_reward_at_year(1, 171_232_871); + check_reward_at_year(2, 152_206_996); + check_reward_at_year(3, 133_181_122); + check_reward_at_year(4, 114_155_247); + check_reward_at_year(5, 95_129_372); + check_reward_at_year(6, 76_103_498); + check_reward_at_year(7, 57_077_623); + check_reward_at_year(8, 38_051_749); + check_reward_at_year(9, 19_025_874); + check_reward_at_year(10, 19_025_874); + check_reward_at_year(11, 19_025_874); + check_reward_at_year(12, 19_025_874); + check_reward_at_year(13, 19_025_874); + check_reward_at_year(14, 19_025_874); + check_reward_at_year(15, 19_025_874); + + // Calculate the block height at year 9. + let block_height_at_year_9 = block_height_at_year(CurrentNetwork::BLOCK_TIME, 9); + + // Ensure that the reward is decreasing for blocks before year 9. + let mut previous_reward = reward_at_block_1; let anchor_height = CurrentNetwork::ANCHOR_HEIGHT as usize; - for height in (2..block_height_at_year_10).step_by(anchor_height).skip(1) { + for height in (2..block_height_at_year_9).step_by(anchor_height).skip(1) { let reward = anchor_block_reward_at_height( height, CurrentNetwork::STARTING_SUPPLY, @@ -263,38 +558,443 @@ mod tests { previous_reward = reward; } - // Ensure that the reward is zero for blocks after year 10. - for height in block_height_at_year_10..(block_height_at_year_10 + ITERATIONS) { + // Ensure that the reward is 19_025_874 for blocks after year 9. + for height in block_height_at_year_9..(block_height_at_year_9 + ITERATIONS) { let reward = anchor_block_reward_at_height( height, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, CurrentNetwork::BLOCK_TIME, ); - assert_eq!(reward, 0); + assert_eq!(reward, 19_025_874); } } + #[test] + fn test_anchor_block_reward_v2() { + // Check the anchor block reward at block 1. + let reward_at_block_1 = anchor_block_reward_at_timestamp( + CurrentNetwork::GENESIS_TIMESTAMP + CurrentNetwork::BLOCK_TIME as i64, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + ); + assert_eq!(reward_at_block_1, EXPECTED_ANCHOR_BLOCK_REWARD_AT_BLOCK_1); + + // A helper function to check the the reward at the first expected block of a given year. + fn check_reward_at_year(year: u32, expected_reward: u128) { + let reward_at_year = anchor_block_reward_at_timestamp( + timestamp_at_year(CurrentNetwork::GENESIS_TIMESTAMP, year), + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + ); + assert_eq!(reward_at_year, expected_reward); + } + + // Check the anchor block reward at the start of years 1 through 15. + check_reward_at_year(1, 171_232_871); + check_reward_at_year(2, 152_206_996); + check_reward_at_year(3, 133_181_122); + check_reward_at_year(4, 114_155_247); + check_reward_at_year(5, 95_129_372); + check_reward_at_year(6, 76_103_498); + check_reward_at_year(7, 57_077_623); + check_reward_at_year(8, 38_051_749); + check_reward_at_year(9, 19_025_874); + check_reward_at_year(10, 19_025_874); + check_reward_at_year(11, 19_025_874); + check_reward_at_year(12, 19_025_874); + check_reward_at_year(13, 19_025_874); + check_reward_at_year(14, 19_025_874); + check_reward_at_year(15, 19_025_874); + + // Calculate the timestamp at year 9. + let timestamp_at_year_9 = timestamp_at_year(CurrentNetwork::GENESIS_TIMESTAMP, 9); + + // Ensure that the reward is decreasing for blocks before year 9. + let mut previous_reward = reward_at_block_1; + let anchor_time = CurrentNetwork::ANCHOR_TIME as usize; + for timestamp in (CurrentNetwork::GENESIS_TIMESTAMP..timestamp_at_year_9).step_by(anchor_time).skip(1) { + let reward = anchor_block_reward_at_timestamp( + timestamp, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + ); + assert!(reward < previous_reward, "Failed on timestamp {timestamp}"); + previous_reward = reward; + } + + // Ensure that the reward is 19_025_874 for blocks after year 9. + for timestamp in timestamp_at_year_9..(timestamp_at_year_9 + ITERATIONS as i64) { + let reward = anchor_block_reward_at_timestamp( + timestamp, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + ); + assert_eq!(reward, 19_025_874); + } + } + + #[test] + fn test_total_anchor_block_reward_v1() { + // A helper function used to add the anchor block reward for a given range of block heights. + fn add_anchor_block_reward(total_reward: &mut u128, start_height: u32, end_height: u32) { + for height in start_height..end_height { + *total_reward += anchor_block_reward_at_height( + height, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_HEIGHT, + CurrentNetwork::BLOCK_TIME, + ); + } + } + + // Initialize the total reward. + let mut total_reward = 0; + + // A helper function to check the sum of all possible anchor rewards over a given year. + let mut check_sum_of_anchor_rewards = |year: u32, expected_reward: u128| { + assert!(year > 0, "Year must be greater than 0"); + let end_height = block_height_at_year(CurrentNetwork::BLOCK_TIME, year); + let start_height = std::cmp::max(1, block_height_at_year(CurrentNetwork::BLOCK_TIME, year - 1)); + add_anchor_block_reward(&mut total_reward, start_height, end_height); + assert_eq!(total_reward, expected_reward); + }; + + // Check the sum of all anchor block rewards at block at year 1. + check_sum_of_anchor_rewards(1, 569999799602807); + // Check the sum of all anchor block rewards at block at year 2. + check_sum_of_anchor_rewards(2, 1079999791366949); + // Check the sum of all anchor block rewards at block at year 3. + check_sum_of_anchor_rewards(3, 1529999785033683); + // Check the sum of all anchor block rewards at block at year 4. + check_sum_of_anchor_rewards(4, 1919999780603002); + // Check the sum of all anchor block rewards at block at year 5. + check_sum_of_anchor_rewards(5, 2249999778074916); + // Check the sum of all anchor block rewards at block at year 6. + check_sum_of_anchor_rewards(6, 2519999777449404); + // Check the sum of all anchor block rewards at block at year 7. + check_sum_of_anchor_rewards(7, 2729999778726485); + // Check the sum of all anchor block rewards at block at year 8. + check_sum_of_anchor_rewards(8, 2879999781906155); + // Check the sum of all anchor block rewards at block at year 9. + check_sum_of_anchor_rewards(9, 2969999786988413); + // Check the sum of all anchor block rewards at block at year 10. + check_sum_of_anchor_rewards(10, 3029999783234813); + // Check the sum of all anchor block rewards at block at year 11. + check_sum_of_anchor_rewards(11, 3089999779481213); + // Check the sum of all anchor block rewards at block at year 12. + check_sum_of_anchor_rewards(12, 3149999775727613); + // Check the sum of all anchor block rewards at block at year 13. + check_sum_of_anchor_rewards(13, 3209999771974013); + // Check the sum of all anchor block rewards at block at year 14. + check_sum_of_anchor_rewards(14, 3269999768220413); + // Check the sum of all anchor block rewards at block at year 15. + check_sum_of_anchor_rewards(15, 3329999764466813); + } + + #[test] + fn test_total_anchor_block_reward_v2() { + // A helper function used to add the anchor block reward for a given range of block timestamps. + fn add_anchor_block_reward(total_reward: &mut u128, start_timestamp: i64, end_timestamp: i64) { + for timestamp in (start_timestamp..end_timestamp).step_by(CurrentNetwork::BLOCK_TIME as usize) { + *total_reward += anchor_block_reward_at_timestamp( + timestamp, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + ); + } + } + + // Initialize the total reward. + let mut total_reward = 0; + + // A helper function to check the sum of all possible anchor rewards over a given year. + let mut check_sum_of_anchor_rewards = |year: u32, expected_reward: u128| { + assert!(year > 0, "Year must be greater than 0"); + let end_timestamp = timestamp_at_year(CurrentNetwork::GENESIS_TIMESTAMP, year); + let start_timestamp = std::cmp::max( + CurrentNetwork::GENESIS_TIMESTAMP, + timestamp_at_year(CurrentNetwork::GENESIS_TIMESTAMP, year - 1), + ); + add_anchor_block_reward(&mut total_reward, start_timestamp, end_timestamp); + // println!("year {year}, total_reward: {total_reward} expected_reward: {expected_reward}") + assert_eq!(total_reward, expected_reward); + }; + + // Check the sum of all anchor block rewards at block at year 1. + check_sum_of_anchor_rewards(1, 569999989861552); + // Check the sum of all anchor block rewards at block at year 2. + check_sum_of_anchor_rewards(2, 1079999981625694); + // Check the sum of all anchor block rewards at block at year 3. + check_sum_of_anchor_rewards(3, 1529999975292428); + // Check the sum of all anchor block rewards at block at year 4. + check_sum_of_anchor_rewards(4, 1919999970861747); + // Check the sum of all anchor block rewards at block at year 5. + check_sum_of_anchor_rewards(5, 2249999968333661); + // Check the sum of all anchor block rewards at block at year 6. + check_sum_of_anchor_rewards(6, 2519999967708149); + // Check the sum of all anchor block rewards at block at year 7. + check_sum_of_anchor_rewards(7, 2729999968985230); + // Check the sum of all anchor block rewards at block at year 8. + check_sum_of_anchor_rewards(8, 2879999972164900); + // Check the sum of all anchor block rewards at block at year 9. + check_sum_of_anchor_rewards(9, 2969999977247158); + // Check the sum of all anchor block rewards at block at year 10. + check_sum_of_anchor_rewards(10, 3029999973493558); + // Check the sum of all anchor block rewards at block at year 11. + check_sum_of_anchor_rewards(11, 3089999969739958); + // Check the sum of all anchor block rewards at block at year 12. + check_sum_of_anchor_rewards(12, 3149999965986358); + // Check the sum of all anchor block rewards at block at year 13. + check_sum_of_anchor_rewards(13, 3209999962232758); + // Check the sum of all anchor block rewards at block at year 14. + check_sum_of_anchor_rewards(14, 3269999958479158); + // Check the sum of all anchor block rewards at block at year 15. + check_sum_of_anchor_rewards(15, 3329999954725558); + } + #[test] fn test_block_reward() { - let reward = block_reward(CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::BLOCK_TIME, 0, 0); + let mut rng = TestRng::default(); + + // Ensure that a block height of `TestnetV0::CONSENSUS_V2_HEIGHT` uses block reward V2. + let time_since_last_block = rng.gen_range(1..=V2_MAX_BLOCK_INTERVAL); + let reward = block_reward::( + TestnetV0::CONSENSUS_V2_HEIGHT, + TestnetV0::STARTING_SUPPLY, + TestnetV0::BLOCK_TIME, + time_since_last_block, + 0, + 0, + ); + let expected_reward = block_reward_v2(TestnetV0::STARTING_SUPPLY, time_since_last_block, 0, 0); + assert_eq!(reward, expected_reward); + + for _ in 0..100 { + // Check that the block reward is correct for the first consensus version. + let consensus_v1_height = rng.gen_range(0..TestnetV0::CONSENSUS_V2_HEIGHT); + let consensus_v1_reward = block_reward::( + consensus_v1_height, + TestnetV0::STARTING_SUPPLY, + TestnetV0::BLOCK_TIME, + 0, + 0, + 0, + ); + let expected_reward = block_reward_v1(TestnetV0::STARTING_SUPPLY, TestnetV0::BLOCK_TIME, 0, 0); + assert_eq!(consensus_v1_reward, expected_reward); + + // Check that the block reward is correct for the second consensus version. + let consensus_v2_height = rng.gen_range(TestnetV0::CONSENSUS_V2_HEIGHT..u32::MAX); + let time_since_last_block = rng.gen_range(1..=V2_MAX_BLOCK_INTERVAL); + let consensus_v2_reward = block_reward::( + consensus_v2_height, + TestnetV0::STARTING_SUPPLY, + TestnetV0::BLOCK_TIME, + time_since_last_block, + 0, + 0, + ); + let expected_reward = block_reward_v2(TestnetV0::STARTING_SUPPLY, time_since_last_block, 0, 0); + assert_eq!(consensus_v2_reward, expected_reward); + } + } + + #[test] + fn test_block_reward_v1() { + let reward = block_reward_v1(CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::BLOCK_TIME, 0, 0); + assert_eq!(reward, EXPECTED_STAKING_REWARD); + + // Increasing the anchor time will increase the reward. + let larger_reward = block_reward_v1(CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::BLOCK_TIME + 1, 0, 0); + assert!(reward < larger_reward); + + // Decreasing the anchor time will decrease the reward. + let smaller_reward = block_reward_v1(CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::BLOCK_TIME - 1, 0, 0); + assert!(reward > smaller_reward); + } + + #[test] + fn test_block_reward_v2() { + let reward = block_reward_v2(CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::BLOCK_TIME as i64, 0, 0); assert_eq!(reward, EXPECTED_STAKING_REWARD); // Increasing the anchor time will increase the reward. - let larger_reward = block_reward(CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::BLOCK_TIME + 1, 0, 0); + let larger_reward = + block_reward_v2(CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::BLOCK_TIME as i64 + 1, 0, 0); assert!(reward < larger_reward); // Decreasing the anchor time will decrease the reward. - let smaller_reward = block_reward(CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::BLOCK_TIME - 1, 0, 0); + let smaller_reward = + block_reward_v2(CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::BLOCK_TIME as i64 - 1, 0, 0); assert!(reward > smaller_reward); + + // Increasing the block interval past `V2_MAX_BLOCK_INTERVAL` does not increase the reward. + let max_reward = block_reward_v2(CurrentNetwork::STARTING_SUPPLY, V2_MAX_BLOCK_INTERVAL, 0, 0); + assert_eq!(max_reward, EXPECTED_MAX_STAKING_REWARD); + let equivalent_reward = block_reward_v2(CurrentNetwork::STARTING_SUPPLY, V2_MAX_BLOCK_INTERVAL + 1, 0, 0); + assert_eq!(max_reward, equivalent_reward); + + // Test that there is a minimum block reward when the time since last block is 1 second. + let min_reward = block_reward_v2(CurrentNetwork::STARTING_SUPPLY, 1, 0, 0); + let equivalent_reward = block_reward_v2(CurrentNetwork::STARTING_SUPPLY, 0, 0, 0); + assert_eq!(min_reward, equivalent_reward); + } + + #[test] + fn test_block_reward_v1_vs_v2() { + let mut rng = TestRng::default(); + + // Declare a tolerance for reward divergence between v1 and v2 due to truncation. + const TOLERANCE: f64 = 0.001; // 0.1% tolerance + + // Expect that the v2 block reward is equivalent to the v1 block reward if the `CurrentNetwork::BLOCK_TIME` is fixed. + let reward_v1 = block_reward_v1(CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::BLOCK_TIME, 0, 0); + assert_eq!(reward_v1, EXPECTED_STAKING_REWARD); + let reward_v2 = block_reward_v2(CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::BLOCK_TIME as i64, 0, 0); + assert_eq!(reward_v1, reward_v2); + + // Decreasing the time since last block based on `CurrentNetwork::BLOCK_TIME` will proportionally reduce the v2 rewards. + let shorter_time = CurrentNetwork::BLOCK_TIME / 2; + let smaller_reward = block_reward_v2(CurrentNetwork::STARTING_SUPPLY, shorter_time as i64, 0, 0); + let expected_reward = EXPECTED_STAKING_REWARD / 2; + assert!((smaller_reward as f64 - expected_reward as f64).abs() / expected_reward as f64 <= TOLERANCE); + + // Increasing the time since last block based on `CurrentNetwork::BLOCK_TIME` will proportionally increase the v2 rewards (up to a certain cap). + let longer_time = CurrentNetwork::BLOCK_TIME * 2; + let larger_reward = block_reward_v2(CurrentNetwork::STARTING_SUPPLY, longer_time as i64, 0, 0); + let expected_reward = EXPECTED_STAKING_REWARD * 2; + assert!((larger_reward as f64 - expected_reward as f64).abs() / expected_reward as f64 <= TOLERANCE); + + for _ in 0..10 { + // Randomly sample the time factor. + let factor = rng.gen_range(1..10); + + // Ensure that scaling the time elapsed down scales the reward down proportionally. + let shorter_time = CurrentNetwork::BLOCK_TIME / factor; + let time_factor: f64 = CurrentNetwork::BLOCK_TIME as f64 / shorter_time as f64; + let smaller_reward = block_reward_v2(CurrentNetwork::STARTING_SUPPLY, shorter_time as i64, 0, 0); + let expected_reward = (EXPECTED_STAKING_REWARD as f64 / time_factor) as u64; + assert!((smaller_reward as f64 - expected_reward as f64).abs() / expected_reward as f64 <= TOLERANCE); + + // Ensure that scaling the time elapsed up scales the reward up proportionally (up to a certain cap). + let longer_time = CurrentNetwork::BLOCK_TIME * factor; + let time_factor: f64 = longer_time as f64 / CurrentNetwork::BLOCK_TIME as f64; + let larger_reward = block_reward_v2(CurrentNetwork::STARTING_SUPPLY, longer_time as i64, 0, 0); + let expected_reward = (EXPECTED_STAKING_REWARD as f64 * time_factor) as u64; + match longer_time as i64 > V2_MAX_BLOCK_INTERVAL { + true => assert_eq!(larger_reward, EXPECTED_MAX_STAKING_REWARD), + false => { + assert!((larger_reward as f64 - expected_reward as f64).abs() / expected_reward as f64 <= TOLERANCE) + } + } + } } #[test] fn test_coinbase_reward() { + let mut rng = TestRng::default(); + + // Ensure that a block height of `TestnetV0::CONSENSUS_V2_HEIGHT` uses coinbase reward V2. + let block_timestamp = TestnetV0::GENESIS_TIMESTAMP + .saturating_add(TestnetV0::CONSENSUS_V2_HEIGHT.saturating_mul(TestnetV0::BLOCK_TIME as u32) as i64); + let reward = coinbase_reward::( + TestnetV0::CONSENSUS_V2_HEIGHT, + block_timestamp, + TestnetV0::GENESIS_TIMESTAMP, + TestnetV0::STARTING_SUPPLY, + TestnetV0::ANCHOR_TIME, + TestnetV0::ANCHOR_HEIGHT, + TestnetV0::BLOCK_TIME, + 1, + 0, + 1, + ) + .unwrap(); + let expected_reward = coinbase_reward_v2( + block_timestamp, + TestnetV0::GENESIS_TIMESTAMP, + TestnetV0::STARTING_SUPPLY, + TestnetV0::ANCHOR_TIME, + 1, + 0, + 1, + ) + .unwrap(); + assert_eq!(reward, expected_reward); + + for _ in 0..100 { + // Check that the block reward is correct for the first consensus version. + let consensus_v1_height = rng.gen_range(0..TestnetV0::CONSENSUS_V2_HEIGHT); + let block_timestamp = TestnetV0::GENESIS_TIMESTAMP + .saturating_add(consensus_v1_height.saturating_mul(TestnetV0::BLOCK_TIME as u32) as i64); + let consensus_v1_reward = coinbase_reward::( + consensus_v1_height, + block_timestamp, + TestnetV0::GENESIS_TIMESTAMP, + TestnetV0::STARTING_SUPPLY, + TestnetV0::ANCHOR_TIME, + TestnetV0::ANCHOR_HEIGHT, + TestnetV0::BLOCK_TIME, + 1, + 0, + 1, + ) + .unwrap(); + let expected_reward = coinbase_reward_v1( + consensus_v1_height, + TestnetV0::STARTING_SUPPLY, + TestnetV0::ANCHOR_HEIGHT, + TestnetV0::BLOCK_TIME, + 1, + 0, + 1, + ) + .unwrap(); + assert_eq!(consensus_v1_reward, expected_reward); + + // Check that the block reward is correct for the second consensus version. + let consensus_v2_height = rng.gen_range(TestnetV0::CONSENSUS_V2_HEIGHT..u32::MAX); + let block_timestamp = TestnetV0::GENESIS_TIMESTAMP + .saturating_add(consensus_v2_height.saturating_mul(TestnetV0::BLOCK_TIME as u32) as i64); + let consensus_v2_reward = coinbase_reward::( + consensus_v2_height, + block_timestamp, + TestnetV0::GENESIS_TIMESTAMP, + TestnetV0::STARTING_SUPPLY, + TestnetV0::ANCHOR_TIME, + TestnetV0::ANCHOR_HEIGHT, + TestnetV0::BLOCK_TIME, + 1, + 0, + 1, + ) + .unwrap(); + let expected_reward = coinbase_reward_v2( + block_timestamp, + TestnetV0::GENESIS_TIMESTAMP, + TestnetV0::STARTING_SUPPLY, + TestnetV0::ANCHOR_TIME, + 1, + 0, + 1, + ) + .unwrap(); + assert_eq!(consensus_v2_reward, expected_reward); + } + } + + #[test] + fn test_coinbase_reward_v1() { let coinbase_target: u64 = 10000; let combined_proof_target: u128 = coinbase_target as u128; - let reward = coinbase_reward( + let reward = coinbase_reward_v1( 1, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, @@ -307,7 +1007,7 @@ mod tests { assert_eq!(reward, EXPECTED_COINBASE_REWARD_AT_BLOCK_1); // Halving the combined proof target halves the reward. - let smaller_reward = coinbase_reward( + let smaller_reward = coinbase_reward_v1( 1, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, @@ -320,7 +1020,7 @@ mod tests { assert_eq!(smaller_reward, reward / 2); // Halving the remaining coinbase target halves the reward. - let smaller_reward = coinbase_reward( + let smaller_reward = coinbase_reward_v1( 1, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, @@ -333,7 +1033,7 @@ mod tests { assert_eq!(smaller_reward, reward / 2); // Dramatically increasing the combined proof target greater than the remaining coinbase target will not increase the reward. - let equivalent_reward = coinbase_reward( + let equivalent_reward = coinbase_reward_v1( 1, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, @@ -346,7 +1046,7 @@ mod tests { assert_eq!(reward, equivalent_reward); // Decreasing the combined proof target to 0 will result in a reward of 0. - let zero_reward = coinbase_reward( + let zero_reward = coinbase_reward_v1( 1, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, @@ -359,7 +1059,7 @@ mod tests { assert_eq!(zero_reward, 0); // Increasing the cumulative proof target beyond the coinbase target will result in a reward of 0. - let zero_reward = coinbase_reward( + let zero_reward = coinbase_reward_v1( 1, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, @@ -373,7 +1073,90 @@ mod tests { } #[test] - fn test_coinbase_reward_remaining_target() { + fn test_coinbase_reward_v2() { + let coinbase_target: u64 = 10000; + let combined_proof_target: u128 = coinbase_target as u128; + + let reward = coinbase_reward_v2( + CurrentNetwork::GENESIS_TIMESTAMP + CurrentNetwork::BLOCK_TIME as i64, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + combined_proof_target, + 0, + coinbase_target, + ) + .unwrap(); + assert_eq!(reward, EXPECTED_COINBASE_REWARD_AT_BLOCK_1); + + // Halving the combined proof target halves the reward. + let smaller_reward = coinbase_reward_v2( + CurrentNetwork::GENESIS_TIMESTAMP + CurrentNetwork::BLOCK_TIME as i64, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + combined_proof_target / 2, + 0, + coinbase_target, + ) + .unwrap(); + assert_eq!(smaller_reward, reward / 2); + + // Halving the remaining coinbase target halves the reward. + let smaller_reward = coinbase_reward_v2( + CurrentNetwork::GENESIS_TIMESTAMP + CurrentNetwork::BLOCK_TIME as i64, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + combined_proof_target, + coinbase_target / 2, + coinbase_target, + ) + .unwrap(); + assert_eq!(smaller_reward, reward / 2); + + // Dramatically increasing the combined proof target greater than the remaining coinbase target will not increase the reward. + let equivalent_reward = coinbase_reward_v2( + CurrentNetwork::GENESIS_TIMESTAMP + CurrentNetwork::BLOCK_TIME as i64, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + u128::MAX, + 0, + coinbase_target, + ) + .unwrap(); + assert_eq!(reward, equivalent_reward); + + // Decreasing the combined proof target to 0 will result in a reward of 0. + let zero_reward = coinbase_reward_v2( + CurrentNetwork::GENESIS_TIMESTAMP + CurrentNetwork::BLOCK_TIME as i64, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + 0, + 0, + coinbase_target, + ) + .unwrap(); + assert_eq!(zero_reward, 0); + + // Increasing the cumulative proof target beyond the coinbase target will result in a reward of 0. + let zero_reward = coinbase_reward_v2( + CurrentNetwork::GENESIS_TIMESTAMP + CurrentNetwork::BLOCK_TIME as i64, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + 1, + coinbase_target + 1, + coinbase_target, + ) + .unwrap(); + assert_eq!(zero_reward, 0); + } + + #[test] + fn test_coinbase_reward_v1_remaining_target() { let mut rng = TestRng::default(); fn compute_coinbase_reward( @@ -381,7 +1164,7 @@ mod tests { cumulative_proof_target: u64, coinbase_target: u64, ) -> u64 { - coinbase_reward( + coinbase_reward_v1( 1, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, @@ -431,12 +1214,70 @@ mod tests { } #[test] - fn test_coinbase_reward_up_to_year_10() { + fn test_coinbase_reward_v2_remaining_target() { + let mut rng = TestRng::default(); + + fn compute_coinbase_reward( + combined_proof_target: u64, + cumulative_proof_target: u64, + coinbase_target: u64, + ) -> u64 { + coinbase_reward_v2( + CurrentNetwork::GENESIS_TIMESTAMP + CurrentNetwork::BLOCK_TIME as i64, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + combined_proof_target as u128, + cumulative_proof_target, + coinbase_target, + ) + .unwrap() + } + + // Sample the starting conditions. + let coinbase_target: u64 = rng.gen_range(1_000_000..1_000_000_000_000_000); + let cumulative_proof_target = coinbase_target / 2; + let combined_proof_target = coinbase_target / 4; + let reward = compute_coinbase_reward(combined_proof_target, cumulative_proof_target, coinbase_target); + + for _ in 0..ITERATIONS { + // Check that as long as the sum of the combined proof target and cumulative proof target is less than the coinbase target, + // the reward remains the same. + // Intuition: Staying below the coinbase target preserves the reward for the combined proof target. + let equivalent_reward = compute_coinbase_reward( + combined_proof_target, + rng.gen_range(0..(coinbase_target - combined_proof_target)), + coinbase_target, + ); + assert_eq!(reward, equivalent_reward); + + // Check that increasing the cumulative proof target to devalue the combined proof target will decrease the reward. + // Intuition: Overflowing the coinbase target crowds out the combined proof target, leading to less reward for the combined proof target. + let lower_reward = compute_coinbase_reward( + combined_proof_target, + rng.gen_range((coinbase_target - combined_proof_target + 1)..coinbase_target), + coinbase_target, + ); + assert!(lower_reward < reward); + + // Check that increasing the combined proof target increases the reward. + // Intuition: If a prover contributes more proof target, they should be rewarded more. + let larger_reward = compute_coinbase_reward( + rng.gen_range(combined_proof_target + 1..u64::MAX), + cumulative_proof_target, + coinbase_target, + ); + assert!(reward < larger_reward); + } + } + + #[test] + fn test_coinbase_reward_v1_up_to_year_10() { let block_height_at_year_10 = block_height_at_year(CurrentNetwork::BLOCK_TIME, 10); let mut block_height = 1; - let mut previous_reward = coinbase_reward( + let mut previous_reward = coinbase_reward_v1( block_height, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, @@ -458,7 +1299,7 @@ mod tests { let mut hit_1b = false; while block_height < block_height_at_year_10 { - let reward = coinbase_reward( + let reward = coinbase_reward_v1( block_height, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, @@ -491,17 +1332,81 @@ mod tests { } } - assert_eq!(total_reward, 1_499_999_984_232_003, "Update me if my parameters have changed"); + assert_eq!(total_reward, 1_514_999_979_651_171, "Update me if my parameters have changed"); + } + + #[test] + fn test_coinbase_reward_v2_up_to_year_10() { + let block_height_at_year_10 = timestamp_at_year(CurrentNetwork::GENESIS_TIMESTAMP, 10); + + let mut timestamp = CurrentNetwork::GENESIS_TIMESTAMP; + + let mut previous_reward = coinbase_reward_v2( + CurrentNetwork::GENESIS_TIMESTAMP + CurrentNetwork::BLOCK_TIME as i64, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + 1, + 0, + 1, + ) + .unwrap(); + + timestamp += CurrentNetwork::BLOCK_TIME as i64; + + let mut total_reward = previous_reward; + + let coinbase_target = CurrentNetwork::ANCHOR_HEIGHT as u64; + let mut cumulative_proof_target = 0; + + let mut hit_500m = false; + let mut hit_1b = false; + + while timestamp < block_height_at_year_10 { + let reward = coinbase_reward_v2( + timestamp, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + 1, + cumulative_proof_target, + coinbase_target, + ) + .unwrap(); + assert!(reward <= previous_reward); + + total_reward += reward; + previous_reward = reward; + timestamp += CurrentNetwork::BLOCK_TIME as i64; + + // Update the cumulative proof target. + cumulative_proof_target = match cumulative_proof_target + 1 { + cumulative_proof_target if cumulative_proof_target == coinbase_target => 0, + cumulative_proof_target => cumulative_proof_target, + }; + + if !hit_500m && total_reward > 500_000_000_000_000 { + println!("500M credits block timestamp is {timestamp}"); + assert_eq!(timestamp, 1783331630, "Update me if my parameters have changed"); + hit_500m = true; + } else if !hit_1b && total_reward > 1_000_000_000_000_000 { + println!("1B credits block timestamp is {timestamp}"); + assert_eq!(timestamp, 1858748810, "Update me if my parameters have changed"); + hit_1b = true; + } + } + + assert_eq!(total_reward, 1_515_000_074_780_540, "Update me if my parameters have changed"); } #[test] - fn test_coinbase_reward_after_year_10() { + fn test_coinbase_reward_v1_after_year_10() { let mut rng = TestRng::default(); let block_height_at_year_10 = block_height_at_year(CurrentNetwork::BLOCK_TIME, 10); - // Check that the block at year 10 has a reward of 0. - let reward = coinbase_reward( + // Check that the block at year 10 has a reward of 19. + let reward = coinbase_reward_v1( block_height_at_year_10, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, @@ -511,16 +1416,24 @@ mod tests { 1, ) .unwrap(); - assert_eq!(reward, 0); + assert_eq!(reward, 19_025_874); - // Check that the subsequent blocks have a reward of 0. + // Check that the subsequent blocks have an anchor reward of 19 and reward less than or equal to 19. for _ in 0..ITERATIONS { let block_height: u32 = rng.gen_range(block_height_at_year_10..block_height_at_year_10 * 10); let coinbase_target = rng.gen_range(1_000_000..1_000_000_000_000_000); let cumulative_proof_target = rng.gen_range(0..coinbase_target); let combined_proof_target = rng.gen_range(0..coinbase_target as u128); - let reward = coinbase_reward( + let anchor_reward = anchor_block_reward_at_height( + block_height, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_HEIGHT, + CurrentNetwork::BLOCK_TIME, + ); + assert_eq!(anchor_reward, 19_025_874); + + let reward = coinbase_reward_v1( block_height, CurrentNetwork::STARTING_SUPPLY, CurrentNetwork::ANCHOR_HEIGHT, @@ -530,8 +1443,55 @@ mod tests { coinbase_target, ) .unwrap(); + assert!(reward <= 19_025_874); + } + } + + #[test] + fn test_coinbase_reward_v2_after_year_10() { + let mut rng = TestRng::default(); + + let timestamp_at_year_10 = timestamp_at_year(CurrentNetwork::GENESIS_TIMESTAMP, 10); - assert_eq!(reward, 0); + // Check that the block at year 10 has a reward of 19. + let reward = coinbase_reward_v2( + timestamp_at_year_10, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + 1, + 0, + 1, + ) + .unwrap(); + assert_eq!(reward, 19_025_874); + + // Check that the subsequent blocks have an anchor reward of 19 and reward less than or equal to 19. + for _ in 0..ITERATIONS { + let timestamp: i64 = rng.gen_range(timestamp_at_year_10..timestamp_at_year_10 * 10); + let coinbase_target = rng.gen_range(1_000_000..1_000_000_000_000_000); + let cumulative_proof_target = rng.gen_range(0..coinbase_target); + let combined_proof_target = rng.gen_range(0..coinbase_target as u128); + + let anchor_reward = anchor_block_reward_at_timestamp( + timestamp, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + ); + assert_eq!(anchor_reward, 19_025_874); + + let reward = coinbase_reward_v2( + timestamp, + CurrentNetwork::GENESIS_TIMESTAMP, + CurrentNetwork::STARTING_SUPPLY, + CurrentNetwork::ANCHOR_TIME, + combined_proof_target, + cumulative_proof_target, + coinbase_target, + ) + .unwrap(); + assert!(reward <= 19_025_874); } } @@ -543,7 +1503,11 @@ mod tests { fn test_new_targets(rng: &mut TestRng, minimum_coinbase_target: u64) { let previous_coinbase_target: u64 = rng.gen_range(minimum_coinbase_target..u64::MAX); - let previous_prover_target = proof_target(previous_coinbase_target, CurrentNetwork::GENESIS_PROOF_TARGET); + let previous_prover_target = proof_target( + previous_coinbase_target, + CurrentNetwork::GENESIS_PROOF_TARGET, + CurrentNetwork::MAX_SOLUTIONS_AS_POWER_OF_TWO, + ); let previous_timestamp = rng.gen(); @@ -558,7 +1522,11 @@ mod tests { CurrentNetwork::GENESIS_COINBASE_TARGET, ) .unwrap(); - let new_prover_target = proof_target(new_coinbase_target, CurrentNetwork::GENESIS_PROOF_TARGET); + let new_prover_target = proof_target( + new_coinbase_target, + CurrentNetwork::GENESIS_PROOF_TARGET, + CurrentNetwork::MAX_SOLUTIONS_AS_POWER_OF_TWO, + ); assert_eq!(new_coinbase_target, previous_coinbase_target); assert_eq!(new_prover_target, previous_prover_target); @@ -573,7 +1541,11 @@ mod tests { CurrentNetwork::GENESIS_COINBASE_TARGET, ) .unwrap(); - let new_prover_target = proof_target(new_coinbase_target, CurrentNetwork::GENESIS_PROOF_TARGET); + let new_prover_target = proof_target( + new_coinbase_target, + CurrentNetwork::GENESIS_PROOF_TARGET, + CurrentNetwork::MAX_SOLUTIONS_AS_POWER_OF_TWO, + ); assert!(new_coinbase_target < previous_coinbase_target); assert!(new_prover_target < previous_prover_target); @@ -588,7 +1560,11 @@ mod tests { CurrentNetwork::GENESIS_COINBASE_TARGET, ) .unwrap(); - let new_prover_target = proof_target(new_coinbase_target, CurrentNetwork::GENESIS_PROOF_TARGET); + let new_prover_target = proof_target( + new_coinbase_target, + CurrentNetwork::GENESIS_PROOF_TARGET, + CurrentNetwork::MAX_SOLUTIONS_AS_POWER_OF_TWO, + ); assert!(new_coinbase_target > previous_coinbase_target); assert!(new_prover_target > previous_prover_target); @@ -703,4 +1679,111 @@ mod tests { assert_eq!(EXPECTED_NUM_BLOCKS_TO_DOUBLE, num_blocks); } + + #[test] + fn test_to_next_targets_meets_threshold() { + let mut rng = TestRng::default(); + + let minimum_coinbase_target: u64 = 2u64.pow(10) - 1; + + for _ in 0..ITERATIONS { + // Sample the initial values. + let latest_coinbase_target = rng.gen_range(minimum_coinbase_target..u64::MAX / 2); + let threshold = latest_coinbase_target as u128 / 2; + let last_coinbase_target = rng.gen_range(minimum_coinbase_target..latest_coinbase_target); + let last_coinbase_timestamp = rng.gen_range(0..i64::MAX / 2); + let next_timestamp = last_coinbase_timestamp + 100; + let latest_cumulative_weight = rng.gen_range(0..u128::MAX / 2); + + // Sample a cumulative proof target and combined proof target pair that meets the threshold. + let latest_cumulative_proof_target = rng.gen_range(0..threshold); + let combined_proof_target = + rng.gen_range(threshold.saturating_sub(latest_cumulative_proof_target)..u128::MAX); + + assert!(latest_cumulative_proof_target.saturating_add(combined_proof_target) >= threshold); + + // Calculate the next targets. + let ( + _, + _, + next_cumulative_proof_target, + next_cumulative_weight, + next_last_coinbase_target, + next_last_coinbase_timestamp, + ) = to_next_targets::( + latest_cumulative_proof_target, + combined_proof_target, + latest_coinbase_target, + latest_cumulative_weight, + last_coinbase_target, + last_coinbase_timestamp, + next_timestamp, + ) + .unwrap(); + + // Check that meeting the target threshold does the following: + // 1. Resets the next_cumulative_proof_target. + // 2. Updates the last_coinbase_target. + // 3. Updates the last_coinbase_timestamp. + assert_eq!(next_cumulative_proof_target, 0); + assert_ne!(next_last_coinbase_target, last_coinbase_target); + assert_eq!(next_last_coinbase_timestamp, next_timestamp); + + // Check that the cumulative_weight is updated correctly. + assert_eq!(next_cumulative_weight, latest_cumulative_weight.saturating_add(combined_proof_target)); + } + } + + #[test] + fn test_to_next_targets_does_not_meet_threshold() { + let mut rng = TestRng::default(); + + let minimum_coinbase_target: u64 = 2u64.pow(10) - 1; + + for _ in 0..ITERATIONS { + // Sample the initial values. + let latest_coinbase_target = rng.gen_range(minimum_coinbase_target..u64::MAX / 2); + let threshold = latest_coinbase_target as u128 / 2; + let last_coinbase_target = rng.gen_range(minimum_coinbase_target..latest_coinbase_target); + let last_coinbase_timestamp = rng.gen_range(0..i64::MAX / 2); + let next_timestamp = last_coinbase_timestamp + 100; + let latest_cumulative_weight = rng.gen_range(0..u128::MAX / 2); + + // Sample a cumulative proof target and combined proof target pair that meets the threshold. + let latest_cumulative_proof_target = rng.gen_range(0..threshold); + let combined_proof_target = rng.gen_range(0..threshold.saturating_sub(latest_cumulative_proof_target)); + + assert!(latest_cumulative_proof_target.saturating_add(combined_proof_target) < threshold); + + // Calculate the next targets. + let ( + _, + _, + next_cumulative_proof_target, + next_cumulative_weight, + next_last_coinbase_target, + next_last_coinbase_timestamp, + ) = to_next_targets::( + latest_cumulative_proof_target, + combined_proof_target, + latest_coinbase_target, + latest_cumulative_weight, + last_coinbase_target, + last_coinbase_timestamp, + next_timestamp, + ) + .unwrap(); + + // Check that missing the target threshold does the following: + // 1. Does not reset the next_cumulative_proof_target. + // 2. Does not update the last_coinbase_target. + // 3. Does not update the last_coinbase_timestamp. + assert_eq!(next_cumulative_proof_target, latest_cumulative_proof_target + combined_proof_target); + assert_eq!(next_last_coinbase_target, last_coinbase_target); + assert_eq!(next_last_coinbase_timestamp, last_coinbase_timestamp); + + // Check that the cumulative_weight is updated correctly. + assert_eq!(next_cumulative_weight, latest_cumulative_weight.saturating_add(combined_proof_target)); + } + } } diff --git a/ledger/block/src/lib.rs b/ledger/block/src/lib.rs index fd9dae34ce..2a62ab4d59 100644 --- a/ledger/block/src/lib.rs +++ b/ledger/block/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -29,6 +30,9 @@ pub use ratifications::*; pub mod ratify; pub use ratify::*; +pub mod solutions; +pub use solutions::*; + pub mod transaction; pub use transaction::*; @@ -51,10 +55,11 @@ use console::{ types::{Field, Group, U64}, }; use ledger_authority::Authority; -use ledger_coinbase::{CoinbaseSolution, ProverSolution, PuzzleCommitment}; use ledger_committee::Committee; +use ledger_narwhal_data::Data; use ledger_narwhal_subdag::Subdag; use ledger_narwhal_transmission_id::TransmissionID; +use ledger_puzzle::{PuzzleSolutions, Solution, SolutionID}; #[derive(Clone, PartialEq, Eq)] pub struct Block { @@ -69,7 +74,9 @@ pub struct Block { /// The ratifications in this block. ratifications: Ratifications, /// The solutions in the block. - solutions: Option>, + solutions: Solutions, + /// The aborted solution IDs in this block. + aborted_solution_ids: Vec>, /// The transactions in this block. transactions: Transactions, /// The aborted transaction IDs in this block. @@ -84,7 +91,8 @@ impl Block { previous_hash: N::BlockHash, header: Header, ratifications: Ratifications, - solutions: Option>, + solutions: Solutions, + aborted_solution_ids: Vec>, transactions: Transactions, aborted_transaction_ids: Vec, rng: &mut R, @@ -94,7 +102,16 @@ impl Block { // Construct the beacon authority. let authority = Authority::new_beacon(private_key, block_hash, rng)?; // Construct the block. - Self::from(previous_hash, header, authority, ratifications, solutions, transactions, aborted_transaction_ids) + Self::from( + previous_hash, + header, + authority, + ratifications, + solutions, + aborted_solution_ids, + transactions, + aborted_transaction_ids, + ) } /// Initializes a new quorum block from the given previous block hash, block header, @@ -104,14 +121,24 @@ impl Block { header: Header, subdag: Subdag, ratifications: Ratifications, - solutions: Option>, + solutions: Solutions, + aborted_solution_ids: Vec>, transactions: Transactions, aborted_transaction_ids: Vec, ) -> Result { // Construct the beacon authority. let authority = Authority::new_quorum(subdag); // Construct the block. - Self::from(previous_hash, header, authority, ratifications, solutions, transactions, aborted_transaction_ids) + Self::from( + previous_hash, + header, + authority, + ratifications, + solutions, + aborted_solution_ids, + transactions, + aborted_transaction_ids, + ) } /// Initializes a new block from the given previous block hash, block header, @@ -121,12 +148,18 @@ impl Block { header: Header, authority: Authority, ratifications: Ratifications, - solutions: Option>, + solutions: Solutions, + aborted_solution_ids: Vec>, transactions: Transactions, aborted_transaction_ids: Vec, ) -> Result { - // Ensure the block contains transactions. - ensure!(!transactions.is_empty(), "Cannot create a block with zero transactions"); + // Ensure the number of aborted solutions IDs is within the allowed range. + if aborted_solution_ids.len() > Solutions::::MAX_ABORTED_SOLUTIONS { + bail!( + "Cannot initialize a block with more than {} aborted solutions IDs", + Solutions::::MAX_ABORTED_SOLUTIONS + ); + } // Ensure the number of transactions is within the allowed range. if transactions.len() > Transactions::::MAX_TRANSACTIONS { @@ -157,16 +190,18 @@ impl Block { } Authority::Quorum(subdag) => { // Ensure the transmission IDs from the subdag correspond to the block. - Self::check_subdag_transmissions(subdag, &solutions, &transactions, &aborted_transaction_ids)?; + Self::check_subdag_transmissions( + subdag, + &solutions, + &aborted_solution_ids, + &transactions, + &aborted_transaction_ids, + )?; } } // Ensure that coinbase accumulator matches the solutions. - let solutions_root = match &solutions { - Some(coinbase_solution) => coinbase_solution.to_accumulator_point()?, - None => Field::::zero(), - }; - if header.solutions_root() != solutions_root { + if header.solutions_root() != solutions.to_solutions_root()? { bail!("The solutions root in the block does not correspond to the solutions"); } @@ -187,6 +222,7 @@ impl Block { authority, ratifications, solutions, + aborted_solution_ids, transactions, aborted_transaction_ids, ) @@ -200,7 +236,8 @@ impl Block { header: Header, authority: Authority, ratifications: Ratifications, - solutions: Option>, + solutions: Solutions, + aborted_solution_ids: Vec>, transactions: Transactions, aborted_transaction_ids: Vec, ) -> Result { @@ -210,9 +247,10 @@ impl Block { previous_hash, header, authority, - transactions, ratifications, solutions, + aborted_solution_ids, + transactions, aborted_transaction_ids, }) } @@ -240,8 +278,13 @@ impl Block { } /// Returns the solutions in the block. - pub const fn solutions(&self) -> Option<&CoinbaseSolution> { - self.solutions.as_ref() + pub const fn solutions(&self) -> &Solutions { + &self.solutions + } + + /// Returns the aborted solution IDs in this block. + pub const fn aborted_solution_ids(&self) -> &Vec> { + &self.aborted_solution_ids } /// Returns the transactions in this block. @@ -366,8 +409,8 @@ impl Block { impl Block { /// Returns the solution with the given solution ID, if it exists. - pub fn get_solution(&self, puzzle_commitment: &PuzzleCommitment) -> Option<&ProverSolution> { - self.solutions.as_ref().and_then(|solution| solution.get_solution(puzzle_commitment)) + pub fn get_solution(&self, solution_id: &SolutionID) -> Option<&Solution> { + self.solutions.as_ref().and_then(|solution| solution.get_solution(solution_id)) } /// Returns the transaction with the given transaction ID, if it exists. @@ -419,9 +462,9 @@ impl Block { } impl Block { - /// Returns the puzzle commitments in this block. - pub fn puzzle_commitments(&self) -> Option>> { - self.solutions.as_ref().map(|solution| solution.puzzle_commitments()) + /// Returns the solution IDs in this block. + pub fn solution_ids(&self) -> Option>> { + self.solutions.as_ref().map(|solution| solution.solution_ids()) } /// Returns an iterator over the transaction IDs, for all transactions in `self`. @@ -562,12 +605,12 @@ pub mod test_helpers { use super::*; use console::account::{Address, PrivateKey}; use ledger_query::Query; - use ledger_store::{helpers::memory::BlockMemory, BlockStore}; + use ledger_store::{BlockStore, helpers::memory::BlockMemory}; use synthesizer_process::Process; use once_cell::sync::OnceCell; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; type CurrentAleo = circuit::network::AleoV0; /// Samples a random genesis block. @@ -647,20 +690,57 @@ pub mod test_helpers { let previous_hash = ::BlockHash::default(); // Construct the block. - let block = - Block::new_beacon(&private_key, previous_hash, header, ratifications, None, transactions, vec![], rng) - .unwrap(); + let block = Block::new_beacon( + &private_key, + previous_hash, + header, + ratifications, + None.into(), + vec![], + transactions, + vec![], + rng, + ) + .unwrap(); assert!(block.header().is_genesis(), "Failed to initialize a genesis block"); // Return the block, transaction, and private key. (block, transaction, private_key) } + + pub(crate) fn sample_metadata() -> Metadata { + let network = CurrentNetwork::ID; + let round = u64::MAX; + let height = u32::MAX; + let cumulative_weight = u128::MAX - 1; + let cumulative_proof_target = u128::MAX - 1; + let coinbase_target = u64::MAX; + let proof_target = u64::MAX - 1; + let last_coinbase_target = u64::MAX; + let timestamp = i64::MAX - 1; + let last_coinbase_timestamp = timestamp - 1; + Metadata::new( + network, + round, + height, + cumulative_weight, + cumulative_proof_target, + coinbase_target, + proof_target, + last_coinbase_target, + last_coinbase_timestamp, + timestamp, + ) + .unwrap() + } } #[cfg(test)] mod tests { use super::*; + use console::network::MainnetV0; use indexmap::IndexMap; + type CurrentNetwork = MainnetV0; #[test] fn test_find_transaction_for_transition_id() { @@ -798,4 +878,12 @@ mod tests { assert_eq!(transaction.find_record(commitment), None); } } + + #[test] + fn test_serde_metadata() { + let metadata = crate::test_helpers::sample_metadata(); + let json_metadata = serde_json::to_string(&metadata).unwrap(); + let deserialized_metadata: Metadata = serde_json::from_str(&json_metadata).unwrap(); + assert_eq!(metadata, deserialized_metadata); + } } diff --git a/ledger/block/src/ratifications/bytes.rs b/ledger/block/src/ratifications/bytes.rs index aa8d6f4a9a..2e121f6466 100644 --- a/ledger/block/src/ratifications/bytes.rs +++ b/ledger/block/src/ratifications/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/ratifications/merkle.rs b/ledger/block/src/ratifications/merkle.rs index 806e4eb7ad..90a28215aa 100644 --- a/ledger/block/src/ratifications/merkle.rs +++ b/ledger/block/src/ratifications/merkle.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -54,9 +55,9 @@ impl Ratifications { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_ratifications_depth() { diff --git a/ledger/block/src/ratifications/mod.rs b/ledger/block/src/ratifications/mod.rs index bb11fe0951..4c6a16138c 100644 --- a/ledger/block/src/ratifications/mod.rs +++ b/ledger/block/src/ratifications/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,7 +20,7 @@ mod string; use crate::Ratify; use console::{ network::prelude::*, - program::{RatificationsPath, RatificationsTree, RATIFICATIONS_DEPTH}, + program::{RATIFICATIONS_DEPTH, RatificationsPath, RatificationsTree}, types::Field, }; @@ -137,7 +138,7 @@ impl Ratifications { pub mod test_helpers { use super::*; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; /// Samples a block ratifications. pub(crate) fn sample_block_ratifications(rng: &mut TestRng) -> Ratifications { diff --git a/ledger/block/src/ratifications/serialize.rs b/ledger/block/src/ratifications/serialize.rs index df252a8bbd..7bd964a49b 100644 --- a/ledger/block/src/ratifications/serialize.rs +++ b/ledger/block/src/ratifications/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -66,9 +67,9 @@ impl<'de, N: Network> Deserialize<'de> for Ratifications { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u32 = 100; diff --git a/ledger/block/src/ratifications/string.rs b/ledger/block/src/ratifications/string.rs index 9a31010535..c0446de485 100644 --- a/ledger/block/src/ratifications/string.rs +++ b/ledger/block/src/ratifications/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/ratify/bytes.rs b/ledger/block/src/ratify/bytes.rs index bab8503907..cd06493881 100644 --- a/ledger/block/src/ratify/bytes.rs +++ b/ledger/block/src/ratify/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -41,8 +42,24 @@ impl FromBytes for Ratify { // Insert the public balance. public_balances.insert(address, amount); } + // Read the number of bonded balances. + let num_bonded_balances: u16 = FromBytes::read_le(&mut reader)?; + // Read the bonded balances. + let mut bonded_balances = BondedBalances::with_capacity(num_bonded_balances as usize); + for _ in 0..num_bonded_balances { + // Read the address. + let address: Address = FromBytes::read_le(&mut reader)?; + // Read the validator address. + let validator_address: Address = FromBytes::read_le(&mut reader)?; + // Read the withdrawal address. + let withdrawal_address: Address = FromBytes::read_le(&mut reader)?; + // Read the amount. + let amount: u64 = FromBytes::read_le(&mut reader)?; + // Insert the bonded balance. + bonded_balances.insert(address, (validator_address, withdrawal_address, amount)); + } // Return the ratify object. - Self::Genesis(committee, public_balances) + Self::Genesis(Box::new(committee), Box::new(public_balances), Box::new(bonded_balances)) } 1 => { // Read the amount. @@ -69,12 +86,19 @@ impl ToBytes for Ratify { 1u8.write_le(&mut writer)?; match self { - Self::Genesis(committee, public_balances) => { + Self::Genesis(committee, public_balances, bonded_balances) => { (0 as Variant).write_le(&mut writer)?; committee.write_le(&mut writer)?; u16::try_from(public_balances.len()).map_err(|e| error(e.to_string()))?.write_le(&mut writer)?; - for (address, amount) in public_balances { + for (address, amount) in public_balances.iter() { + address.write_le(&mut writer)?; + amount.write_le(&mut writer)?; + } + u16::try_from(bonded_balances.len()).map_err(|e| error(e.to_string()))?.write_le(&mut writer)?; + for (address, (validator_address, withdrawal_address, amount)) in bonded_balances.iter() { address.write_le(&mut writer)?; + validator_address.write_le(&mut writer)?; + withdrawal_address.write_le(&mut writer)?; amount.write_le(&mut writer)?; } Ok(()) diff --git a/ledger/block/src/ratify/mod.rs b/ledger/block/src/ratify/mod.rs index c9a468c229..a963580598 100644 --- a/ledger/block/src/ratify/mod.rs +++ b/ledger/block/src/ratify/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,11 +25,15 @@ use indexmap::IndexMap; type Variant = u8; /// A helper type to represent the public balances. type PublicBalances = IndexMap, u64>; +/// A helper type to represent the bonded balances, as a +/// mapping of `staker_address` to `(validator_address, withdrawal_address, amount)`. +type BondedBalances = IndexMap, (Address, Address, u64)>; +// Note: The size of the `Ratify` object is 32 bytes. #[derive(Clone, PartialEq, Eq)] pub enum Ratify { /// The genesis. - Genesis(Committee, PublicBalances), + Genesis(Box>, Box>, Box>), /// The block reward. BlockReward(u64), /// The puzzle reward. @@ -45,9 +50,9 @@ impl Ratify { #[cfg(test)] pub(crate) mod test_helpers { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; pub(crate) fn sample_ratifications(rng: &mut TestRng) -> Vec> { let committee = ledger_committee::test_helpers::sample_committee(rng); @@ -55,11 +60,26 @@ pub(crate) mod test_helpers { for (address, _) in committee.members().iter() { public_balances.insert(*address, rng.gen()); } + let bonded_balances = committee + .members() + .iter() + .map(|(address, (amount, _, _))| (*address, (*address, *address, *amount))) + .collect(); vec![ - Ratify::Genesis(committee, public_balances), + Ratify::Genesis(Box::new(committee), Box::new(public_balances), Box::new(bonded_balances)), Ratify::BlockReward(rng.gen()), Ratify::PuzzleReward(rng.gen()), ] } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn check_ratify_size() { + assert_eq!(std::mem::size_of::>(), 32); + } +} diff --git a/ledger/block/src/ratify/serialize.rs b/ledger/block/src/ratify/serialize.rs index a6c4f9a245..0bbe4b5e52 100644 --- a/ledger/block/src/ratify/serialize.rs +++ b/ledger/block/src/ratify/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,11 +20,12 @@ impl Serialize for Ratify { fn serialize(&self, serializer: S) -> Result { match serializer.is_human_readable() { true => match self { - Self::Genesis(committee, public_balances) => { - let mut input = serializer.serialize_struct("Ratify", 3)?; + Self::Genesis(committee, public_balances, bonded_balances) => { + let mut input = serializer.serialize_struct("Ratify", 4)?; input.serialize_field("type", "genesis")?; input.serialize_field("committee", &committee)?; input.serialize_field("public_balances", &public_balances)?; + input.serialize_field("bonded_balances", &bonded_balances)?; input.end() } Self::BlockReward(amount) => { @@ -60,8 +62,11 @@ impl<'de, N: Network> Deserialize<'de> for Ratify { // Retrieve the public balances. let public_balances: PublicBalances = DeserializeExt::take_from_value::(&mut object, "public_balances")?; + // Retrieve the bonded balances. + let bonded_balances: BondedBalances = + DeserializeExt::take_from_value::(&mut object, "bonded_balances")?; // Construct the ratify object. - Ratify::Genesis(committee, public_balances) + Ratify::Genesis(Box::new(committee), Box::new(public_balances), Box::new(bonded_balances)) } Some("block_reward") => { // Retrieve the amount. diff --git a/ledger/block/src/ratify/string.rs b/ledger/block/src/ratify/string.rs index 6872ff77be..fd135dd476 100644 --- a/ledger/block/src/ratify/string.rs +++ b/ledger/block/src/ratify/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/serialize.rs b/ledger/block/src/serialize.rs index 24edfa8687..73fd9d3951 100644 --- a/ledger/block/src/serialize.rs +++ b/ledger/block/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,17 +20,14 @@ impl Serialize for Block { fn serialize(&self, serializer: S) -> Result { match serializer.is_human_readable() { true => { - let mut block = serializer.serialize_struct("Block", 7 + self.solutions.is_some() as usize)?; + let mut block = serializer.serialize_struct("Block", 9)?; block.serialize_field("block_hash", &self.block_hash)?; block.serialize_field("previous_hash", &self.previous_hash)?; block.serialize_field("header", &self.header)?; block.serialize_field("authority", &self.authority)?; block.serialize_field("ratifications", &self.ratifications)?; - - if let Some(solutions) = &self.solutions { - block.serialize_field("solutions", solutions)?; - } - + block.serialize_field("solutions", &self.solutions)?; + block.serialize_field("aborted_solution_ids", &self.aborted_solution_ids)?; block.serialize_field("transactions", &self.transactions)?; block.serialize_field("aborted_transaction_ids", &self.aborted_transaction_ids)?; block.end() @@ -47,16 +45,14 @@ impl<'de, N: Network> Deserialize<'de> for Block { let mut block = serde_json::Value::deserialize(deserializer)?; let block_hash: N::BlockHash = DeserializeExt::take_from_value::(&mut block, "block_hash")?; - // Retrieve the solutions. - let solutions = block.get_mut("solutions").unwrap_or(&mut serde_json::Value::Null).take(); - // Recover the block. let block = Self::from( DeserializeExt::take_from_value::(&mut block, "previous_hash")?, DeserializeExt::take_from_value::(&mut block, "header")?, DeserializeExt::take_from_value::(&mut block, "authority")?, DeserializeExt::take_from_value::(&mut block, "ratifications")?, - serde_json::from_value(solutions).map_err(de::Error::custom)?, + DeserializeExt::take_from_value::(&mut block, "solutions")?, + DeserializeExt::take_from_value::(&mut block, "aborted_solution_ids")?, DeserializeExt::take_from_value::(&mut block, "transactions")?, DeserializeExt::take_from_value::(&mut block, "aborted_transaction_ids")?, ) @@ -65,7 +61,7 @@ impl<'de, N: Network> Deserialize<'de> for Block { // Ensure the block hash matches. match block_hash == block.hash() { true => Ok(block), - false => Err(error("Mismatching block hash, possible data corruption")).map_err(de::Error::custom), + false => Err(de::Error::custom(error("Mismatching block hash, possible data corruption"))), } } false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "block"), @@ -76,9 +72,9 @@ impl<'de, N: Network> Deserialize<'de> for Block { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_serde_json() -> Result<()> { diff --git a/ledger/block/src/solutions/bytes.rs b/ledger/block/src/solutions/bytes.rs new file mode 100644 index 0000000000..bd1cdcdb14 --- /dev/null +++ b/ledger/block/src/solutions/bytes.rs @@ -0,0 +1,85 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl FromBytes for Solutions { + /// Reads the solutions from the buffer. + fn read_le(mut reader: R) -> IoResult { + // Read the version. + let version: u8 = FromBytes::read_le(&mut reader)?; + // Ensure the version is valid. + if version != 1 { + return Err(error(format!("Invalid solutions version ({version})"))); + } + + // Read the variant. + let variant: u8 = FromBytes::read_le(&mut reader)?; + // Parse the variant. + match variant { + 0 => { + // Return the solutions. + Ok(Self { solutions: None }) + } + 1 => { + // Read the solutions. + let solutions: PuzzleSolutions = FromBytes::read_le(&mut reader)?; + // Return the solutions. + Self::new(solutions).map_err(error) + } + _ => Err(error(format!("Invalid solutions variant ({variant})"))), + } + } +} + +impl ToBytes for Solutions { + /// Writes the solutions to the buffer. + fn write_le(&self, mut writer: W) -> IoResult<()> { + // Write the version. + 1u8.write_le(&mut writer)?; + + match &self.solutions { + None => { + // Write the variant. + 0u8.write_le(&mut writer)?; + } + Some(solutions) => { + // Write the variant. + 1u8.write_le(&mut writer)?; + // Write the solutions. + solutions.write_le(&mut writer)?; + } + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_bytes() -> Result<()> { + let mut rng = TestRng::default(); + + // Sample random solutions. + let expected = crate::solutions::serialize::tests::sample_solutions(&mut rng); + + // Check the byte representation. + let expected_bytes = expected.to_bytes_le()?; + assert_eq!(expected, Solutions::read_le(&expected_bytes[..])?); + Ok(()) + } +} diff --git a/ledger/block/src/solutions/merkle.rs b/ledger/block/src/solutions/merkle.rs new file mode 100644 index 0000000000..bc445e6517 --- /dev/null +++ b/ledger/block/src/solutions/merkle.rs @@ -0,0 +1,26 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl Solutions { + /// Returns the solutions root. + pub fn to_solutions_root(&self) -> Result> { + match &self.solutions { + Some(solutions) => solutions.to_accumulator_point(), + None => Ok(Field::::zero()), + } + } +} diff --git a/ledger/block/src/solutions/mod.rs b/ledger/block/src/solutions/mod.rs new file mode 100644 index 0000000000..cdd2c1a93e --- /dev/null +++ b/ledger/block/src/solutions/mod.rs @@ -0,0 +1,85 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +mod bytes; +mod merkle; +mod serialize; +mod string; + +use console::{network::prelude::*, types::Field}; +use ledger_committee::Committee; +use ledger_narwhal_batch_header::BatchHeader; +use ledger_puzzle::{PuzzleSolutions, SolutionID}; + +#[derive(Clone, Eq, PartialEq)] +pub struct Solutions { + /// The prover solutions for the puzzle. + solutions: Option>, +} + +impl Solutions { + /// The maximum number of aborted solutions allowed in a block. + pub const MAX_ABORTED_SOLUTIONS: usize = BatchHeader::::MAX_TRANSMISSIONS_PER_BATCH + * BatchHeader::::MAX_GC_ROUNDS + * Committee::::MAX_COMMITTEE_SIZE as usize; +} + +impl From>> for Solutions { + /// Initializes a new instance of the solutions. + fn from(solutions: Option>) -> Self { + // Return the solutions. + Self { solutions } + } +} + +impl Solutions { + /// Initializes a new instance of the solutions. + pub fn new(solutions: PuzzleSolutions) -> Result { + // Return the solutions. + Ok(Self { solutions: Some(solutions) }) + } + + /// Returns `true` if the solutions are empty. + pub fn is_empty(&self) -> bool { + self.solutions.is_none() + } + + /// Returns the number of solutions. + pub fn len(&self) -> usize { + match &self.solutions { + Some(solutions) => solutions.len(), + None => 0, + } + } +} + +impl Solutions { + /// Returns an iterator over the solution IDs. + pub fn solution_ids<'a>(&'a self) -> Box> + 'a> { + match &self.solutions { + Some(solutions) => Box::new(solutions.keys()), + None => Box::new(std::iter::empty::<&SolutionID>()), + } + } +} + +impl Deref for Solutions { + type Target = Option>; + + /// Returns the solutions. + fn deref(&self) -> &Self::Target { + &self.solutions + } +} diff --git a/ledger/block/src/solutions/serialize.rs b/ledger/block/src/solutions/serialize.rs new file mode 100644 index 0000000000..456057e452 --- /dev/null +++ b/ledger/block/src/solutions/serialize.rs @@ -0,0 +1,120 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl Serialize for Solutions { + /// Serializes the solutions to a JSON-string or buffer. + fn serialize(&self, serializer: S) -> Result { + match serializer.is_human_readable() { + true => { + let mut solutions = serializer.serialize_struct("Solutions", 1 + self.solutions.is_some() as usize)?; + solutions.serialize_field("version", &1u8)?; + if let Some(s) = &self.solutions { + solutions.serialize_field("solutions", s)?; + } + solutions.end() + } + false => ToBytesSerializer::serialize_with_size_encoding(self, serializer), + } + } +} + +impl<'de, N: Network> Deserialize<'de> for Solutions { + /// Deserializes the solutions from a JSON-string or buffer. + fn deserialize>(deserializer: D) -> Result { + match deserializer.is_human_readable() { + true => { + // Deserialize the solutions into a JSON value. + let mut solutions = serde_json::Value::deserialize(deserializer)?; + + // Retrieve the version. + let version: u8 = DeserializeExt::take_from_value::(&mut solutions, "version")?; + // Ensure the version is valid. + if version != 1 { + return Err(de::Error::custom(format!("Invalid solutions version ({version})"))); + } + + // Retrieve the solutions, if it exists. + Ok(Self { + solutions: serde_json::from_value( + solutions.get_mut("solutions").unwrap_or(&mut serde_json::Value::Null).take(), + ) + .map_err(de::Error::custom)?, + }) + } + false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "solutions"), + } + } +} + +#[cfg(test)] +pub(super) mod tests { + use super::*; + use console::account::{Address, PrivateKey}; + use ledger_puzzle::{PartialSolution, Solution}; + + type CurrentNetwork = console::network::MainnetV0; + + pub(crate) fn sample_solutions(rng: &mut TestRng) -> Solutions { + // Sample a new solutions. + let mut solutions = vec![]; + for _ in 0..rng.gen_range(1..=CurrentNetwork::MAX_SOLUTIONS) { + let private_key = PrivateKey::::new(rng).unwrap(); + let address = Address::try_from(private_key).unwrap(); + let partial_solution = PartialSolution::new(rng.gen(), address, u64::rand(rng)).unwrap(); + solutions.push(Solution::new(partial_solution, u64::rand(rng))); + } + Solutions::new(PuzzleSolutions::new(solutions).unwrap()).unwrap() + } + + #[test] + fn test_serde_json() -> Result<()> { + let rng = &mut TestRng::default(); + + // Sample a new solutions. + let expected = sample_solutions(rng); + + // Serialize + let expected_string = &expected.to_string(); + let candidate_string = serde_json::to_string(&expected)?; + assert_eq!(expected, serde_json::from_str(&candidate_string)?); + + // Deserialize + assert_eq!(expected, Solutions::from_str(expected_string)?); + assert_eq!(expected, serde_json::from_str(&candidate_string)?); + + Ok(()) + } + + #[test] + fn test_bincode() -> Result<()> { + let rng = &mut TestRng::default(); + + // Sample a new solutions. + let expected = sample_solutions(rng); + + // Serialize + let expected_bytes = expected.to_bytes_le()?; + let expected_bytes_with_size_encoding = bincode::serialize(&expected)?; + assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]); + + // Deserialize + assert_eq!(expected, Solutions::read_le(&expected_bytes[..])?); + assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..])?); + + Ok(()) + } +} diff --git a/ledger/coinbase/src/helpers/coinbase_solution/string.rs b/ledger/block/src/solutions/string.rs similarity index 79% rename from ledger/coinbase/src/helpers/coinbase_solution/string.rs rename to ledger/block/src/solutions/string.rs index cf44a84a39..54c23fe77e 100644 --- a/ledger/coinbase/src/helpers/coinbase_solution/string.rs +++ b/ledger/block/src/solutions/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use super::*; -impl FromStr for CoinbaseSolution { +impl FromStr for Solutions { type Err = Error; /// Initializes the solutions from a JSON-string. @@ -23,14 +24,14 @@ impl FromStr for CoinbaseSolution { } } -impl Debug for CoinbaseSolution { +impl Debug for Solutions { /// Prints the solutions as a JSON-string. fn fmt(&self, f: &mut Formatter) -> fmt::Result { Display::fmt(self, f) } } -impl Display for CoinbaseSolution { +impl Display for Solutions { /// Displays the solutions as a JSON-string. fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{}", serde_json::to_string(self).map_err::(ser::Error::custom)?) @@ -46,11 +47,11 @@ mod tests { let mut rng = TestRng::default(); // Sample random solutions. - let expected = crate::helpers::coinbase_solution::serialize::tests::sample_solutions(&mut rng); + let expected = crate::solutions::serialize::tests::sample_solutions(&mut rng); // Check the string representation. let candidate = format!("{expected}"); - assert_eq!(expected, CoinbaseSolution::from_str(&candidate)?); + assert_eq!(expected, Solutions::from_str(&candidate)?); Ok(()) } diff --git a/ledger/block/src/string.rs b/ledger/block/src/string.rs index 53b3fe8d66..5eacc8db1f 100644 --- a/ledger/block/src/string.rs +++ b/ledger/block/src/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transaction/bytes.rs b/ledger/block/src/transaction/bytes.rs index 299c27be99..18cdbad312 100644 --- a/ledger/block/src/transaction/bytes.rs +++ b/ledger/block/src/transaction/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transaction/deployment/bytes.rs b/ledger/block/src/transaction/deployment/bytes.rs index e8e97757a6..f0f2700a4e 100644 --- a/ledger/block/src/transaction/deployment/bytes.rs +++ b/ledger/block/src/transaction/deployment/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transaction/deployment/mod.rs b/ledger/block/src/transaction/deployment/mod.rs index 01d4cac081..42c6182f6f 100644 --- a/ledger/block/src/transaction/deployment/mod.rs +++ b/ledger/block/src/transaction/deployment/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -124,6 +125,40 @@ impl Deployment { &self.verifying_keys } + /// Returns the sum of the variable counts for all functions in this deployment. + pub fn num_combined_variables(&self) -> Result { + // Initialize the accumulator. + let mut num_combined_variables = 0u64; + // Iterate over the functions. + for (_, (vk, _)) in &self.verifying_keys { + // Add the number of variables. + // Note: This method must be *checked* because the claimed variable count + // is from the user, not the synthesizer. + num_combined_variables = num_combined_variables + .checked_add(vk.num_variables()) + .ok_or_else(|| anyhow!("Overflow when counting variables for '{}'", self.program_id()))?; + } + // Return the number of combined variables. + Ok(num_combined_variables) + } + + /// Returns the sum of the constraint counts for all functions in this deployment. + pub fn num_combined_constraints(&self) -> Result { + // Initialize the accumulator. + let mut num_combined_constraints = 0u64; + // Iterate over the functions. + for (_, (vk, _)) in &self.verifying_keys { + // Add the number of constraints. + // Note: This method must be *checked* because the claimed constraint count + // is from the user, not the synthesizer. + num_combined_constraints = num_combined_constraints + .checked_add(vk.circuit_info.num_constraints as u64) + .ok_or_else(|| anyhow!("Overflow when counting constraints for '{}'", self.program_id()))?; + } + // Return the number of combined constraints. + Ok(num_combined_constraints) + } + /// Returns the deployment ID. pub fn to_deployment_id(&self) -> Result> { Ok(*Transaction::deployment_tree(self, None)?.root()) @@ -133,12 +168,12 @@ impl Deployment { #[cfg(test)] pub mod test_helpers { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; use synthesizer_process::Process; use once_cell::sync::OnceCell; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; type CurrentAleo = circuit::network::AleoV0; pub(crate) fn sample_deployment(rng: &mut TestRng) -> Deployment { diff --git a/ledger/block/src/transaction/deployment/serialize.rs b/ledger/block/src/transaction/deployment/serialize.rs index 88af802fc9..02480533da 100644 --- a/ledger/block/src/transaction/deployment/serialize.rs +++ b/ledger/block/src/transaction/deployment/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transaction/deployment/string.rs b/ledger/block/src/transaction/deployment/string.rs index dbf9cdda56..9cade1f6b0 100644 --- a/ledger/block/src/transaction/deployment/string.rs +++ b/ledger/block/src/transaction/deployment/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transaction/execution/bytes.rs b/ledger/block/src/transaction/execution/bytes.rs index c10a8c8fda..26269d68cc 100644 --- a/ledger/block/src/transaction/execution/bytes.rs +++ b/ledger/block/src/transaction/execution/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transaction/execution/mod.rs b/ledger/block/src/transaction/execution/mod.rs index cfcbb26c51..36139105c5 100644 --- a/ledger/block/src/transaction/execution/mod.rs +++ b/ledger/block/src/transaction/execution/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -147,7 +148,7 @@ impl Execution { pub mod test_helpers { use super::*; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; /// Samples a random execution. pub(crate) fn sample_execution(rng: &mut TestRng) -> Execution { diff --git a/ledger/block/src/transaction/execution/serialize.rs b/ledger/block/src/transaction/execution/serialize.rs index b432dd8e72..467dcb6f33 100644 --- a/ledger/block/src/transaction/execution/serialize.rs +++ b/ledger/block/src/transaction/execution/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transaction/execution/string.rs b/ledger/block/src/transaction/execution/string.rs index 08dfd0524b..ae47ab1dbd 100644 --- a/ledger/block/src/transaction/execution/string.rs +++ b/ledger/block/src/transaction/execution/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transaction/fee/bytes.rs b/ledger/block/src/transaction/fee/bytes.rs index 1f156f622f..6a8d391f4a 100644 --- a/ledger/block/src/transaction/fee/bytes.rs +++ b/ledger/block/src/transaction/fee/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transaction/fee/mod.rs b/ledger/block/src/transaction/fee/mod.rs index 233704fca4..eaa2a07f8a 100644 --- a/ledger/block/src/transaction/fee/mod.rs +++ b/ledger/block/src/transaction/fee/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -78,7 +79,7 @@ impl Fee { pub fn payer(&self) -> Option> { // Retrieve the payer. match self.transition.outputs().last() { - Some(Output::Future(_, Some(future))) => match future.arguments().get(0) { + Some(Output::Future(_, Some(future))) => match future.arguments().first() { Some(Argument::Plaintext(Plaintext::Literal(Literal::Address(address), _))) => Some(*address), _ => None, }, @@ -202,12 +203,12 @@ pub mod test_helpers { use super::*; use console::types::Field; use ledger_query::Query; - use ledger_store::{helpers::memory::BlockMemory, BlockStore}; + use ledger_store::{BlockStore, helpers::memory::BlockMemory}; use synthesizer_process::Process; use once_cell::sync::OnceCell; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; type CurrentAleo = circuit::network::AleoV0; /// Samples a random hardcoded private fee. diff --git a/ledger/block/src/transaction/fee/serialize.rs b/ledger/block/src/transaction/fee/serialize.rs index b73ec5e037..8d8c2a9b6f 100644 --- a/ledger/block/src/transaction/fee/serialize.rs +++ b/ledger/block/src/transaction/fee/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transaction/fee/string.rs b/ledger/block/src/transaction/fee/string.rs index 3b6ea42a0c..12f9449be1 100644 --- a/ledger/block/src/transaction/fee/string.rs +++ b/ledger/block/src/transaction/fee/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transaction/merkle.rs b/ledger/block/src/transaction/merkle.rs index f84ea87ca7..d6e5d4fa56 100644 --- a/ledger/block/src/transaction/merkle.rs +++ b/ledger/block/src/transaction/merkle.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,7 +17,7 @@ use super::*; impl Transaction { /// The maximum number of transitions allowed in a transaction. - const MAX_TRANSITIONS: usize = usize::pow(2, TRANSACTION_DEPTH as u32); + pub const MAX_TRANSITIONS: usize = usize::pow(2, TRANSACTION_DEPTH as u32); /// Returns the transaction root, by computing the root for a Merkle tree of the transition IDs. pub fn to_root(&self) -> Result> { diff --git a/ledger/block/src/transaction/mod.rs b/ledger/block/src/transaction/mod.rs index fe1ace4c76..61e49e6afe 100644 --- a/ledger/block/src/transaction/mod.rs +++ b/ledger/block/src/transaction/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -29,7 +30,7 @@ mod string; use crate::Transition; use console::{ network::prelude::*, - program::{Ciphertext, ProgramOwner, Record, TransactionLeaf, TransactionPath, TransactionTree, TRANSACTION_DEPTH}, + program::{Ciphertext, ProgramOwner, Record, TRANSACTION_DEPTH, TransactionLeaf, TransactionPath, TransactionTree}, types::{Field, Group, U64}, }; @@ -407,9 +408,9 @@ impl Transaction { #[cfg(test)] pub mod test_helpers { use super::*; - use console::{account::PrivateKey, network::Testnet3, program::ProgramOwner}; + use console::{account::PrivateKey, network::MainnetV0, program::ProgramOwner}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Samples a random deployment transaction with a private or public fee. pub fn sample_deployment_transaction(is_fee_private: bool, rng: &mut TestRng) -> Transaction { diff --git a/ledger/block/src/transaction/serialize.rs b/ledger/block/src/transaction/serialize.rs index ec6aae1448..78d763dd0d 100644 --- a/ledger/block/src/transaction/serialize.rs +++ b/ledger/block/src/transaction/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -100,9 +101,7 @@ impl<'de, N: Network> Deserialize<'de> for Transaction { // Ensure the transaction ID matches. match id == transaction.id() { true => Ok(transaction), - false => { - Err(error("Mismatching transaction ID, possible data corruption")).map_err(de::Error::custom) - } + false => Err(de::Error::custom(error("Mismatching transaction ID, possible data corruption"))), } } false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "transaction"), diff --git a/ledger/block/src/transaction/string.rs b/ledger/block/src/transaction/string.rs index 82336d1385..f68837f03e 100644 --- a/ledger/block/src/transaction/string.rs +++ b/ledger/block/src/transaction/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transactions/bytes.rs b/ledger/block/src/transactions/bytes.rs index d76e8625ba..9e9a41900c 100644 --- a/ledger/block/src/transactions/bytes.rs +++ b/ledger/block/src/transactions/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transactions/confirmed/bytes.rs b/ledger/block/src/transactions/confirmed/bytes.rs index 16f929215c..81813e292a 100644 --- a/ledger/block/src/transactions/confirmed/bytes.rs +++ b/ledger/block/src/transactions/confirmed/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transactions/confirmed/mod.rs b/ledger/block/src/transactions/confirmed/mod.rs index 9d16b7915d..9593e2ace5 100644 --- a/ledger/block/src/transactions/confirmed/mod.rs +++ b/ledger/block/src/transactions/confirmed/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,8 +17,8 @@ mod bytes; mod serialize; mod string; -use crate::{rejected::Rejected, Transaction}; -use console::{network::prelude::*, types::Field}; +use crate::{Transaction, rejected::Rejected}; +use console::{network::prelude::*, program::FINALIZE_ID_DEPTH, types::Field}; use synthesizer_program::FinalizeOperation; pub type NumFinalizeSize = u16; @@ -261,6 +262,16 @@ impl ConfirmedTransaction { } } + /// Returns the finalize ID, by computing the root of a (small) Merkle tree comprised of + /// the ordered finalize operations for the transaction. + pub fn to_finalize_id(&self) -> Result> { + // Prepare the leaves. + let leaves = self.finalize_operations().iter().map(ToBits::to_bits_le).collect::>(); + // Compute the finalize ID. + // Note: This call will ensure the number of finalize operations is within the size of the Merkle tree. + Ok(*N::merkle_tree_bhp::(&leaves)?.root()) + } + /// Returns the rejected ID, if the confirmed transaction is rejected. pub fn to_rejected_id(&self) -> Result>> { match self { @@ -328,9 +339,9 @@ impl Deref for ConfirmedTransaction { #[cfg(test)] pub mod test_helpers { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Samples an accepted deploy transaction at the given index. pub(crate) fn sample_accepted_deploy( @@ -346,12 +357,7 @@ pub mod test_helpers { true => vec![FinalizeOperation::InitializeMapping(Uniform::rand(rng))], false => vec![ FinalizeOperation::InitializeMapping(Uniform::rand(rng)), - FinalizeOperation::UpdateKeyValue( - Uniform::rand(rng), - Uniform::rand(rng), - Uniform::rand(rng), - Uniform::rand(rng), - ), + FinalizeOperation::UpdateKeyValue(Uniform::rand(rng), Uniform::rand(rng), Uniform::rand(rng)), ], }; @@ -439,7 +445,7 @@ mod test { use super::*; use crate::transactions::confirmed::test_helpers; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; #[test] fn test_accepted_execute() { @@ -451,12 +457,7 @@ mod test { // Create an `AcceptedExecution` with valid `FinalizeOperation`s. let finalize_operations = vec![ FinalizeOperation::InsertKeyValue(Uniform::rand(rng), Uniform::rand(rng), Uniform::rand(rng)), - FinalizeOperation::UpdateKeyValue( - Uniform::rand(rng), - Uniform::rand(rng), - Uniform::rand(rng), - Uniform::rand(rng), - ), + FinalizeOperation::UpdateKeyValue(Uniform::rand(rng), Uniform::rand(rng), Uniform::rand(rng)), FinalizeOperation::RemoveKeyValue(Uniform::rand(rng), Uniform::rand(rng)), ]; let confirmed = ConfirmedTransaction::accepted_execute(index, tx.clone(), finalize_operations.clone()).unwrap(); diff --git a/ledger/block/src/transactions/confirmed/serialize.rs b/ledger/block/src/transactions/confirmed/serialize.rs index 7b7925fd52..67d62f610d 100644 --- a/ledger/block/src/transactions/confirmed/serialize.rs +++ b/ledger/block/src/transactions/confirmed/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transactions/confirmed/string.rs b/ledger/block/src/transactions/confirmed/string.rs index 6d361bb82e..1b40c9e454 100644 --- a/ledger/block/src/transactions/confirmed/string.rs +++ b/ledger/block/src/transactions/confirmed/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transactions/merkle.rs b/ledger/block/src/transactions/merkle.rs index 4efc914ba5..f5a3e99b96 100644 --- a/ledger/block/src/transactions/merkle.rs +++ b/ledger/block/src/transactions/merkle.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -17,13 +18,23 @@ use super::*; impl Transactions { /// Returns the finalize root of the transactions. pub fn to_finalize_root(&self, ratified_finalize_operations: Vec>) -> Result> { - // Prepare the leaves. - let leaves = self.finalize_operations().chain(&ratified_finalize_operations).map(ToBits::to_bits_le); - // Compute the finalize tree. - // Note: This call will check the number of finalize operations is within the size of the Merkle tree. - let tree = N::merkle_tree_bhp::(&leaves.collect::>())?; - // Return the finalize root. - Ok(*tree.root()) + // Prepare the ratified finalize ID - a Merkle tree composed of the ratified finalize operations. + let ratified_finalize_id = *N::merkle_tree_bhp::( + &ratified_finalize_operations.iter().map(ToBits::to_bits_le).collect::>(), + )? + .root(); + + // Prepare the leaves, composed of: + // | transaction_0 finalize ID, ..., transaction_n finalize ID | ratified finalize ID | + let leaves = self + .iter() + .map(|tx| tx.to_finalize_id().map(|id| id.to_bits_le())) + .chain(std::iter::once(Ok(ratified_finalize_id.to_bits_le()))) + .collect::>>()?; + + // Compute the finalize root. + // Note: This call will ensure the number of finalize operations is within the size of the Merkle tree. + Ok(*N::merkle_tree_bhp::(&leaves)?.root()) } } @@ -67,13 +78,17 @@ impl Transactions { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_transactions_depth() { // Ensure the log2 relationship between depth and the maximum number of transactions. - assert_eq!(2usize.pow(TRANSACTIONS_DEPTH as u32), Transactions::::MAX_TRANSACTIONS); + // Note: This test uses 'checked_sub' to ensure the depth is not zero. + assert_eq!( + 2usize.pow(TRANSACTIONS_DEPTH as u32).checked_sub(1).expect("Invalid depth"), + Transactions::::MAX_TRANSACTIONS + ); } } diff --git a/ledger/block/src/transactions/mod.rs b/ledger/block/src/transactions/mod.rs index 794b65cab7..39628f15bb 100644 --- a/ledger/block/src/transactions/mod.rs +++ b/ledger/block/src/transactions/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -28,18 +29,18 @@ use console::{ network::prelude::*, program::{ Ciphertext, + FINALIZE_ID_DEPTH, + FINALIZE_OPERATIONS_DEPTH, ProgramOwner, Record, + TRANSACTIONS_DEPTH, TransactionsPath, TransactionsTree, - FINALIZE_OPERATIONS_DEPTH, - TRANSACTIONS_DEPTH, }, types::{Field, Group, U64}, }; use ledger_committee::Committee; use ledger_narwhal_batch_header::BatchHeader; -use ledger_narwhal_subdag::Subdag; use synthesizer_program::FinalizeOperation; use indexmap::IndexMap; @@ -170,11 +171,11 @@ impl Transactions { impl Transactions { /// The maximum number of aborted transactions allowed in a block. - pub const MAX_ABORTED_TRANSACTIONS: usize = Subdag::::MAX_ROUNDS - * Committee::::MAX_COMMITTEE_SIZE as usize - * BatchHeader::::MAX_TRANSMISSIONS_PER_BATCH; + pub const MAX_ABORTED_TRANSACTIONS: usize = BatchHeader::::MAX_TRANSMISSIONS_PER_BATCH + * BatchHeader::::MAX_GC_ROUNDS + * Committee::::MAX_COMMITTEE_SIZE as usize; /// The maximum number of transactions allowed in a block. - pub const MAX_TRANSACTIONS: usize = usize::pow(2, TRANSACTIONS_DEPTH as u32); + pub const MAX_TRANSACTIONS: usize = usize::pow(2, TRANSACTIONS_DEPTH as u32).saturating_sub(1); /// Returns an iterator over all transactions, for all transactions in `self`. pub fn iter(&self) -> impl '_ + ExactSizeIterator> { @@ -339,7 +340,7 @@ impl Transactions { pub mod test_helpers { use super::*; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; /// Samples a block transactions. pub(crate) fn sample_block_transactions(rng: &mut TestRng) -> Transactions { @@ -350,14 +351,23 @@ pub mod test_helpers { #[cfg(test)] mod tests { use super::*; + use ledger_narwhal_batch_header::BatchHeader; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; #[test] - fn test_max_transactions() { - assert_eq!( - Transactions::::MAX_TRANSACTIONS, - ledger_narwhal_batch_header::BatchHeader::::MAX_TRANSACTIONS + fn test_max_transmissions() { + // Determine the maximum number of transmissions in a block. + let max_transmissions_per_block = BatchHeader::::MAX_TRANSMISSIONS_PER_BATCH + * BatchHeader::::MAX_GC_ROUNDS + * BatchHeader::::MAX_CERTIFICATES as usize; + + // Note: The maximum number of *transmissions* in a block cannot exceed the maximum number of *transactions* in a block. + // If you intended to change the number of 'MAX_TRANSACTIONS', note that this will break the inclusion proof, + // and you will need to migrate all users to a new circuit for the inclusion proof. + assert!( + max_transmissions_per_block <= Transactions::::MAX_TRANSACTIONS, + "The maximum number of transmissions in a block is too large" ); } } diff --git a/ledger/block/src/transactions/rejected/bytes.rs b/ledger/block/src/transactions/rejected/bytes.rs index c5cff5fe43..7746e8a9c7 100644 --- a/ledger/block/src/transactions/rejected/bytes.rs +++ b/ledger/block/src/transactions/rejected/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transactions/rejected/mod.rs b/ledger/block/src/transactions/rejected/mod.rs index c730935c4d..655ee40f67 100644 --- a/ledger/block/src/transactions/rejected/mod.rs +++ b/ledger/block/src/transactions/rejected/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -94,9 +95,9 @@ impl Rejected { #[cfg(test)] pub mod test_helpers { use super::*; - use console::{account::PrivateKey, network::Testnet3}; + use console::{account::PrivateKey, network::MainnetV0}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Samples a rejected deployment. pub(crate) fn sample_rejected_deployment(is_fee_private: bool, rng: &mut TestRng) -> Rejected { diff --git a/ledger/block/src/transactions/rejected/serialize.rs b/ledger/block/src/transactions/rejected/serialize.rs index a1998371e6..1cfc25de41 100644 --- a/ledger/block/src/transactions/rejected/serialize.rs +++ b/ledger/block/src/transactions/rejected/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transactions/rejected/string.rs b/ledger/block/src/transactions/rejected/string.rs index e15f66b6cb..2d8e03e888 100644 --- a/ledger/block/src/transactions/rejected/string.rs +++ b/ledger/block/src/transactions/rejected/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transactions/serialize.rs b/ledger/block/src/transactions/serialize.rs index f1a264e611..81fd339431 100644 --- a/ledger/block/src/transactions/serialize.rs +++ b/ledger/block/src/transactions/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -65,9 +66,9 @@ impl<'de, N: Network> Deserialize<'de> for Transactions { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const ITERATIONS: u32 = 6; diff --git a/ledger/block/src/transactions/string.rs b/ledger/block/src/transactions/string.rs index 29fcdbc894..9ab1dba03a 100644 --- a/ledger/block/src/transactions/string.rs +++ b/ledger/block/src/transactions/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transition/bytes.rs b/ledger/block/src/transition/bytes.rs index dacc875df8..7c54ad5924 100644 --- a/ledger/block/src/transition/bytes.rs +++ b/ledger/block/src/transition/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -53,10 +54,12 @@ impl FromBytes for Transition { let tpk = FromBytes::read_le(&mut reader)?; // Read the transition commitment. let tcm = FromBytes::read_le(&mut reader)?; + // Read the signer commitment. + let scm = FromBytes::read_le(&mut reader)?; // Construct the candidate transition. let transition = - Self::new(program_id, function_name, inputs, outputs, tpk, tcm).map_err(|e| error(e.to_string()))?; + Self::new(program_id, function_name, inputs, outputs, tpk, tcm, scm).map_err(|e| error(e.to_string()))?; // Ensure the transition ID matches the expected ID. match transition_id == *transition.id() { true => Ok(transition), @@ -91,7 +94,9 @@ impl ToBytes for Transition { // Write the transition public key. self.tpk.write_le(&mut writer)?; // Write the transition commitment. - self.tcm.write_le(&mut writer) + self.tcm.write_le(&mut writer)?; + // Write the signer commitment. + self.scm.write_le(&mut writer) } } diff --git a/ledger/block/src/transition/input/bytes.rs b/ledger/block/src/transition/input/bytes.rs index faceae3a05..eb00e313ad 100644 --- a/ledger/block/src/transition/input/bytes.rs +++ b/ledger/block/src/transition/input/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transition/input/mod.rs b/ledger/block/src/transition/input/mod.rs index 284af88f76..bafa4ed603 100644 --- a/ledger/block/src/transition/input/mod.rs +++ b/ledger/block/src/transition/input/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -180,9 +181,9 @@ impl Input { #[cfg(test)] pub(crate) mod test_helpers { use super::*; - use console::{network::Testnet3, program::Literal}; + use console::{network::MainnetV0, program::Literal}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Sample the transition inputs. pub(crate) fn sample_inputs() -> Vec<(::TransitionID, Input)> { diff --git a/ledger/block/src/transition/input/serialize.rs b/ledger/block/src/transition/input/serialize.rs index 3a959b7c40..8aff3c4cbe 100644 --- a/ledger/block/src/transition/input/serialize.rs +++ b/ledger/block/src/transition/input/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transition/input/string.rs b/ledger/block/src/transition/input/string.rs index c6a510414c..d4a5815752 100644 --- a/ledger/block/src/transition/input/string.rs +++ b/ledger/block/src/transition/input/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transition/merkle.rs b/ledger/block/src/transition/merkle.rs index d5a8fb33b1..78c3546a99 100644 --- a/ledger/block/src/transition/merkle.rs +++ b/ledger/block/src/transition/merkle.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -36,7 +37,7 @@ impl Transition { // Check if the input ID matches the given ID. if id == input.id() { // Return the transition leaf. - return Ok(input.to_transition_leaf(index as u8)); + return Ok(input.to_transition_leaf(u8::try_from(index)?)); } } // Error if the input ID was not found. @@ -48,7 +49,7 @@ impl Transition { // Check if the output ID matches the given ID. if id == output.id() { // Return the transition leaf. - return Ok(output.to_transition_leaf((self.inputs.len() + index) as u8)); + return Ok(output.to_transition_leaf(u8::try_from(self.inputs.len() + index)?)); } } // Error if the output ID was not found. @@ -97,9 +98,9 @@ impl Transition { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_transition_depth() { diff --git a/ledger/block/src/transition/mod.rs b/ledger/block/src/transition/mod.rs index 136b417e43..c72e61b650 100644 --- a/ledger/block/src/transition/mod.rs +++ b/ledger/block/src/transition/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -35,12 +36,13 @@ use console::{ Register, Request, Response, + TRANSITION_DEPTH, TransitionLeaf, TransitionPath, TransitionTree, Value, ValueType, - TRANSITION_DEPTH, + compute_function_id, }, types::{Field, Group}, }; @@ -61,6 +63,8 @@ pub struct Transition { tpk: Group, /// The transition commitment. tcm: Field, + /// The transition signer commitment. + scm: Field, } impl Transition { @@ -73,12 +77,13 @@ impl Transition { outputs: Vec>, tpk: Group, tcm: Field, + scm: Field, ) -> Result { // Compute the transition ID. let function_tree = Self::function_tree(&inputs, &outputs)?; let id = N::hash_bhp512(&(*function_tree.root(), tcm).to_bits_le())?; // Return the transition. - Ok(Self { id: id.into(), program_id, function_name, inputs, outputs, tpk, tcm }) + Ok(Self { id: id.into(), program_id, function_name, inputs, outputs, tpk, tcm, scm }) } /// Initializes a new transition from a request and response. @@ -93,9 +98,8 @@ impl Transition { let function_name = *request.function_name(); let num_inputs = request.inputs().len(); - // Compute the function ID as `Hash(network_id, program_id, function_name)`. - let function_id = - N::hash_bhp1024(&(network_id, program_id.name(), program_id.network(), function_name).to_bits_le())?; + // Compute the function ID. + let function_id = compute_function_id(&network_id, &program_id, &function_name)?; let inputs = request .input_ids() @@ -255,8 +259,10 @@ impl Transition { let tpk = request.to_tpk(); // Retrieve the `tcm`. let tcm = *request.tcm(); + // Retrieve the `scm`. + let scm = *request.scm(); // Return the transition. - Self::new(program_id, function_name, inputs, outputs, tpk, tcm) + Self::new(program_id, function_name, inputs, outputs, tpk, tcm, scm) } } @@ -295,23 +301,37 @@ impl Transition { pub const fn tcm(&self) -> &Field { &self.tcm } + + /// Returns the signer commitment. + pub const fn scm(&self) -> &Field { + &self.scm + } } impl Transition { /// Returns `true` if this is a `bond_public` transition. #[inline] pub fn is_bond_public(&self) -> bool { - self.inputs.len() == 2 - && self.outputs.is_empty() + self.inputs.len() == 3 + && self.outputs.len() == 1 && self.program_id.to_string() == "credits.aleo" && self.function_name.to_string() == "bond_public" } + /// Returns `true` if this is a `bond_validator` transition. + #[inline] + pub fn is_bond_validator(&self) -> bool { + self.inputs.len() == 3 + && self.outputs.len() == 1 + && self.program_id.to_string() == "credits.aleo" + && self.function_name.to_string() == "bond_validator" + } + /// Returns `true` if this is an `unbond_public` transition. #[inline] pub fn is_unbond_public(&self) -> bool { self.inputs.len() == 2 - && self.outputs.is_empty() + && self.outputs.len() == 1 && self.program_id.to_string() == "credits.aleo" && self.function_name.to_string() == "unbond_public" } @@ -471,7 +491,7 @@ pub mod test_helpers { use super::*; use crate::Transaction; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; /// Samples a random transition. pub(crate) fn sample_transition(rng: &mut TestRng) -> Transition { diff --git a/ledger/block/src/transition/output/bytes.rs b/ledger/block/src/transition/output/bytes.rs index 867b6600d6..9e21b40756 100644 --- a/ledger/block/src/transition/output/bytes.rs +++ b/ledger/block/src/transition/output/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transition/output/mod.rs b/ledger/block/src/transition/output/mod.rs index 3f0f5ff7a4..bbe80539c9 100644 --- a/ledger/block/src/transition/output/mod.rs +++ b/ledger/block/src/transition/output/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -257,9 +258,9 @@ impl Output { #[cfg(test)] pub(crate) mod test_helpers { use super::*; - use console::{network::Testnet3, program::Literal}; + use console::{network::MainnetV0, program::Literal}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Sample the transition outputs. pub(crate) fn sample_outputs() -> Vec<(::TransitionID, Output)> { diff --git a/ledger/block/src/transition/output/serialize.rs b/ledger/block/src/transition/output/serialize.rs index 47041735a0..8931715aaf 100644 --- a/ledger/block/src/transition/output/serialize.rs +++ b/ledger/block/src/transition/output/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transition/output/string.rs b/ledger/block/src/transition/output/string.rs index 460bac5e2a..77bc39ccab 100644 --- a/ledger/block/src/transition/output/string.rs +++ b/ledger/block/src/transition/output/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/transition/serialize.rs b/ledger/block/src/transition/serialize.rs index 47e5e4b4f4..fa5742a14a 100644 --- a/ledger/block/src/transition/serialize.rs +++ b/ledger/block/src/transition/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,7 +20,7 @@ impl Serialize for Transition { fn serialize(&self, serializer: S) -> Result { match serializer.is_human_readable() { true => { - let mut transition = serializer.serialize_struct("Transition", 7)?; + let mut transition = serializer.serialize_struct("Transition", 8)?; transition.serialize_field("id", &self.id)?; transition.serialize_field("program", &self.program_id)?; transition.serialize_field("function", &self.function_name)?; @@ -27,6 +28,7 @@ impl Serialize for Transition { transition.serialize_field("outputs", &self.outputs)?; transition.serialize_field("tpk", &self.tpk)?; transition.serialize_field("tcm", &self.tcm)?; + transition.serialize_field("scm", &self.scm)?; transition.end() } false => ToBytesSerializer::serialize_with_size_encoding(self, serializer), @@ -58,13 +60,15 @@ impl<'de, N: Network> Deserialize<'de> for Transition { DeserializeExt::take_from_value::(&mut transition, "tpk")?, // Retrieve the `tcm`. DeserializeExt::take_from_value::(&mut transition, "tcm")?, + // Retrieve the `scm`. + DeserializeExt::take_from_value::(&mut transition, "scm")?, ) .map_err(de::Error::custom)?; // Ensure the transition ID is correct. match id == *transition.id() { true => Ok(transition), - false => Err(error("Transition ID mismatch, possible data corruption")).map_err(de::Error::custom), + false => Err(de::Error::custom(error("Transition ID mismatch, possible data corruption"))), } } false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "transition"), diff --git a/ledger/block/src/transition/string.rs b/ledger/block/src/transition/string.rs index 1b896c8e35..5d7624e759 100644 --- a/ledger/block/src/transition/string.rs +++ b/ledger/block/src/transition/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/block/src/verify.rs b/ledger/block/src/verify.rs index 1cb990077b..c4c2f15146 100644 --- a/ledger/block/src/verify.rs +++ b/ledger/block/src/verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,7 +17,7 @@ #![allow(clippy::type_complexity)] use super::*; -use ledger_coinbase::{CoinbasePuzzle, EpochChallenge}; +use ledger_puzzle::Puzzle; use synthesizer_program::FinalizeOperation; use std::collections::HashSet; @@ -30,18 +31,29 @@ impl Block { &self, previous_block: &Block, current_state_root: N::StateRoot, - current_committee: &Committee, - current_puzzle: &CoinbasePuzzle, - current_epoch_challenge: &EpochChallenge, + previous_committee_lookback: &Committee, + current_committee_lookback: &Committee, + current_puzzle: &Puzzle, + current_epoch_hash: N::BlockHash, current_timestamp: i64, ratified_finalize_operations: Vec>, - ) -> Result> { + ) -> Result<(Vec>, Vec)> { // Ensure the block hash is correct. self.verify_hash(previous_block.height(), previous_block.hash())?; // Ensure the block authority is correct. - let (expected_round, expected_height, expected_timestamp, expected_existing_transaction_ids) = - self.verify_authority(previous_block.round(), previous_block.height(), current_committee)?; + let ( + expected_round, + expected_height, + expected_timestamp, + expected_existing_solution_ids, + expected_existing_transaction_ids, + ) = self.verify_authority( + previous_block.round(), + previous_block.height(), + previous_committee_lookback, + current_committee_lookback, + )?; // Ensure the block solutions are correct. let ( @@ -53,7 +65,7 @@ impl Block { expected_last_coinbase_timestamp, expected_block_reward, expected_puzzle_reward, - ) = self.verify_solutions(previous_block, current_puzzle, current_epoch_challenge)?; + ) = self.verify_solutions(previous_block, current_puzzle, current_epoch_hash)?; // Ensure the block ratifications are correct. self.verify_ratifications(expected_block_reward, expected_puzzle_reward)?; @@ -94,8 +106,8 @@ impl Block { current_timestamp, )?; - // Return the expected existing transaction ids. - Ok(expected_existing_transaction_ids) + // Return the expected existing solution IDs and transaction IDs. + Ok((expected_existing_solution_ids, expected_existing_transaction_ids)) } } @@ -138,8 +150,10 @@ impl Block { &self, previous_round: u64, previous_height: u32, - current_committee: &Committee, - ) -> Result<(u64, u32, i64, Vec)> { + previous_committee_lookback: &Committee, + current_committee_lookback: &Committee, + ) -> Result<(u64, u32, i64, Vec>, Vec)> { + // Note: Do not remove this. This ensures that all blocks after genesis are quorum blocks. #[cfg(not(any(test, feature = "test")))] ensure!(self.authority.is_quorum(), "The next block must be a quorum block"); @@ -160,27 +174,37 @@ impl Block { subdag.anchor_round(), previous_round ); + // Ensure that the rounds in the subdag are sequential. + if previous_round != 0 { + for round in previous_round..=subdag.anchor_round() { + ensure!( + subdag.contains_key(&round), + "Subdag is missing round {round} in block {expected_height}", + ); + } + } // Output the subdag anchor round. subdag.anchor_round() } }; - // Ensure the block round is at least the starting round of the committee. + // Ensure the block round minus the committee lookback range is at least the starting round of the committee lookback. ensure!( - expected_round >= current_committee.starting_round(), - "Block {} has an invalid round (found '{expected_round}', expected at least '{}')", - expected_height, - current_committee.starting_round() + expected_round.saturating_sub(Committee::::COMMITTEE_LOOKBACK_RANGE) + >= current_committee_lookback.starting_round(), + "Block {expected_height} has an invalid round (found '{}', expected at least '{}')", + expected_round.saturating_sub(Committee::::COMMITTEE_LOOKBACK_RANGE), + current_committee_lookback.starting_round() ); // Ensure the block authority is correct. - // Determine the transaction IDs expected to be in previous blocks. - let expected_existing_transaction_ids = match &self.authority { + // Determine the solution IDs and transaction IDs that are expected to be in previous blocks. + let (expected_existing_solution_ids, expected_existing_transaction_ids) = match &self.authority { Authority::Beacon(signature) => { // Retrieve the signer. let signer = signature.to_address(); // Ensure the block is signed by a committee member. ensure!( - current_committee.members().contains_key(&signer), + current_committee_lookback.members().contains_key(&signer), "Beacon block {expected_height} has a signer not in the committee (found '{signer}')", ); // Ensure the signature is valid. @@ -189,11 +213,11 @@ impl Block { "Signature is invalid in block {expected_height}" ); - vec![] + (vec![], vec![]) } Authority::Quorum(subdag) => { // Compute the expected leader. - let expected_leader = current_committee.get_leader(expected_round)?; + let expected_leader = current_committee_lookback.get_leader(expected_round)?; // Ensure the block is authored by the expected leader. ensure!( subdag.leader_address() == expected_leader, @@ -204,6 +228,7 @@ impl Block { Self::check_subdag_transmissions( subdag, &self.solutions, + &self.aborted_solution_ids, &self.transactions, &self.aborted_transaction_ids, )? @@ -214,12 +239,41 @@ impl Block { let expected_timestamp = match &self.authority { // Beacon blocks do not have a timestamp check. Authority::Beacon(..) => self.timestamp(), - // Quorum blocks use the median timestamp from the subdag. - Authority::Quorum(subdag) => subdag.timestamp(), + // Quorum blocks use the weighted median timestamp from the subdag. + Authority::Quorum(subdag) => subdag.timestamp(previous_committee_lookback), }; + // Check that the committee IDs are correct. + if let Authority::Quorum(subdag) = &self.authority { + // Check that the committee ID of the leader certificate is correct. + ensure!( + subdag.leader_certificate().committee_id() == current_committee_lookback.id(), + "Leader certificate has an incorrect committee ID" + ); + + // Check that all all certificates on each round have the same committee ID. + cfg_iter!(subdag).try_for_each(|(round, certificates)| { + // Check that every certificate for a given round shares the same committee ID. + let expected_committee_id = certificates + .first() + .map(|certificate| certificate.committee_id()) + .ok_or(anyhow!("No certificates found for subdag round {round}"))?; + ensure!( + certificates.iter().skip(1).all(|certificate| certificate.committee_id() == expected_committee_id), + "Certificates on round {round} do not all have the same committee ID", + ); + Ok(()) + })?; + } + // Return success. - Ok((expected_round, expected_height, expected_timestamp, expected_existing_transaction_ids)) + Ok(( + expected_round, + expected_height, + expected_timestamp, + expected_existing_solution_ids, + expected_existing_transaction_ids, + )) } /// Ensures the block ratifications are correct. @@ -260,100 +314,86 @@ impl Block { fn verify_solutions( &self, previous_block: &Block, - current_puzzle: &CoinbasePuzzle, - current_epoch_challenge: &EpochChallenge, + current_puzzle: &Puzzle, + current_epoch_hash: N::BlockHash, ) -> Result<(u128, u128, u64, u64, u64, i64, u64, u64)> { let height = self.height(); let timestamp = self.timestamp(); - let (combined_proof_target, expected_cumulative_proof_target, is_coinbase_target_reached) = match &self - .solutions - { - Some(coinbase) => { - // Ensure the number of solutions is within the allowed range. - ensure!( - coinbase.len() <= N::MAX_SOLUTIONS, - "Block {height} contains too many prover solutions (found '{}', expected '{}')", - coinbase.len(), - N::MAX_SOLUTIONS - ); - // Ensure the solutions are not accepted after the block height at year 10. - if height > block_height_at_year(N::BLOCK_TIME, 10) { - bail!("Solutions are no longer accepted after the block height at year 10."); - } - - // Ensure the puzzle proof is valid. - if let Err(e) = - current_puzzle.check_solutions(coinbase, current_epoch_challenge, previous_block.proof_target()) - { - bail!("Block {height} contains an invalid puzzle proof - {e}"); - } + // Ensure the number of solutions is within the allowed range. + ensure!( + self.solutions.len() <= N::MAX_SOLUTIONS, + "Block {height} contains too many prover solutions (found '{}', expected '{}')", + self.solutions.len(), + N::MAX_SOLUTIONS + ); + // Ensure the number of aborted solution IDs is within the allowed range. + ensure!( + self.aborted_solution_ids.len() <= Solutions::::MAX_ABORTED_SOLUTIONS, + "Block {height} contains too many aborted solution IDs (found '{}', expected '{}')", + self.aborted_solution_ids.len(), + Solutions::::MAX_ABORTED_SOLUTIONS + ); - // Compute the combined proof target. - let combined_proof_target = coinbase.to_combined_proof_target()?; + // Ensure there are no duplicate solution IDs. + if has_duplicates( + self.solutions + .as_ref() + .map(PuzzleSolutions::solution_ids) + .into_iter() + .flatten() + .chain(self.aborted_solution_ids()), + ) { + bail!("Found a duplicate solution in block {height}"); + } - // Ensure that the block cumulative proof target is less than the previous block's coinbase target. - // Note: This is a sanity check, as the cumulative proof target resets to 0 if the - // coinbase target was reached in this block. - if self.cumulative_proof_target() >= previous_block.coinbase_target() as u128 { - bail!( - "The cumulative proof target in block {height} must be less than the previous coinbase target" - ) - } + // Compute the combined proof target. + let combined_proof_target = match self.solutions.deref() { + Some(solutions) => current_puzzle.get_combined_proof_target(solutions)?, + None => 0u128, + }; - // Compute the actual cumulative proof target (which can exceed the coinbase target). - let cumulative_proof_target = - previous_block.cumulative_proof_target().saturating_add(combined_proof_target); - // Determine if the coinbase target is reached. - let is_coinbase_target_reached = cumulative_proof_target >= previous_block.coinbase_target() as u128; - // Compute the block cumulative proof target (which cannot exceed the coinbase target). - let expected_cumulative_proof_target = match is_coinbase_target_reached { - true => 0u128, - false => cumulative_proof_target, - }; - - (combined_proof_target, expected_cumulative_proof_target, is_coinbase_target_reached) + // Verify the solutions. + if let Some(coinbase) = self.solutions.deref() { + // Ensure the puzzle proof is valid. + if let Err(e) = current_puzzle.check_solutions(coinbase, current_epoch_hash, previous_block.proof_target()) + { + bail!("Block {height} contains an invalid puzzle proof - {e}"); } - None => { - // Set the combined proof target. - let combined_proof_target = 0; - // Determine the cumulative proof target. - let expected_cumulative_proof_target = previous_block.cumulative_proof_target(); - (combined_proof_target, expected_cumulative_proof_target, false) + // Ensure that the block cumulative proof target is less than the previous block's coinbase target. + // Note: This is a sanity check, as the cumulative proof target resets to 0 if the + // coinbase target was reached in this block. + if self.cumulative_proof_target() >= previous_block.coinbase_target() as u128 { + bail!("The cumulative proof target in block {height} must be less than the previous coinbase target") } }; - // Compute the expected cumulative weight. - let expected_cumulative_weight = previous_block.cumulative_weight().saturating_add(combined_proof_target); - - // Construct the next coinbase target. - let expected_coinbase_target = coinbase_target( + // Calculate the next coinbase targets and timestamps. + let ( + expected_coinbase_target, + expected_proof_target, + expected_cumulative_proof_target, + expected_cumulative_weight, + expected_last_coinbase_target, + expected_last_coinbase_timestamp, + ) = to_next_targets::( + previous_block.cumulative_proof_target(), + combined_proof_target, + previous_block.coinbase_target(), + previous_block.cumulative_weight(), previous_block.last_coinbase_target(), previous_block.last_coinbase_timestamp(), timestamp, - N::ANCHOR_TIME, - N::NUM_BLOCKS_PER_EPOCH, - N::GENESIS_COINBASE_TARGET, )?; - // Ensure the proof target is correct. - let expected_proof_target = proof_target(expected_coinbase_target, N::GENESIS_PROOF_TARGET); - - // Determine the expected last coinbase target. - let expected_last_coinbase_target = match is_coinbase_target_reached { - true => expected_coinbase_target, - false => previous_block.last_coinbase_target(), - }; - // Determine the expected last coinbase timestamp. - let expected_last_coinbase_timestamp = match is_coinbase_target_reached { - true => timestamp, - false => previous_block.last_coinbase_timestamp(), - }; // Calculate the expected coinbase reward. - let expected_coinbase_reward = coinbase_reward( + let expected_coinbase_reward = coinbase_reward::( height, + timestamp, + N::GENESIS_TIMESTAMP, N::STARTING_SUPPLY, + N::ANCHOR_TIME, N::ANCHOR_HEIGHT, N::BLOCK_TIME, combined_proof_target, @@ -365,9 +405,17 @@ impl Block { let expected_transaction_fees = self.transactions.iter().map(|tx| Ok(*tx.priority_fee_amount()?)).sum::>()?; + // Calculate the time since last block. + let time_since_last_block = timestamp.saturating_sub(previous_block.timestamp()); // Compute the expected block reward. - let expected_block_reward = - block_reward(N::STARTING_SUPPLY, N::BLOCK_TIME, expected_coinbase_reward, expected_transaction_fees); + let expected_block_reward = block_reward::( + height, + N::STARTING_SUPPLY, + N::BLOCK_TIME, + time_since_last_block, + expected_coinbase_reward, + expected_transaction_fees, + ); // Compute the expected puzzle reward. let expected_puzzle_reward = puzzle_reward(expected_coinbase_reward); @@ -387,9 +435,6 @@ impl Block { fn verify_transactions(&self) -> Result<()> { let height = self.height(); - // Ensure there are transactions. - ensure!(!self.transactions.is_empty(), "Block {height} must contain at least 1 transaction"); - // Ensure the number of transactions is within the allowed range. if self.transactions.len() > Transactions::::MAX_TRANSACTIONS { bail!( @@ -493,10 +538,7 @@ impl Block { /// Computes the solutions root for the block. fn compute_solutions_root(&self) -> Result> { - match self.solutions { - Some(ref coinbase) => coinbase.to_accumulator_point(), - None => Ok(Field::zero()), - } + self.solutions.to_solutions_root() } /// Computes the subdag root for the block. @@ -508,58 +550,88 @@ impl Block { } /// Checks that the transmission IDs in the given subdag matches the solutions and transactions in the block. + /// Returns the IDs of the transactions and solutions that should already exist in the ledger. pub(super) fn check_subdag_transmissions( subdag: &Subdag, - solutions: &Option>, + solutions: &Option>, + aborted_solution_ids: &[SolutionID], transactions: &Transactions, aborted_transaction_ids: &[N::TransactionID], - ) -> Result> { + ) -> Result<(Vec>, Vec)> { // Prepare an iterator over the solution IDs. let mut solutions = solutions.as_ref().map(|s| s.deref()).into_iter().flatten().peekable(); - // Prepare an iterator over the unconfirmed transaction IDs. - let unconfirmed_transaction_ids = cfg_iter!(transactions) - .map(|confirmed| confirmed.to_unconfirmed_transaction_id()) + // Prepare an iterator over the unconfirmed transactions. + let unconfirmed_transactions = cfg_iter!(transactions) + .map(|confirmed| confirmed.to_unconfirmed_transaction()) .collect::>>()?; - let mut unconfirmed_transaction_ids = unconfirmed_transaction_ids.iter().peekable(); + let mut unconfirmed_transactions = unconfirmed_transactions.iter().peekable(); - // Initialize a list of already seen transmission IDs. - let mut seen_transmission_ids = HashSet::new(); + // Initialize a set of already seen transaction and solution IDs. + let mut seen_transaction_ids = HashSet::new(); + let mut seen_solution_ids = HashSet::new(); - // Initialize a list of aborted or already-existing solution IDs. - let mut aborted_or_existing_solution_ids = Vec::new(); - // Initialize a list of aborted or already-existing transaction IDs. - let mut aborted_or_existing_transaction_ids = Vec::new(); + // Initialize a set of aborted or already-existing solution IDs. + let mut aborted_or_existing_solution_ids = HashSet::new(); + // Initialize a set of aborted or already-existing transaction IDs. + let mut aborted_or_existing_transaction_ids = HashSet::new(); // Iterate over the transmission IDs. for transmission_id in subdag.transmission_ids() { - // If the transmission ID has already been seen, then continue. - if !seen_transmission_ids.insert(transmission_id) { - continue; + // If the transaction or solution ID has already been seen, then continue. + // Note: This is done instead of checking `TransmissionID` directly, because we need to + // ensure that each transaction or solution ID is unique. The `TransmissionID` is guaranteed + // to be unique, however the transaction/solution ID may not be due to malleability concerns. + match transmission_id { + TransmissionID::Ratification => {} + TransmissionID::Solution(solution_id, _) => { + if !seen_solution_ids.insert(solution_id) { + continue; + } + } + TransmissionID::Transaction(transaction_id, _) => { + if !seen_transaction_ids.insert(transaction_id) { + continue; + } + } } // Process the transmission ID. match transmission_id { TransmissionID::Ratification => {} - TransmissionID::Solution(commitment) => { + TransmissionID::Solution(solution_id, _checksum) => { match solutions.peek() { - // Check the next solution matches the expected commitment. - Some((_, solution)) if solution.commitment() == *commitment => { + // Check the next solution matches the expected solution ID. + // We don't check against the checksum, because check_solution_mut might mutate the solution. + Some((_, solution)) if solution.id() == *solution_id => { // Increment the solution iterator. solutions.next(); } // Otherwise, add the solution ID to the aborted or existing list. - _ => aborted_or_existing_solution_ids.push(commitment), + _ => { + if !aborted_or_existing_solution_ids.insert(*solution_id) { + bail!("Block contains a duplicate aborted solution ID (found '{solution_id}')"); + } + } } } - TransmissionID::Transaction(transaction_id) => { - match unconfirmed_transaction_ids.peek() { + TransmissionID::Transaction(transaction_id, checksum) => { + match unconfirmed_transactions.peek() { // Check the next transaction matches the expected transaction. - Some(expected_id) if transaction_id == *expected_id => { - // Increment the unconfirmed transaction ID iterator. - unconfirmed_transaction_ids.next(); + Some(transaction) + if transaction.id() == *transaction_id + && Data::>::Buffer(transaction.to_bytes_le()?.into()) + .to_checksum::()? + == *checksum => + { + // Increment the unconfirmed transaction iterator. + unconfirmed_transactions.next(); } // Otherwise, add the transaction ID to the aborted or existing list. - _ => aborted_or_existing_transaction_ids.push(*transaction_id), + _ => { + if !aborted_or_existing_transaction_ids.insert(*transaction_id) { + bail!("Block contains a duplicate aborted transaction ID (found '{transaction_id}')"); + } + } } } } @@ -568,11 +640,17 @@ impl Block { // Ensure there are no more solutions in the block. ensure!(solutions.next().is_none(), "There exists more solutions than expected."); // Ensure there are no more transactions in the block. - ensure!(unconfirmed_transaction_ids.next().is_none(), "There exists more transactions than expected."); + ensure!(unconfirmed_transactions.next().is_none(), "There exists more transactions than expected."); - // TODO: Move this check to be outside of this method, and check against the ledger for existence. - // Ensure there are no aborted or existing solution IDs. - // ensure!(aborted_or_existing_solution_ids.is_empty(), "Block contains aborted or already-existing solutions."); + // Ensure the aborted solution IDs match. + for aborted_solution_id in aborted_solution_ids { + // If the aborted transaction ID is not found, throw an error. + if !aborted_or_existing_solution_ids.contains(aborted_solution_id) { + bail!( + "Block contains an aborted solution ID that is not found in the subdag (found '{aborted_solution_id}')" + ); + } + } // Ensure the aborted transaction IDs match. for aborted_transaction_id in aborted_transaction_ids { // If the aborted transaction ID is not found, throw an error. @@ -583,13 +661,17 @@ impl Block { } } - // Retrieve the transaction ids that should already exist in the ledger. + // Retrieve the solution IDs that should already exist in the ledger. + let existing_solution_ids: Vec<_> = aborted_or_existing_solution_ids + .difference(&aborted_solution_ids.iter().copied().collect()) + .copied() + .collect(); + // Retrieve the transaction IDs that should already exist in the ledger. let existing_transaction_ids: Vec<_> = aborted_or_existing_transaction_ids - .iter() - .filter(|id| !aborted_transaction_ids.contains(id)) + .difference(&aborted_transaction_ids.iter().copied().collect()) .copied() .collect(); - Ok(existing_transaction_ids) + Ok((existing_solution_ids, existing_transaction_ids)) } } diff --git a/ledger/coinbase/benches/coinbase_puzzle.rs b/ledger/coinbase/benches/coinbase_puzzle.rs deleted file mode 100644 index fe8c86c4ca..0000000000 --- a/ledger/coinbase/benches/coinbase_puzzle.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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. - -#![allow(clippy::single_element_loop)] - -#[macro_use] -extern crate criterion; - -use console::{ - account::*, - network::{Network, Testnet3}, -}; -use snarkvm_ledger_coinbase::{CoinbasePuzzle, CoinbaseSolution, EpochChallenge, PuzzleConfig}; - -use criterion::Criterion; -use rand::{self, thread_rng, CryptoRng, RngCore}; - -type CoinbasePuzzleInst = CoinbasePuzzle; - -fn sample_inputs( - degree: u32, - rng: &mut (impl CryptoRng + RngCore), -) -> (EpochChallenge, Address, u64) { - let epoch_challenge = sample_epoch_challenge(degree, rng); - let (address, nonce) = sample_address_and_nonce(rng); - (epoch_challenge, address, nonce) -} - -fn sample_epoch_challenge(degree: u32, rng: &mut (impl CryptoRng + RngCore)) -> EpochChallenge { - EpochChallenge::new(rng.next_u32(), Default::default(), degree).unwrap() -} - -fn sample_address_and_nonce(rng: &mut (impl CryptoRng + RngCore)) -> (Address, u64) { - let private_key = PrivateKey::new(rng).unwrap(); - let address = Address::try_from(private_key).unwrap(); - let nonce = rng.next_u64(); - (address, nonce) -} - -#[cfg(feature = "setup")] -fn coinbase_puzzle_trim(c: &mut Criterion) { - let max_degree = 1 << 15; - let max_config = PuzzleConfig { degree: max_degree }; - let universal_srs = CoinbasePuzzle::::setup(max_config).unwrap(); - - for degree in [(1 << 13) - 1] { - let config = PuzzleConfig { degree }; - - c.bench_function(&format!("CoinbasePuzzle::Trim 2^{}", ((degree + 1) as f64).log2()), |b| { - b.iter(|| CoinbasePuzzleInst::trim(&universal_srs, config).unwrap()) - }); - } -} - -#[cfg(feature = "setup")] -fn coinbase_puzzle_prove(c: &mut Criterion) { - let rng = &mut thread_rng(); - - let max_degree = 1 << 15; - let max_config = PuzzleConfig { degree: max_degree }; - let universal_srs = CoinbasePuzzle::::setup(max_config).unwrap(); - - for degree in [(1 << 13) - 1] { - let config = PuzzleConfig { degree }; - let puzzle = CoinbasePuzzleInst::trim(&universal_srs, config).unwrap(); - - c.bench_function(&format!("CoinbasePuzzle::Prove 2^{}", ((degree + 1) as f64).log2()), |b| { - let (epoch_challenge, address, nonce) = sample_inputs(degree, rng); - b.iter(|| puzzle.prove(&epoch_challenge, address, nonce, None).unwrap()) - }); - } -} - -#[cfg(feature = "setup")] -fn coinbase_puzzle_verify(c: &mut Criterion) { - let rng = &mut thread_rng(); - - let max_degree = 1 << 15; - let max_config = PuzzleConfig { degree: max_degree }; - let universal_srs = CoinbasePuzzle::::setup(max_config).unwrap(); - - for degree in [(1 << 13) - 1] { - let config = PuzzleConfig { degree }; - let puzzle = CoinbasePuzzleInst::trim(&universal_srs, config).unwrap(); - let epoch_challenge = sample_epoch_challenge(degree, rng); - - for batch_size in [10, 100, ::MAX_SOLUTIONS] { - let solutions = (0..batch_size) - .map(|_| { - let (address, nonce) = sample_address_and_nonce(rng); - puzzle.prove(&epoch_challenge, address, nonce, None).unwrap() - }) - .collect::>(); - let solutions = CoinbaseSolution::new(solutions).unwrap(); - - c.bench_function( - &format!("CoinbasePuzzle::Verify {batch_size} of 2^{}", ((degree + 1) as f64).log2()), - |b| b.iter(|| puzzle.check_solutions(&solutions, &epoch_challenge, 0u64).unwrap()), - ); - } - } -} - -criterion_group! { - name = coinbase_puzzle; - config = Criterion::default().sample_size(10); - targets = coinbase_puzzle_trim, coinbase_puzzle_prove, coinbase_puzzle_verify, -} - -criterion_main!(coinbase_puzzle); diff --git a/ledger/coinbase/src/hash.rs b/ledger/coinbase/src/hash.rs deleted file mode 100644 index cf1339ca3a..0000000000 --- a/ledger/coinbase/src/hash.rs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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 console::prelude::{bail, cfg_into_iter, ensure, Result, Zero}; -use snarkvm_algorithms::{fft::DensePolynomial, polycommit::kzg10::KZGCommitment}; -use snarkvm_curves::PairingEngine; -use snarkvm_fields::PrimeField; -use snarkvm_utilities::CanonicalSerialize; - -use blake2::Digest; - -#[cfg(not(feature = "serial"))] -use rayon::prelude::*; - -pub fn hash_to_coefficients(input: &[u8], num_coefficients: u32) -> Vec { - // Hash the input. - let hash = blake2::Blake2s256::digest(input); - // Hash with a counter and return the coefficients. - cfg_into_iter!(0..num_coefficients) - .map(|counter| { - let mut input_with_counter = [0u8; 36]; - input_with_counter[..32].copy_from_slice(&hash); - input_with_counter[32..].copy_from_slice(&counter.to_le_bytes()); - F::from_bytes_le_mod_order(&blake2::Blake2b512::digest(input_with_counter)) - }) - .collect() -} - -pub fn hash_to_polynomial(input: &[u8], degree: u32) -> DensePolynomial { - // Hash the input into coefficients. - let coefficients = hash_to_coefficients(input, degree + 1); - // Construct the polynomial from the coefficients. - DensePolynomial::from_coefficients_vec(coefficients) -} - -pub fn hash_commitment(commitment: &KZGCommitment) -> Result { - // Convert the commitment into bytes. - let mut bytes = Vec::with_capacity(96); - commitment.serialize_uncompressed(&mut bytes)?; - ensure!(bytes.len() == 96, "Invalid commitment byte length for hashing"); - - // Return the hash of the commitment. - Ok(E::Fr::from_bytes_le_mod_order(&blake2::Blake2b512::digest(&bytes))) -} - -pub fn hash_commitments( - commitments: impl ExactSizeIterator>, -) -> Result> { - // Retrieve the number of commitments. - let num_commitments = match u32::try_from(commitments.len()) { - Ok(num_commitments) => num_commitments, - Err(_) => bail!("Cannot hash more than 2^32 commitments: found {}", commitments.len()), - }; - ensure!(!num_commitments.is_zero(), "No commitments provided for hashing"); - - // Convert the commitments into bytes. - let bytes = commitments - .flat_map(|commitment| { - let mut bytes = Vec::with_capacity(96); - commitment.serialize_uncompressed(&mut bytes).unwrap(); - bytes - }) - .collect::>(); - ensure!(bytes.len() == 96 * usize::try_from(num_commitments)?, "Invalid commitment byte length for hashing"); - - // Hash the commitment bytes into coefficients. - Ok(hash_to_coefficients(&bytes, num_commitments + 1)) -} diff --git a/ledger/coinbase/src/helpers/coinbase_solution/mod.rs b/ledger/coinbase/src/helpers/coinbase_solution/mod.rs deleted file mode 100644 index a735607a53..0000000000 --- a/ledger/coinbase/src/helpers/coinbase_solution/mod.rs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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. - -mod bytes; -mod serialize; -mod string; - -use super::*; - -use indexmap::IndexMap; - -/// The coinbase puzzle solution is composed of individual prover solutions. -#[derive(Clone, Eq, PartialEq)] -pub struct CoinbaseSolution { - /// The prover solutions for the coinbase puzzle. - solutions: IndexMap, ProverSolution>, -} - -impl CoinbaseSolution { - /// Initializes a new instance of the solutions. - pub fn new(solutions: Vec>) -> Result { - // Ensure the solutions are not empty. - ensure!(!solutions.is_empty(), "There are no solutions to verify for the coinbase puzzle"); - // Ensure the number of partial solutions does not exceed `MAX_PROVER_SOLUTIONS`. - if solutions.len() > N::MAX_SOLUTIONS { - bail!( - "The solutions exceed the allowed number of partial solutions. ({} > {})", - solutions.len(), - N::MAX_SOLUTIONS - ); - } - // Ensure the puzzle commitments are unique. - if has_duplicates(solutions.iter().map(|s| s.commitment())) { - bail!("The solutions contain duplicate puzzle commitments"); - } - // Return the solutions. - Ok(Self { solutions: solutions.into_iter().map(|solution| (solution.commitment(), solution)).collect() }) - } - - /// Returns the puzzle commitments. - pub fn puzzle_commitments(&self) -> impl '_ + Iterator> { - self.solutions.keys() - } - - /// Returns the number of solutions. - pub fn len(&self) -> usize { - self.solutions.len() - } - - /// Returns `true` if there are no solutions. - pub fn is_empty(&self) -> bool { - self.solutions.is_empty() - } - - /// Returns the prover solution for the puzzle commitment. - pub fn get_solution(&self, puzzle_commitment: &PuzzleCommitment) -> Option<&ProverSolution> { - self.solutions.get(puzzle_commitment) - } - - /// Returns the combined sum of the prover solutions. - pub fn to_combined_proof_target(&self) -> Result { - // Compute the combined proof target as a u128. - self.solutions.values().try_fold(0u128, |combined, solution| { - combined.checked_add(solution.to_target()? as u128).ok_or_else(|| anyhow!("Combined target overflowed")) - }) - } - - /// Returns the accumulator challenge point. - pub fn to_accumulator_point(&self) -> Result> { - let mut challenge_points = hash_commitments(self.solutions.keys().map(|pcm| **pcm))?; - ensure!(challenge_points.len() == self.solutions.len() + 1, "Invalid number of challenge points"); - - // Pop the last challenge point as the accumulator challenge point. - match challenge_points.pop() { - Some(point) => Ok(Field::new(point)), - None => bail!("Missing the accumulator challenge point"), - } - } -} - -impl Deref for CoinbaseSolution { - type Target = IndexMap, ProverSolution>; - - fn deref(&self) -> &Self::Target { - &self.solutions - } -} diff --git a/ledger/coinbase/src/helpers/epoch_challenge/bytes.rs b/ledger/coinbase/src/helpers/epoch_challenge/bytes.rs deleted file mode 100644 index e9e250ca9f..0000000000 --- a/ledger/coinbase/src/helpers/epoch_challenge/bytes.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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 super::*; - -impl FromBytes for EpochChallenge { - /// Reads the epoch challenge from a buffer. - fn read_le(mut reader: R) -> IoResult { - // Read the epoch number. - let epoch_number = FromBytes::read_le(&mut reader)?; - // Read the epoch block hash. - let epoch_block_hash = FromBytes::read_le(&mut reader)?; - // Read the epoch degree. - let degree = FromBytes::read_le(&mut reader)?; - // Return the epoch challenge. - Self::new(epoch_number, epoch_block_hash, degree).map_err(|e| error(e.to_string())) - } -} - -impl ToBytes for EpochChallenge { - /// Writes the epoch challenge to a buffer. - fn write_le(&self, mut writer: W) -> IoResult<()> { - // Write the epoch number. - self.epoch_number.write_le(&mut writer)?; - // Write the epoch block hash. - self.epoch_block_hash.write_le(&mut writer)?; - // Write the epoch degree. - self.degree().write_le(&mut writer) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use console::network::Testnet3; - - use rand::RngCore; - - type CurrentNetwork = Testnet3; - - const ITERATIONS: usize = 100; - - #[test] - fn test_bytes() { - let mut rng = TestRng::default(); - - for _ in 0..ITERATIONS { - // Sample a new epoch challenge. - let degree: u16 = rng.gen(); // Bound the maximal test degree to 2^16. - let expected = EpochChallenge::::new(rng.next_u32(), rng.gen(), degree as u32).unwrap(); - - // Check the byte representation. - let expected_bytes = expected.to_bytes_le().unwrap(); - let candidate = EpochChallenge::read_le(&expected_bytes[..]).unwrap(); - assert_eq!(expected.epoch_number(), candidate.epoch_number()); - assert_eq!(expected.epoch_block_hash(), candidate.epoch_block_hash()); - assert_eq!(expected.degree(), candidate.degree()); - assert_eq!(expected, candidate); - - assert!(EpochChallenge::::read_le(&expected_bytes[1..]).is_err()); - } - } -} diff --git a/ledger/coinbase/src/helpers/epoch_challenge/mod.rs b/ledger/coinbase/src/helpers/epoch_challenge/mod.rs deleted file mode 100644 index 9a9860cec8..0000000000 --- a/ledger/coinbase/src/helpers/epoch_challenge/mod.rs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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. - -mod bytes; - -use super::*; -use crate::hash_to_polynomial; -use snarkvm_algorithms::fft::Evaluations as EvaluationsOnDomain; - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct EpochChallenge { - /// The epoch number. - epoch_number: u32, - /// The epoch block hash, defined as the block hash right before the epoch updated. - epoch_block_hash: N::BlockHash, - /// The epoch polynomial. - epoch_polynomial: DensePolynomial<::Fr>, - /// The evaluations of the epoch polynomial over the product domain. - epoch_polynomial_evaluations: EvaluationsOnDomain<::Fr>, -} - -impl EpochChallenge { - /// Initializes a new epoch challenge. - pub fn new(epoch_number: u32, epoch_block_hash: N::BlockHash, degree: u32) -> Result { - // Construct the 'input' as '( epoch_number || epoch_block_hash )' - let mut input = vec![]; - epoch_number.write_le(&mut input)?; - epoch_block_hash.write_le(&mut input)?; - - let product_domain = CoinbasePuzzle::::product_domain(degree)?; - - let epoch_polynomial = hash_to_polynomial::<::Fr>(&input, degree); - ensure!(u32::try_from(epoch_polynomial.degree()).is_ok(), "Degree is too large"); - - let epoch_polynomial_evaluations = epoch_polynomial.evaluate_over_domain_by_ref(product_domain); - // Returns the epoch challenge. - Ok(EpochChallenge { epoch_number, epoch_block_hash, epoch_polynomial, epoch_polynomial_evaluations }) - } - - /// Returns the epoch number for the solution. - pub const fn epoch_number(&self) -> u32 { - self.epoch_number - } - - /// Returns the epoch block hash for the solution. - pub const fn epoch_block_hash(&self) -> N::BlockHash { - self.epoch_block_hash - } - - /// Returns the epoch polynomial for the solution. - pub const fn epoch_polynomial(&self) -> &DensePolynomial<::Fr> { - &self.epoch_polynomial - } - - /// Returns the evaluations of the epoch polynomial over the product domain. - pub const fn epoch_polynomial_evaluations(&self) -> &EvaluationsOnDomain<::Fr> { - &self.epoch_polynomial_evaluations - } - - /// Returns the number of coefficients of the epoch polynomial. - pub fn degree(&self) -> u32 { - // Convert the degree into a u32. - // The `unwrap` is guaranteed to succeed as we check the degree is less - // than `u32::MAX` in `new`. - u32::try_from(self.epoch_polynomial.degree()).unwrap() - } - - /// Returns the number of coefficients of the epoch polynomial. - pub fn num_coefficients(&self) -> Result { - let degree = self.degree(); - degree.checked_add(1).ok_or_else(|| anyhow!("Epoch polynomial degree ({degree} + 1) overflows")) - } -} diff --git a/ledger/coinbase/src/helpers/mod.rs b/ledger/coinbase/src/helpers/mod.rs deleted file mode 100644 index 10926b3366..0000000000 --- a/ledger/coinbase/src/helpers/mod.rs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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. - -mod coinbase_solution; -pub use coinbase_solution::*; - -mod epoch_challenge; -pub use epoch_challenge::*; - -mod partial_solution; -pub use partial_solution::*; - -mod prover_solution; -pub use prover_solution::*; - -mod puzzle_commitment; -pub use puzzle_commitment::*; - -use crate::{hash_commitment, hash_commitments, CoinbasePuzzle}; -use console::{account::Address, prelude::*, types::Field}; -use snarkvm_algorithms::{ - fft::{domain::FFTPrecomputation, DensePolynomial, EvaluationDomain}, - polycommit::kzg10::{KZGCommitment, KZGProof, LagrangeBasis, VerifierKey, KZG10}, -}; -use snarkvm_curves::PairingEngine; -use snarkvm_utilities::{FromBytes, ToBytes}; - -use anyhow::Result; -use std::{ - borrow::Cow, - io::{Read, Result as IoResult, Write}, -}; - -/// The proof of opening the polynomial, for the solution. -pub type PuzzleProof = KZGProof<::PairingCurve>; - -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct PuzzleConfig { - /// The maximum degree of the polynomial. - pub degree: u32, -} - -pub type CoinbaseVerifyingKey = VerifierKey<::PairingCurve>; - -#[derive(Clone, Debug)] -pub struct CoinbaseProvingKey { - /// The key used to commit to polynomials in Lagrange basis. - pub lagrange_basis_at_beta_g: Vec<::G1Affine>, - /// Domain used to compute the product of the epoch polynomial and the prover polynomial. - pub product_domain: EvaluationDomain<::Fr>, - /// Precomputation to speed up FFTs. - pub fft_precomputation: FFTPrecomputation<::Fr>, - /// Elements of the product domain. - pub product_domain_elements: Vec<::Fr>, - /// The verifying key of the coinbase puzzle. - pub verifying_key: CoinbaseVerifyingKey, -} - -impl CoinbaseProvingKey { - /// Obtain elements of the SRS in the lagrange basis powers. - pub fn lagrange_basis(&self) -> LagrangeBasis { - LagrangeBasis { - lagrange_basis_at_beta_g: Cow::Borrowed(self.lagrange_basis_at_beta_g.as_slice()), - powers_of_beta_times_gamma_g: Cow::Owned(vec![]), - domain: self.product_domain, - } - } - - /// Returns the elements of the product domain. - pub fn product_domain_elements(&self) -> &[::Fr] { - &self.product_domain_elements - } -} diff --git a/ledger/coinbase/src/helpers/partial_solution/mod.rs b/ledger/coinbase/src/helpers/partial_solution/mod.rs deleted file mode 100644 index 4fc078e310..0000000000 --- a/ledger/coinbase/src/helpers/partial_solution/mod.rs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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. - -mod bytes; -mod serialize; -mod string; - -use super::*; - -/// The partial solution for the coinbase puzzle from a prover. -#[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct PartialSolution { - /// The address of the prover. - address: Address, - /// The nonce for the solution. - nonce: u64, - /// The commitment for the solution. - commitment: PuzzleCommitment, -} - -impl PartialSolution { - /// Initializes a new instance of the partial solution. - pub fn new>>(address: Address, nonce: u64, commitment: C) -> Self { - Self { address, nonce, commitment: commitment.into() } - } - - /// Returns the address of the prover. - pub const fn address(&self) -> Address { - self.address - } - - /// Returns the nonce for the solution. - pub const fn nonce(&self) -> u64 { - self.nonce - } - - /// Returns the commitment for the solution. - pub const fn commitment(&self) -> PuzzleCommitment { - self.commitment - } - - /// Returns the prover polynomial. - pub fn to_prover_polynomial( - &self, - epoch_challenge: &EpochChallenge, - ) -> Result::Fr>> { - CoinbasePuzzle::prover_polynomial(epoch_challenge, self.address(), self.nonce()) - } - - /// Returns the target of the solution. - pub fn to_target(&self) -> Result { - self.commitment.to_target() - } -} diff --git a/ledger/coinbase/src/helpers/prover_solution/mod.rs b/ledger/coinbase/src/helpers/prover_solution/mod.rs deleted file mode 100644 index 548ba3773f..0000000000 --- a/ledger/coinbase/src/helpers/prover_solution/mod.rs +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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. - -mod bytes; -mod serialize; -mod string; - -use super::*; - -/// The prover solution for the coinbase puzzle from a prover. -#[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct ProverSolution { - /// The core data of the prover solution. - partial_solution: PartialSolution, - /// The proof for the solution. - proof: PuzzleProof, -} - -impl ProverSolution { - /// Initializes a new instance of the prover solution. - pub const fn new(partial_solution: PartialSolution, proof: PuzzleProof) -> Self { - Self { partial_solution, proof } - } - - /// Returns `true` if the prover solution is valid. - pub fn verify( - &self, - verifying_key: &CoinbaseVerifyingKey, - epoch_challenge: &EpochChallenge, - proof_target: u64, - ) -> Result { - // Ensure the proof is non-hiding. - if self.proof.is_hiding() { - return Ok(false); - } - - // Ensure that the prover solution is greater than the proof target. - if self.to_target()? < proof_target { - bail!("Prover puzzle does not meet the proof target requirements.") - } - - // Compute the prover polynomial. - let prover_polynomial = self.partial_solution.to_prover_polynomial(epoch_challenge)?; - - // Compute the challenge point. - let challenge_point = hash_commitment(&self.commitment())?; - - // Evaluate the epoch and prover polynomials at the challenge point. - let epoch_evaluation = epoch_challenge.epoch_polynomial().evaluate(challenge_point); - let prover_evaluation = prover_polynomial.evaluate(challenge_point); - - // Compute the claimed value by multiplying the evaluations. - let claimed_value = epoch_evaluation * prover_evaluation; - - // Check the KZG proof. - Ok(KZG10::check(verifying_key, &self.commitment(), challenge_point, claimed_value, self.proof())?) - } - - /// Returns the address of the prover. - pub const fn address(&self) -> Address { - self.partial_solution.address() - } - - /// Returns the nonce for the solution. - pub const fn nonce(&self) -> u64 { - self.partial_solution.nonce() - } - - /// Returns the commitment for the solution. - pub const fn commitment(&self) -> PuzzleCommitment { - self.partial_solution.commitment() - } - - /// Returns the proof for the solution. - pub const fn proof(&self) -> &PuzzleProof { - &self.proof - } - - /// Returns the prover polynomial. - pub fn to_prover_polynomial( - &self, - epoch_challenge: &EpochChallenge, - ) -> Result::Fr>> { - self.partial_solution.to_prover_polynomial(epoch_challenge) - } - - /// Returns the target of the solution. - pub fn to_target(&self) -> Result { - self.partial_solution.to_target() - } -} diff --git a/ledger/coinbase/src/helpers/puzzle_commitment/mod.rs b/ledger/coinbase/src/helpers/puzzle_commitment/mod.rs deleted file mode 100644 index b4b14414ec..0000000000 --- a/ledger/coinbase/src/helpers/puzzle_commitment/mod.rs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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. - -mod bytes; -mod serialize; -mod string; - -pub use string::PUZZLE_COMMITMENT_PREFIX; - -use super::*; -use snarkvm_algorithms::crypto_hash::sha256d_to_u64; - -/// A coinbase puzzle commitment to a polynomial. -#[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct PuzzleCommitment { - /// The commitment for the solution. - commitment: KZGCommitment<::PairingCurve>, -} - -impl PuzzleCommitment { - /// Initializes a new instance of the puzzle commitment. - pub const fn new(commitment: KZGCommitment<::PairingCurve>) -> Self { - Self { commitment } - } - - /// Initializes a new instance of the puzzle commitment. - pub fn from_g1_affine(commitment: <::PairingCurve as PairingEngine>::G1Affine) -> Self { - Self::from(KZGCommitment(commitment)) - } - - /// Returns the proof target. - pub fn to_target(&self) -> Result { - let hash_to_u64 = sha256d_to_u64(&self.commitment.to_bytes_le()?); - if hash_to_u64 == 0 { Ok(u64::MAX) } else { Ok(u64::MAX / hash_to_u64) } - } -} - -impl From::PairingCurve>> for PuzzleCommitment { - /// Initializes a new instance of the puzzle commitment. - fn from(commitment: KZGCommitment<::PairingCurve>) -> Self { - Self::new(commitment) - } -} - -impl Default for PuzzleCommitment { - fn default() -> Self { - Self::new(KZGCommitment::empty()) - } -} - -impl Deref for PuzzleCommitment { - type Target = KZGCommitment<::PairingCurve>; - - fn deref(&self) -> &Self::Target { - &self.commitment - } -} diff --git a/ledger/coinbase/src/helpers/puzzle_commitment/string.rs b/ledger/coinbase/src/helpers/puzzle_commitment/string.rs deleted file mode 100644 index d01cac5802..0000000000 --- a/ledger/coinbase/src/helpers/puzzle_commitment/string.rs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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 super::*; - -pub static PUZZLE_COMMITMENT_PREFIX: &str = "puzzle"; - -impl FromStr for PuzzleCommitment { - type Err = Error; - - /// Reads in the puzzle commitment string. - fn from_str(puzzle_commitment: &str) -> Result { - // Decode the puzzle commitment string from bech32m. - let (hrp, data, variant) = bech32::decode(puzzle_commitment)?; - if hrp != PUZZLE_COMMITMENT_PREFIX { - bail!("Failed to decode puzzle commitment: '{hrp}' is an invalid prefix") - } else if data.is_empty() { - bail!("Failed to decode puzzle commitment: data field is empty") - } else if variant != bech32::Variant::Bech32m { - bail!("Found a puzzle commitment that is not bech32m encoded: {puzzle_commitment}"); - } - // Decode the puzzle commitment data from u5 to u8, and into the puzzle commitment. - Ok(Self::read_le(&Vec::from_base32(&data)?[..])?) - } -} - -impl Debug for PuzzleCommitment { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - Display::fmt(self, f) - } -} - -impl Display for PuzzleCommitment { - /// Writes the puzzle commitment as a bech32m string. - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - // Convert the puzzle commitment to bytes. - let bytes = self.to_bytes_le().map_err(|_| fmt::Error)?; - // Encode the bytes into bech32m. - let string = bech32::encode(PUZZLE_COMMITMENT_PREFIX, bytes.to_base32(), bech32::Variant::Bech32m) - .map_err(|_| fmt::Error)?; - // Output the string. - Display::fmt(&string, f) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use console::network::Testnet3; - - type CurrentNetwork = Testnet3; - - const ITERATIONS: u64 = 1_000; - - #[test] - fn test_string() -> Result<()> { - // Ensure type and empty value fails. - assert!(PuzzleCommitment::::from_str(&format!("{PUZZLE_COMMITMENT_PREFIX}1")).is_err()); - assert!(PuzzleCommitment::::from_str("").is_err()); - - let mut rng = TestRng::default(); - - for _ in 0..ITERATIONS { - // Sample a new puzzle commitment. - let expected = PuzzleCommitment::::new(KZGCommitment(rng.gen())); - - // Check the string representation. - let candidate = format!("{expected}"); - assert_eq!(expected, PuzzleCommitment::from_str(&candidate)?); - assert_eq!(PUZZLE_COMMITMENT_PREFIX, candidate.to_string().split('1').next().unwrap()); - } - Ok(()) - } - - #[test] - fn test_display() -> Result<()> { - let mut rng = TestRng::default(); - - for _ in 0..ITERATIONS { - // Sample a new puzzle commitment. - let expected = PuzzleCommitment::::new(KZGCommitment(rng.gen())); - - let candidate = expected.to_string(); - assert_eq!(format!("{expected}"), candidate); - assert_eq!(PUZZLE_COMMITMENT_PREFIX, candidate.split('1').next().unwrap()); - - let candidate_recovered = PuzzleCommitment::::from_str(&candidate.to_string())?; - assert_eq!(expected, candidate_recovered); - } - Ok(()) - } -} diff --git a/ledger/coinbase/src/lib.rs b/ledger/coinbase/src/lib.rs deleted file mode 100644 index c3016e150b..0000000000 --- a/ledger/coinbase/src/lib.rs +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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. - -#![forbid(unsafe_code)] -#![allow(clippy::too_many_arguments)] -#![warn(clippy::cast_possible_truncation)] - -mod helpers; -pub use helpers::*; - -mod hash; -use hash::*; - -#[cfg(test)] -mod tests; - -use console::{ - account::Address, - prelude::{anyhow, bail, cfg_iter, ensure, has_duplicates, Network, Result, ToBytes}, -}; -use snarkvm_algorithms::{ - fft::{DensePolynomial, EvaluationDomain}, - polycommit::kzg10::{UniversalParams as SRS, KZG10}, -}; -use snarkvm_curves::PairingEngine; -use snarkvm_fields::Zero; -use snarkvm_synthesizer_snark::UniversalSRS; - -use aleo_std::prelude::*; -use std::sync::Arc; - -#[cfg(not(feature = "serial"))] -use rayon::prelude::*; - -#[derive(Clone)] -pub enum CoinbasePuzzle { - /// The prover contains the coinbase puzzle proving key. - Prover(Arc>), - /// The verifier contains the coinbase puzzle verifying key. - Verifier(Arc>), -} - -impl CoinbasePuzzle { - /// Initializes a new `SRS` for the coinbase puzzle. - #[cfg(any(test, feature = "setup"))] - pub fn setup(config: PuzzleConfig) -> Result> { - // The SRS must support committing to the product of two degree `n` polynomials. - // Thus, the SRS must support committing to a polynomial of degree `2n - 1`. - let total_degree = (2 * config.degree - 1).try_into()?; - let srs = KZG10::load_srs(total_degree)?; - Ok(srs) - } - - /// Load the coinbase puzzle proving and verifying keys. - pub fn load() -> Result { - let max_degree = N::COINBASE_PUZZLE_DEGREE; - // Load the universal SRS. - let universal_srs = UniversalSRS::::load()?; - // Trim the universal SRS to the maximum degree. - Self::trim(&*universal_srs, PuzzleConfig { degree: max_degree }) - } - - pub fn trim(srs: &SRS, config: PuzzleConfig) -> Result { - // As above, we must support committing to the product of two degree `n` polynomials. - // Thus, the SRS must support committing to a polynomial of degree `2n - 1`. - // Since the upper bound to `srs.powers_of_beta_g` takes as input the number - // of coefficients. The degree of the product has `2n - 1` coefficients. - // - // Hence, we request the powers of beta for the interval [0, 2n]. - let product_domain = Self::product_domain(config.degree)?; - - let lagrange_basis_at_beta_g = srs.lagrange_basis(product_domain)?; - let fft_precomputation = product_domain.precompute_fft(); - let product_domain_elements = product_domain.elements().collect(); - - let vk = CoinbaseVerifyingKey:: { - g: srs.power_of_beta_g(0)?, - gamma_g: ::G1Affine::zero(), // We don't use gamma_g later on since we are not hiding. - h: srs.h, - beta_h: srs.beta_h(), - prepared_h: srs.prepared_h.clone(), - prepared_beta_h: srs.prepared_beta_h.clone(), - }; - - let pk = CoinbaseProvingKey { - product_domain, - product_domain_elements, - lagrange_basis_at_beta_g, - fft_precomputation, - verifying_key: vk, - }; - - Ok(Self::Prover(Arc::new(pk))) - } - - /// Returns a prover solution to the coinbase puzzle. - pub fn prove( - &self, - epoch_challenge: &EpochChallenge, - address: Address, - nonce: u64, - minimum_proof_target: Option, - ) -> Result> { - // Retrieve the coinbase proving key. - let pk = match self { - Self::Prover(coinbase_proving_key) => coinbase_proving_key, - Self::Verifier(_) => bail!("Cannot prove the coinbase puzzle with a verifier"), - }; - - let polynomial = Self::prover_polynomial(epoch_challenge, address, nonce)?; - - let product_evaluations = { - let polynomial_evaluations = pk.product_domain.in_order_fft_with_pc(&polynomial, &pk.fft_precomputation); - pk.product_domain.mul_polynomials_in_evaluation_domain( - polynomial_evaluations, - &epoch_challenge.epoch_polynomial_evaluations().evaluations, - )? - }; - let (commitment, _rand) = KZG10::commit_lagrange(&pk.lagrange_basis(), &product_evaluations, None, None)?; - - let partial_solution = PartialSolution::new(address, nonce, commitment); - - // Check that the minimum target is met. - if let Some(minimum_target) = minimum_proof_target { - let proof_target = partial_solution.to_target()?; - ensure!( - proof_target >= minimum_target, - "Prover solution was below the necessary proof target ({proof_target} < {minimum_target})" - ); - } - - let point = hash_commitment(&commitment)?; - let product_eval_at_point = polynomial.evaluate(point) * epoch_challenge.epoch_polynomial().evaluate(point); - - let proof = KZG10::open_lagrange( - &pk.lagrange_basis(), - pk.product_domain_elements(), - &product_evaluations, - point, - product_eval_at_point, - )?; - ensure!(!proof.is_hiding(), "The prover solution must contain a non-hiding proof"); - - debug_assert!(KZG10::check(&pk.verifying_key, &commitment, point, product_eval_at_point, &proof)?); - - Ok(ProverSolution::new(partial_solution, proof)) - } - - /// Returns `true` if the solutions are valid. - pub fn check_solutions( - &self, - solutions: &CoinbaseSolution, - epoch_challenge: &EpochChallenge, - proof_target: u64, - ) -> Result<()> { - let timer = timer!("CoinbasePuzzle::verify"); - - // Ensure the solutions are not empty. - ensure!(!solutions.is_empty(), "There are no solutions to verify for the coinbase puzzle"); - - // Ensure the number of partial solutions does not exceed `MAX_PROVER_SOLUTIONS`. - if solutions.len() > N::MAX_SOLUTIONS { - bail!( - "The solutions exceed the allowed number of partial solutions. ({} > {})", - solutions.len(), - N::MAX_SOLUTIONS - ); - } - - // Ensure the puzzle commitments are unique. - if has_duplicates(solutions.puzzle_commitments()) { - bail!("The solutions contain duplicate puzzle commitments"); - } - lap!(timer, "Perform initial checks"); - - // Verify each prover solution. - if !cfg_iter!(solutions).all(|(_, solution)| { - solution.verify(self.coinbase_verifying_key(), epoch_challenge, proof_target).unwrap_or(false) - }) { - bail!("The solutions contain an invalid prover solution"); - } - finish!(timer, "Verify each solution"); - - Ok(()) - } - - /// Returns the coinbase proving key. - pub fn coinbase_proving_key(&self) -> Result<&CoinbaseProvingKey> { - match self { - Self::Prover(coinbase_proving_key) => Ok(coinbase_proving_key), - Self::Verifier(_) => bail!("Cannot fetch the coinbase proving key with a verifier"), - } - } - - /// Returns the coinbase verifying key. - pub fn coinbase_verifying_key(&self) -> &CoinbaseVerifyingKey { - match self { - Self::Prover(coinbase_proving_key) => &coinbase_proving_key.verifying_key, - Self::Verifier(coinbase_verifying_key) => coinbase_verifying_key, - } - } -} - -impl CoinbasePuzzle { - /// Checks that the degree for the epoch and prover polynomial is within bounds, - /// and returns the evaluation domain for the product polynomial. - pub(crate) fn product_domain(degree: u32) -> Result> { - ensure!(degree != 0, "Degree cannot be zero"); - let num_coefficients = degree.checked_add(1).ok_or_else(|| anyhow!("Degree is too large"))?; - let product_num_coefficients = num_coefficients - .checked_mul(2) - .and_then(|t| t.checked_sub(1)) - .ok_or_else(|| anyhow!("Degree is too large"))?; - assert_eq!(product_num_coefficients, 2 * degree + 1); - let product_domain = - EvaluationDomain::new(product_num_coefficients.try_into()?).ok_or_else(|| anyhow!("Invalid degree"))?; - assert_eq!(product_domain.size(), (product_num_coefficients as usize).checked_next_power_of_two().unwrap()); - Ok(product_domain) - } - - /// Returns the prover polynomial for the coinbase puzzle. - fn prover_polynomial( - epoch_challenge: &EpochChallenge, - address: Address, - nonce: u64, - ) -> Result::Fr>> { - let input = { - let mut bytes = [0u8; 76]; - epoch_challenge.epoch_number().write_le(&mut bytes[..4])?; - epoch_challenge.epoch_block_hash().write_le(&mut bytes[4..36])?; - address.write_le(&mut bytes[36..68])?; - nonce.write_le(&mut bytes[68..])?; - - bytes - }; - Ok(hash_to_polynomial::<::Fr>(&input, epoch_challenge.degree())) - } -} diff --git a/ledger/coinbase/src/tests.rs b/ledger/coinbase/src/tests.rs deleted file mode 100644 index 15a39fc6a3..0000000000 --- a/ledger/coinbase/src/tests.rs +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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 super::*; -use console::{account::*, network::Testnet3}; -use snarkvm_utilities::Uniform; - -use rand::RngCore; - -const ITERATIONS: u64 = 100; - -#[test] -fn test_coinbase_puzzle() { - let mut rng = TestRng::default(); - - let max_degree = 1 << 15; - let max_config = PuzzleConfig { degree: max_degree }; - let srs = CoinbasePuzzle::::setup(max_config).unwrap(); - - for log_degree in 5..10 { - let degree = (1 << log_degree) - 1; - let config = PuzzleConfig { degree }; - let puzzle = CoinbasePuzzle::::trim(&srs, config).unwrap(); - let epoch_challenge = EpochChallenge::new(rng.next_u32(), Default::default(), degree).unwrap(); - - for batch_size in 1..10 { - let solutions = (0..batch_size) - .map(|_| { - let private_key = PrivateKey::::new(&mut rng).unwrap(); - let address = Address::try_from(private_key).unwrap(); - let nonce = u64::rand(&mut rng); - puzzle.prove(&epoch_challenge, address, nonce, None).unwrap() - }) - .collect::>(); - let full_solution = CoinbaseSolution::new(solutions).unwrap(); - assert!(puzzle.check_solutions(&full_solution, &epoch_challenge, 0u64).is_ok()); - - let bad_epoch_challenge = EpochChallenge::new(rng.next_u32(), Default::default(), degree).unwrap(); - assert!(puzzle.check_solutions(&full_solution, &bad_epoch_challenge, 0u64).is_err()); - } - } -} - -#[test] -fn test_prover_solution_minimum_target() { - let mut rng = TestRng::default(); - - let max_degree = 1 << 15; - let max_config = PuzzleConfig { degree: max_degree }; - let srs = CoinbasePuzzle::::setup(max_config).unwrap(); - - for log_degree in 5..10 { - let degree = (1 << log_degree) - 1; - let config = PuzzleConfig { degree }; - let puzzle = CoinbasePuzzle::::trim(&srs, config).unwrap(); - let epoch_challenge = EpochChallenge::new(rng.next_u32(), Default::default(), degree).unwrap(); - - for _ in 0..ITERATIONS { - let private_key = PrivateKey::::new(&mut rng).unwrap(); - let address = Address::try_from(private_key).unwrap(); - let nonce = u64::rand(&mut rng); - - let solution = puzzle.prove(&epoch_challenge, address, nonce, None).unwrap(); - let proof_target = solution.to_target().unwrap(); - - // Assert that the operation will pass if the minimum target is low enough. - assert!(puzzle.prove(&epoch_challenge, address, nonce, Some(proof_target.saturating_sub(1))).is_ok()); - - // Assert that the operation will fail if the minimum target is too high. - assert!(puzzle.prove(&epoch_challenge, address, nonce, Some(proof_target.saturating_add(1))).is_err()); - } - } -} - -#[test] -fn test_edge_case_for_degree() { - let mut rng = rand::thread_rng(); - - // Generate srs. - let max_degree = 1 << 15; - let max_config = PuzzleConfig { degree: max_degree }; - let srs = CoinbasePuzzle::::setup(max_config).unwrap(); - - // Generate PK and VK. - let degree = (1 << 13) - 1; - let puzzle = CoinbasePuzzle::::trim(&srs, PuzzleConfig { degree }).unwrap(); - - // Generate proof inputs - let private_key = PrivateKey::::new(&mut rng).unwrap(); - let address = Address::try_from(private_key).unwrap(); - let epoch_challenge = EpochChallenge::new(rng.gen(), Default::default(), degree).unwrap(); - - // Generate a prover solution. - let prover_solution = puzzle.prove(&epoch_challenge, address, rng.gen(), None).unwrap(); - let coinbase_solution = CoinbaseSolution::new(vec![prover_solution]).unwrap(); - assert!(puzzle.check_solutions(&coinbase_solution, &epoch_challenge, 0u64).is_ok()); -} - -/// Use `cargo test profiler --features timer` to run this test. -#[ignore] -#[test] -fn test_profiler() -> Result<()> { - fn sample_address_and_nonce(rng: &mut (impl CryptoRng + RngCore)) -> (Address, u64) { - let private_key = PrivateKey::new(rng).unwrap(); - let address = Address::try_from(private_key).unwrap(); - let nonce = rng.next_u64(); - (address, nonce) - } - - let mut rng = rand::thread_rng(); - - // Generate srs. - let max_degree = 1 << 15; - let max_config = PuzzleConfig { degree: max_degree }; - let universal_srs = CoinbasePuzzle::::setup(max_config).unwrap(); - - // Generate PK and VK. - let degree = (1 << 13) - 1; - let config = PuzzleConfig { degree }; - let puzzle = CoinbasePuzzle::trim(&universal_srs, config).unwrap(); - - // Generate proof inputs - let epoch_challenge = EpochChallenge::new(rng.next_u32(), Default::default(), degree).unwrap(); - - for batch_size in [10, 100, ::MAX_SOLUTIONS] { - // Generate the solutions. - let solutions = (0..batch_size) - .map(|_| { - let (address, nonce) = sample_address_and_nonce(&mut rng); - puzzle.prove(&epoch_challenge, address, nonce, None).unwrap() - }) - .collect::>(); - // Construct the solutions. - let solutions = CoinbaseSolution::new(solutions).unwrap(); - // Verify the solutions. - puzzle.check_solutions(&solutions, &epoch_challenge, 0u64).unwrap(); - } - - bail!("\n\nRemember to #[ignore] this test!\n\n") -} diff --git a/ledger/committee/Cargo.toml b/ledger/committee/Cargo.toml index 787714e5ac..12558b107b 100644 --- a/ledger/committee/Cargo.toml +++ b/ledger/committee/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-committee" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A committee for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -24,7 +24,7 @@ license = "Apache-2.0" edition = "2021" [features] -default = [ ] +default = [ "rayon" ] serial = [ "console/serial" ] wasm = [ "console/wasm" ] metrics = [ "dep:metrics" ] @@ -34,7 +34,12 @@ test-helpers = [ "prop-tests", "rand_distr" ] [dependencies.console] package = "snarkvm-console" path = "../../console" -version = "=0.16.19" +version = "=1.1.0" + +[dependencies.ledger-narwhal-batch-header] +package = "snarkvm-ledger-narwhal-batch-header" +path = "../narwhal/batch-header" +version = "=1.1.0" [dependencies.indexmap] version = "2.0" @@ -43,7 +48,7 @@ features = [ "serde", "rayon" ] [dependencies.metrics] package = "snarkvm-metrics" path = "../../metrics" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.serde_json] @@ -70,6 +75,10 @@ optional = true version = "0.4" optional = true +[dependencies.rayon] +version = "1" +optional = true + [dependencies.test-strategy] version = "0.3.1" optional = true @@ -86,10 +95,6 @@ version = "0.4" [dev-dependencies.rayon] version = "1" -[dev-dependencies.ledger-narwhal-batch-header] -package = "snarkvm-ledger-narwhal-batch-header" -path = "../narwhal/batch-header" - [dev-dependencies.snarkvm-ledger-committee] path = "." features = [ "prop-tests" ] diff --git a/ledger/committee/src/bytes.rs b/ledger/committee/src/bytes.rs index 2c3eba9771..85b3a4cd70 100644 --- a/ledger/committee/src/bytes.rs +++ b/ledger/committee/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,6 +25,8 @@ impl FromBytes for Committee { return Err(error("Invalid committee version")); } + // Read the committee ID. + let id = Field::read_le(&mut reader)?; // Read the starting round. let starting_round = u64::read_le(&mut reader)?; // Read the number of members. @@ -35,22 +38,36 @@ impl FromBytes for Committee { Self::MAX_COMMITTEE_SIZE, ))); } + + // Calculate the number of bytes per member. Each member is a (address, stake, is_open, commission) tuple. + let member_byte_size = Address::::size_in_bytes() + 8 + 1 + 1; + // Read the member bytes. + let mut member_bytes = vec![0u8; num_members as usize * member_byte_size]; + reader.read_exact(&mut member_bytes)?; // Read the members. - let mut members = IndexMap::with_capacity(num_members as usize); - for _ in 0..num_members { - // Read the address. - let member = Address::read_le(&mut reader)?; - // Read the stake. - let stake = u64::read_le(&mut reader)?; - // Read the is_open flag. - let is_open = bool::read_le(&mut reader)?; - // Insert the member and (stake, is_open). - members.insert(member, (stake, is_open)); - } + let members = cfg_chunks!(member_bytes, member_byte_size) + .map(|mut bytes| { + // Read the address. + let member = Address::::read_le(&mut bytes)?; + // Read the stake. + let stake = u64::read_le(&mut bytes)?; + // Read the is_open flag. + let is_open = bool::read_le(&mut bytes)?; + // Read the commission. + let commission = u8::read_le(&mut bytes)?; + // Insert the member and (stake, is_open). + Ok((member, (stake, is_open, commission))) + }) + .collect::, std::io::Error>>()?; + // Read the total stake. let total_stake = u64::read_le(&mut reader)?; // Construct the committee. let committee = Self::new(starting_round, members).map_err(|e| error(e.to_string()))?; + // Ensure the committee ID matches. + if committee.id() != id { + return Err(error("Invalid committee ID during deserialization")); + } // Ensure the total stake matches. match committee.total_stake() == total_stake { true => Ok(committee), @@ -64,18 +81,22 @@ impl ToBytes for Committee { fn write_le(&self, mut writer: W) -> IoResult<()> { // Write the version. 1u8.write_le(&mut writer)?; + // Write the committee ID. + self.id().write_le(&mut writer)?; // Write the starting round. self.starting_round.write_le(&mut writer)?; // Write the number of members. u16::try_from(self.members.len()).map_err(|e| error(e.to_string()))?.write_le(&mut writer)?; // Write the members. - for (address, (stake, is_open)) in &self.members { + for (address, (stake, is_open, commission)) in &self.members { // Write the address. address.write_le(&mut writer)?; // Write the stake. stake.write_le(&mut writer)?; // Write the is_open flag. is_open.write_le(&mut writer)?; + // Write the commission. + commission.write_le(&mut writer)?; } // Write the total stake. self.total_stake.write_le(&mut writer) diff --git a/ledger/committee/src/lib.rs b/ledger/committee/src/lib.rs index 9ba7843dcd..206968fc33 100644 --- a/ledger/committee/src/lib.rs +++ b/ledger/committee/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,6 +19,7 @@ mod bytes; mod serialize; mod string; +mod to_id; #[cfg(any(test, feature = "prop-tests"))] pub mod prop_tests; @@ -27,37 +29,49 @@ use console::{ program::{Literal, LiteralType}, types::{Address, Field}, }; +use ledger_narwhal_batch_header::BatchHeader; use indexmap::IndexMap; use std::collections::HashSet; +#[cfg(not(feature = "serial"))] +use rayon::prelude::*; + +/// The minimum self bond for a validator to join the committee +pub const MIN_VALIDATOR_SELF_STAKE: u64 = 100_000_000u64; // microcredits /// The minimum amount of stake required for a validator to bond. -pub const MIN_VALIDATOR_STAKE: u64 = 1_000_000_000_000u64; // microcredits +pub const MIN_VALIDATOR_STAKE: u64 = 10_000_000_000_000u64; // microcredits /// The minimum amount of stake required for a delegator to bond. -pub const MIN_DELEGATOR_STAKE: u64 = 10_000_000u64; // microcredits +pub const MIN_DELEGATOR_STAKE: u64 = 10_000_000_000u64; // microcredits +/// The maximum number of delegators. +pub const MAX_DELEGATORS: u32 = 100_000u32; #[derive(Clone, PartialEq, Eq)] pub struct Committee { + /// The committee ID, defined as the hash of the starting round, members, and total stake. + id: Field, /// The starting round number for this committee. starting_round: u64, - /// A map of `address` to `(stake, is_open)` state. - members: IndexMap, (u64, bool)>, + /// A map of `address` to `(stake, is_open, commission)` state. + members: IndexMap, (u64, bool, u8)>, /// The total stake of all `members`. total_stake: u64, } impl Committee { + /// The committee lookback range. + pub const COMMITTEE_LOOKBACK_RANGE: u64 = BatchHeader::::MAX_GC_ROUNDS as u64; /// The maximum number of members that may be in a committee. - pub const MAX_COMMITTEE_SIZE: u16 = 200; + pub const MAX_COMMITTEE_SIZE: u16 = BatchHeader::::MAX_CERTIFICATES; /// Initializes a new `Committee` instance. - pub fn new_genesis(members: IndexMap, (u64, bool)>) -> Result { + pub fn new_genesis(members: IndexMap, (u64, bool, u8)>) -> Result { // Return the new committee. Self::new(0u64, members) } /// Initializes a new `Committee` instance. - pub fn new(starting_round: u64, members: IndexMap, (u64, bool)>) -> Result { + pub fn new(starting_round: u64, members: IndexMap, (u64, bool, u8)>) -> Result { // Ensure there are at least 3 members. ensure!(members.len() >= 3, "Committee must have at least 3 members"); // Ensure there are no more than the maximum number of members. @@ -68,26 +82,38 @@ impl Committee { ); // Ensure all members have the minimum required stake. ensure!( - members.values().all(|(stake, _)| *stake >= MIN_VALIDATOR_STAKE), + members.values().all(|(stake, _, _)| *stake >= MIN_VALIDATOR_STAKE), "All members must have at least {MIN_VALIDATOR_STAKE} microcredits in stake" ); + // Ensure all members have a commission percentage within 100%. + ensure!( + members.values().all(|(_, _, commission)| *commission <= 100), + "All members must have a commission percentage less than or equal to 100" + ); // Compute the total stake of the committee for this round. let total_stake = Self::compute_total_stake(&members)?; + // Compute the committee ID. + let id = Self::compute_committee_id(starting_round, &members, total_stake)?; #[cfg(feature = "metrics")] metrics::gauge(metrics::committee::TOTAL_STAKE, total_stake as f64); // Return the new committee. - Ok(Self { starting_round, members, total_stake }) + Ok(Self { id, starting_round, members, total_stake }) } } impl Committee { + /// Returns the committee ID. + pub const fn id(&self) -> Field { + self.id + } + /// Returns the starting round number for this committee. pub const fn starting_round(&self) -> u64 { self.starting_round } /// Returns the committee members alongside their stake. - pub const fn members(&self) -> &IndexMap, (u64, bool)> { + pub const fn members(&self) -> &IndexMap, (u64, bool, u8)> { &self.members } @@ -144,14 +170,15 @@ impl Committee { self.total_stake().saturating_add(2).saturating_div(3) } - /// Returns the amount of stake required to reach a quorum threshold `(2f + 1)`. + /// Returns the amount of stake required to reach a quorum threshold `(N - f)`. pub fn quorum_threshold(&self) -> u64 { // Assuming `N = 3f + 1 + k`, where `0 <= k < 3`, - // then `(2N + 3) / 3 = 2f + 1 + (2k + 2)/3 = 2f + 1 + k = N - f`. + // then `2N/3 + 1 = 2f + 1 + (2k + 2)/3 = 2f + 1 + k = N - f`. + // In the line above, `/` means integer division. self.total_stake().saturating_mul(2).saturating_div(3).saturating_add(1) } - /// Returns the total amount of stake in the committee `(3f + 1)`. + /// Returns the total amount of stake in the committee. pub const fn total_stake(&self) -> u64 { self.total_stake } @@ -166,7 +193,7 @@ impl Committee { // Retrieve the total stake of the committee. let total_stake = self.total_stake(); // Construct the round seed. - let seed = [self.starting_round, current_round, total_stake].map(Field::from_u64); + let seed = [current_round].map(Field::from_u64); // Hash the round seed. let hash = Literal::Field(N::hash_to_group_psd4(&seed)?.to_x_coordinate()); // Compute the stake index from the hash output. @@ -182,7 +209,7 @@ impl Committee { // Sort the committee members. let candidates = self.sorted_members(); // Determine the leader of the previous round. - for (candidate, (stake, _)) in candidates { + for (candidate, (stake, _, _)) in candidates { // Increment the current stake index by the candidate's stake. current_stake_index = current_stake_index.saturating_add(stake); // If the current stake index is greater than or equal to the stake index, @@ -196,25 +223,22 @@ impl Committee { Ok(leader.unwrap()) } - /// Returns the committee members sorted by stake in decreasing order. - /// For members with matching stakes, we further sort by their address' x-coordinate in decreasing order. + /// Returns the committee members sorted by their address' x-coordinate in decreasing order. /// Note: This ensures the method returns a deterministic result that is SNARK-friendly. - fn sorted_members(&self) -> indexmap::map::IntoIter, (u64, bool)> { + fn sorted_members(&self) -> indexmap::map::IntoIter, (u64, bool, u8)> { let members = self.members.clone(); - members.sorted_unstable_by(|address1, stake1, address2, stake2| { - // Sort by stake in decreasing order. - let cmp = stake2.cmp(stake1); - // If the stakes are equal, sort by x-coordinate in decreasing order. - if cmp == Ordering::Equal { address2.to_x_coordinate().cmp(&address1.to_x_coordinate()) } else { cmp } + // Note: The use of 'sorted_unstable_by' is safe here because the addresses are guaranteed to be unique. + members.sorted_unstable_by(|address1, (_, _, _), address2, (_, _, _)| { + address2.to_x_coordinate().cmp(&address1.to_x_coordinate()) }) } } impl Committee { /// Compute the total stake of the given members. - fn compute_total_stake(members: &IndexMap, (u64, bool)>) -> Result { + fn compute_total_stake(members: &IndexMap, (u64, bool, u8)>) -> Result { let mut power = 0u64; - for (stake, _) in members.values() { + for (stake, _, _) in members.values() { // Accumulate the stake, checking for overflow. power = match power.checked_add(*stake) { Some(power) => power, @@ -233,7 +257,7 @@ pub mod test_helpers { use indexmap::IndexMap; use rand_distr::{Distribution, Exp}; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; /// Samples a list of random committees. pub fn sample_committees(rng: &mut TestRng) -> Vec> { @@ -248,6 +272,23 @@ pub mod test_helpers { sample_committee_for_round(1, rng) } + /// Samples a random committee with random commissions. + pub fn sample_committee_with_commissions(rng: &mut TestRng) -> Committee { + // Sample the members. + let mut members = IndexMap::new(); + for index in 0..4 { + let is_open = rng.gen(); + let commission = match index { + 0 => 0, + 1 => 100, + _ => rng.gen_range(0..=100), + }; + members.insert(Address::::new(rng.gen()), (2 * MIN_VALIDATOR_STAKE, is_open, commission)); + } + // Return the committee. + Committee::::new(1, members).unwrap() + } + /// Samples a random committee for a given round. pub fn sample_committee_for_round(round: u64, rng: &mut TestRng) -> Committee { sample_committee_for_round_and_size(round, 4, rng) @@ -263,7 +304,7 @@ pub mod test_helpers { let mut members = IndexMap::new(); for _ in 0..num_members { let is_open = rng.gen(); - members.insert(Address::::new(rng.gen()), (2 * MIN_VALIDATOR_STAKE, is_open)); + members.insert(Address::::new(rng.gen()), (2 * MIN_VALIDATOR_STAKE, is_open, 0)); } // Return the committee. Committee::::new(round, members).unwrap() @@ -279,12 +320,28 @@ pub mod test_helpers { let mut committee_members = IndexMap::new(); for member in members { let is_open = rng.gen(); - committee_members.insert(member, (2 * MIN_VALIDATOR_STAKE, is_open)); + committee_members.insert(member, (2 * MIN_VALIDATOR_STAKE, is_open, 0)); } // Return the committee. Committee::::new(round, committee_members).unwrap() } + /// Samples a committee where all validators have the same stake. + pub fn sample_committee_equal_stake_committee(num_members: u16, rng: &mut TestRng) -> Committee { + assert!(num_members >= 4); + // Sample the members. + let mut members = IndexMap::new(); + // Add in the minimum and maximum staked nodes. + members.insert(Address::::new(rng.gen()), (MIN_VALIDATOR_STAKE, false, 0)); + while members.len() < num_members as usize - 1 { + let stake = MIN_VALIDATOR_STAKE; + let is_open = rng.gen(); + members.insert(Address::::new(rng.gen()), (stake, is_open, 0)); + } + // Return the committee. + Committee::::new(1, members).unwrap() + } + /// Samples a random committee. #[allow(clippy::cast_possible_truncation)] pub fn sample_committee_custom(num_members: u16, rng: &mut TestRng) -> Committee { @@ -298,18 +355,18 @@ pub mod test_helpers { // Sample the members. let mut members = IndexMap::new(); // Add in the minimum and maximum staked nodes. - members.insert(Address::::new(rng.gen()), (MIN_VALIDATOR_STAKE, false)); + members.insert(Address::::new(rng.gen()), (MIN_VALIDATOR_STAKE, false, 0)); while members.len() < num_members as usize - 1 { loop { let stake = MIN_VALIDATOR_STAKE as f64 + range * distribution.sample(rng); if stake >= MIN_VALIDATOR_STAKE as f64 && stake <= MAX_STAKE as f64 { let is_open = rng.gen(); - members.insert(Address::::new(rng.gen()), (stake as u64, is_open)); + members.insert(Address::::new(rng.gen()), (stake as u64, is_open, 0)); break; } } } - members.insert(Address::::new(rng.gen()), (MAX_STAKE, false)); + members.insert(Address::::new(rng.gen()), (MAX_STAKE, false, 0)); // Return the committee. Committee::::new(1, members).unwrap() } @@ -321,17 +378,16 @@ mod tests { use console::prelude::TestRng; use parking_lot::RwLock; - use rayon::prelude::*; use std::sync::Arc; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; /// Checks the leader distribution. fn check_leader_distribution(committee: Committee, num_rounds: u64, tolerance_percent: f64) { // Initialize a tracker for the leaders. let leaders = Arc::new(RwLock::new(IndexMap::, i64>::new())); // Iterate through the rounds. - (1..=num_rounds).into_par_iter().for_each(|round| { + cfg_into_iter!(1..=num_rounds).for_each(|round| { // Compute the leader. let leader = committee.get_leader(round).unwrap(); // Increment the leader count for the current leader. @@ -339,7 +395,7 @@ mod tests { }); let leaders = leaders.read(); // Ensure the leader distribution is uniform. - for (i, (address, (stake, _))) in committee.members.iter().enumerate() { + for (i, (address, (stake, _, _))) in committee.members.iter().enumerate() { // Get the leader count for the validator. let Some(leader_count) = leaders.get(address) else { println!("{i}: 0 rounds"); @@ -380,7 +436,7 @@ mod tests { // Set the number of rounds. const NUM_ROUNDS: u64 = 256 * 2_000; // Sample the number of members. - let num_members = rng.gen_range(3..50); + let num_members = rng.gen_range(3..=Committee::::MAX_COMMITTEE_SIZE); // Sample a committee. let committee = crate::test_helpers::sample_committee_custom(num_members, rng); // Check the leader distribution. @@ -392,7 +448,8 @@ mod tests { // Initialize the RNG. let rng = &mut TestRng::default(); // Sample a committee. - let committee = crate::test_helpers::sample_committee_custom(200, rng); + let committee = + crate::test_helpers::sample_committee_custom(Committee::::MAX_COMMITTEE_SIZE, rng); // Start a timer. let timer = std::time::Instant::now(); @@ -401,20 +458,14 @@ mod tests { println!("sorted_members: {}ms", timer.elapsed().as_millis()); // Check that the members are sorted based on our sorting criteria. for i in 0..sorted_members.len() - 1 { - let (address1, (stake1, _)) = sorted_members[i]; - let (address2, (stake2, _)) = sorted_members[i + 1]; - assert!(stake1 >= stake2); - if stake1 == stake2 { - assert!(address1.to_x_coordinate() > address2.to_x_coordinate()); - } + let (address1, (_, _, _)) = sorted_members[i]; + let (address2, (_, _, _)) = sorted_members[i + 1]; + assert!(address1.to_x_coordinate() > address2.to_x_coordinate()); } } #[test] fn test_maximum_committee_size() { - assert_eq!( - Committee::::MAX_COMMITTEE_SIZE as usize, - ledger_narwhal_batch_header::BatchHeader::::MAX_CERTIFICATES - ); + assert_eq!(Committee::::MAX_COMMITTEE_SIZE, BatchHeader::::MAX_CERTIFICATES); } } diff --git a/ledger/committee/src/prop_tests.rs b/ledger/committee/src/prop_tests.rs index f0aa2e7bb2..7377165ec8 100644 --- a/ledger/committee/src/prop_tests.rs +++ b/ledger/committee/src/prop_tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,8 +19,8 @@ use console::account::PrivateKey; use anyhow::Result; use proptest::{ - collection::{hash_set, SizeRange}, - prelude::{any, Arbitrary, BoxedStrategy, Just, Strategy}, + collection::{SizeRange, hash_set}, + prelude::{Arbitrary, BoxedStrategy, Just, Strategy, any}, sample::size_range, }; use rand::SeedableRng; @@ -29,7 +30,7 @@ use std::{ }; use test_strategy::proptest; -type CurrentNetwork = console::network::Testnet3; +type CurrentNetwork = console::network::MainnetV0; #[derive(Debug, Clone)] pub struct Validator { @@ -37,6 +38,7 @@ pub struct Validator { pub address: Address, pub stake: u64, pub is_open: bool, + pub commission: u8, } impl Arbitrary for Validator { @@ -63,7 +65,7 @@ impl Hash for Validator { } fn to_committee((round, ValidatorSet(validators)): (u64, ValidatorSet)) -> Result> { - Committee::new(round, validators.iter().map(|v| (v.address, (v.stake, v.is_open))).collect()) + Committee::new(round, validators.iter().map(|v| (v.address, (v.stake, v.is_open, v.commission))).collect()) } #[derive(Debug, Clone)] @@ -112,7 +114,7 @@ impl Default for ValidatorSet { let rng = &mut rand_chacha::ChaChaRng::seed_from_u64(i); let private_key = PrivateKey::new(rng).unwrap(); let address = Address::try_from(private_key).unwrap(); - Validator { private_key, address, stake: MIN_VALIDATOR_STAKE, is_open: false } + Validator { private_key, address, stake: MIN_VALIDATOR_STAKE, is_open: false, commission: 0 } }) .collect(), ) @@ -130,10 +132,10 @@ impl Arbitrary for ValidatorSet { } pub fn any_valid_validator() -> BoxedStrategy { - (MIN_VALIDATOR_STAKE..100_000_000_000_000, any_valid_private_key(), any::()) - .prop_map(|(stake, private_key, is_open)| { + (MIN_VALIDATOR_STAKE..100_000_000_000_000, any_valid_private_key(), any::(), 0..100u8) + .prop_map(|(stake, private_key, is_open, commission)| { let address = Address::try_from(private_key).unwrap(); - Validator { private_key, address, stake, is_open } + Validator { private_key, address, stake, is_open, commission } }) .boxed() } @@ -159,10 +161,10 @@ fn too_low_stake_committee() -> BoxedStrategy>> #[allow(dead_code)] fn invalid_stake_validator() -> BoxedStrategy { - (0..MIN_VALIDATOR_STAKE, any_valid_private_key(), any::()) - .prop_map(|(stake, private_key, is_open)| { + (0..MIN_VALIDATOR_STAKE, any_valid_private_key(), any::(), 0..u8::MAX) + .prop_map(|(stake, private_key, is_open, commission)| { let address = Address::try_from(private_key).unwrap(); - Validator { private_key, address, stake, is_open } + Validator { private_key, address, stake, is_open, commission } }) .boxed() } @@ -185,7 +187,7 @@ fn committee_members(input: CommitteeContext) { } let quorum_threshold = committee.quorum_threshold(); let availability_threshold = committee.availability_threshold(); - // (2f + 1) + (f + 1) - 1 = 3f + 1 = N + // (N - f) + (f + 1) - 1 = N assert_eq!(quorum_threshold + availability_threshold - 1, total_stake); } @@ -193,7 +195,7 @@ fn committee_members(input: CommitteeContext) { fn invalid_stakes(#[strategy(too_low_stake_committee())] committee: Result>) { assert!(committee.is_err()); if let Err(err) = committee { - assert_eq!(err.to_string().as_str(), "All members must have at least 1000000000000 microcredits in stake"); + assert_eq!(err.to_string().as_str(), "All members must have at least 10000000000000 microcredits in stake"); } } diff --git a/ledger/committee/src/serialize.rs b/ledger/committee/src/serialize.rs index df121bd75a..3a8f72cdd5 100644 --- a/ledger/committee/src/serialize.rs +++ b/ledger/committee/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,7 +20,8 @@ impl Serialize for Committee { fn serialize(&self, serializer: S) -> Result { match serializer.is_human_readable() { true => { - let mut certificate = serializer.serialize_struct("Committee", 3)?; + let mut certificate = serializer.serialize_struct("Committee", 4)?; + certificate.serialize_field("id", &self.id)?; certificate.serialize_field("starting_round", &self.starting_round)?; certificate.serialize_field("members", &self.members)?; certificate.serialize_field("total_stake", &self.total_stake)?; @@ -36,12 +38,17 @@ impl<'de, N: Network> Deserialize<'de> for Committee { match deserializer.is_human_readable() { true => { let mut value = serde_json::Value::deserialize(deserializer)?; + let id: Field = DeserializeExt::take_from_value::(&mut value, "id")?; let total_stake: u64 = DeserializeExt::take_from_value::(&mut value, "total_stake")?; let committee = Self::new( DeserializeExt::take_from_value::(&mut value, "starting_round")?, DeserializeExt::take_from_value::(&mut value, "members")?, ) .map_err(de::Error::custom)?; + + if committee.id != id { + return Err(de::Error::custom("committee ID mismatch")); + } match committee.total_stake == total_stake { true => Ok(committee), false => Err(de::Error::custom("total stake mismatch")), diff --git a/ledger/committee/src/string.rs b/ledger/committee/src/string.rs index cb0572d65a..f11ceb796d 100644 --- a/ledger/committee/src/string.rs +++ b/ledger/committee/src/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/committee/src/to_id.rs b/ledger/committee/src/to_id.rs new file mode 100644 index 0000000000..92ab7f0dc8 --- /dev/null +++ b/ledger/committee/src/to_id.rs @@ -0,0 +1,53 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl Committee { + /// Returns the committee ID. + pub fn to_id(&self) -> Result> { + Self::compute_committee_id(self.starting_round, &self.members, self.total_stake) + } +} + +impl Committee { + /// Returns the commmitee ID. + pub fn compute_committee_id( + starting_round: u64, + members: &IndexMap, (u64, bool, u8)>, + total_stake: u64, + ) -> Result> { + let mut preimage = Vec::new(); + // Insert the starting_round. + starting_round.write_le(&mut preimage)?; + // Write the number of members. + u16::try_from(members.len())?.write_le(&mut preimage)?; + // Write the members. + for (address, (stake, is_open, commission)) in members { + // Write the address. + address.write_le(&mut preimage)?; + // Write the stake. + stake.write_le(&mut preimage)?; + // Write the is_open flag. + is_open.write_le(&mut preimage)?; + // Write the commission. + commission.write_le(&mut preimage)?; + } + // Insert the total stake. + total_stake.write_le(&mut preimage)?; + // Hash the preimage. + N::hash_bhp1024(&preimage.to_bits_le()) + } +} diff --git a/ledger/narwhal/Cargo.toml b/ledger/narwhal/Cargo.toml index f1b5238232..f5f3a2722b 100644 --- a/ledger/narwhal/Cargo.toml +++ b/ledger/narwhal/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-narwhal" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Data structures for a Narwhal-style memory pool in a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -64,37 +64,37 @@ transmission-id = [ "narwhal-transmission-id" ] [dependencies.narwhal-batch-certificate] package = "snarkvm-ledger-narwhal-batch-certificate" path = "./batch-certificate" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.narwhal-batch-header] package = "snarkvm-ledger-narwhal-batch-header" path = "./batch-header" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.narwhal-data] package = "snarkvm-ledger-narwhal-data" path = "./data" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.narwhal-subdag] package = "snarkvm-ledger-narwhal-subdag" path = "./subdag" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.narwhal-transmission] package = "snarkvm-ledger-narwhal-transmission" path = "./transmission" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.narwhal-transmission-id] package = "snarkvm-ledger-narwhal-transmission-id" path = "./transmission-id" -version = "=0.16.19" +version = "=1.1.0" optional = true [dev-dependencies.snarkvm-ledger-narwhal] diff --git a/ledger/narwhal/batch-certificate/Cargo.toml b/ledger/narwhal/batch-certificate/Cargo.toml index 63d18a6237..23fb6f8122 100644 --- a/ledger/narwhal/batch-certificate/Cargo.toml +++ b/ledger/narwhal/batch-certificate/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-narwhal-batch-certificate" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A batch certificate for a Narwhal-style memory pool in a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -32,17 +32,17 @@ test-helpers = [ "narwhal-batch-header/test-helpers" ] [dependencies.console] package = "snarkvm-console" path = "../../../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.narwhal-batch-header] package = "snarkvm-ledger-narwhal-batch-header" path = "../batch-header" -version = "=0.16.19" +version = "=1.1.0" [dependencies.narwhal-transmission-id] package = "snarkvm-ledger-narwhal-transmission-id" path = "../transmission-id" -version = "=0.16.19" +version = "=1.1.0" [dependencies.indexmap] version = "2.0" diff --git a/ledger/narwhal/batch-certificate/src/bytes.rs b/ledger/narwhal/batch-certificate/src/bytes.rs index 446a0d4193..49179d5858 100644 --- a/ledger/narwhal/batch-certificate/src/bytes.rs +++ b/ledger/narwhal/batch-certificate/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,97 +21,46 @@ impl FromBytes for BatchCertificate { // Read the version. let version = u8::read_le(&mut reader)?; // Ensure the version is valid. - if version != 1 && version != 2 { + if version != 1 { return Err(error("Invalid batch certificate version")); } - if version == 1 { - // Read the certificate ID. - let certificate_id = Field::read_le(&mut reader)?; - // Read the batch header. - let batch_header = BatchHeader::read_le(&mut reader)?; - // Read the number of signatures. - let num_signatures = u32::read_le(&mut reader)?; - // Ensure the number of signatures is within bounds. - if num_signatures as usize > Self::MAX_SIGNATURES { - return Err(error(format!( - "Number of signatures ({num_signatures}) exceeds the maximum ({})", - Self::MAX_SIGNATURES - ))); - } - // Read the signatures. - let mut signatures = IndexMap::with_capacity(num_signatures as usize); - for _ in 0..num_signatures { - // Read the signature. - let signature = Signature::read_le(&mut reader)?; - // Read the timestamp. - let timestamp = i64::read_le(&mut reader)?; - // Insert the signature and timestamp. - signatures.insert(signature, timestamp); - } - // Return the batch certificate. - Self::from_v1_deprecated(certificate_id, batch_header, signatures).map_err(error) - } else if version == 2 { - // Read the batch header. - let batch_header = BatchHeader::read_le(&mut reader)?; - // Read the number of signatures. - let num_signatures = u16::read_le(&mut reader)?; - // Ensure the number of signatures is within bounds. - if num_signatures as usize > Self::MAX_SIGNATURES { - return Err(error(format!( - "Number of signatures ({num_signatures}) exceeds the maximum ({})", - Self::MAX_SIGNATURES - ))); - } - // Read the signature bytes. - let mut signature_bytes = vec![0u8; num_signatures as usize * Signature::::size_in_bytes()]; - reader.read_exact(&mut signature_bytes)?; - // Read the signatures. - let signatures = cfg_chunks!(signature_bytes, Signature::::size_in_bytes()) - .map(Signature::read_le) - .collect::, _>>()?; - // Return the batch certificate. - Self::from(batch_header, signatures).map_err(error) - } else { - unreachable!("Invalid batch certificate version") + // Read the batch header. + let batch_header = BatchHeader::read_le(&mut reader)?; + // Read the number of signatures. + let num_signatures = u16::read_le(&mut reader)?; + // Ensure the number of signatures is within bounds. + if num_signatures > Self::MAX_SIGNATURES { + return Err(error(format!( + "Number of signatures ({num_signatures}) exceeds the maximum ({})", + Self::MAX_SIGNATURES + ))); } + // Read the signature bytes. + let mut signature_bytes = vec![0u8; num_signatures as usize * Signature::::size_in_bytes()]; + reader.read_exact(&mut signature_bytes)?; + // Read the signatures. + let signatures = cfg_chunks!(signature_bytes, Signature::::size_in_bytes()) + .map(Signature::read_le) + .collect::, _>>()?; + // Return the batch certificate. + Self::from(batch_header, signatures).map_err(error) } } impl ToBytes for BatchCertificate { /// Writes the batch certificate to the buffer. fn write_le(&self, mut writer: W) -> IoResult<()> { - match self { - Self::V1 { certificate_id, batch_header, signatures } => { - // Write the version. - 1u8.write_le(&mut writer)?; - // Write the certificate ID. - certificate_id.write_le(&mut writer)?; - // Write the batch header. - batch_header.write_le(&mut writer)?; - // Write the number of signatures. - u32::try_from(signatures.len()).map_err(error)?.write_le(&mut writer)?; - // Write the signatures. - for (signature, timestamp) in signatures.iter() { - // Write the signature. - signature.write_le(&mut writer)?; - // Write the timestamp. - timestamp.write_le(&mut writer)?; - } - } - Self::V2 { batch_header, signatures } => { - // Write the version. - 2u8.write_le(&mut writer)?; - // Write the batch header. - batch_header.write_le(&mut writer)?; - // Write the number of signatures. - u16::try_from(signatures.len()).map_err(error)?.write_le(&mut writer)?; - // Write the signatures. - for signature in signatures.iter() { - // Write the signature. - signature.write_le(&mut writer)?; - } - } + // Write the version. + 1u8.write_le(&mut writer)?; + // Write the batch header. + self.batch_header.write_le(&mut writer)?; + // Write the number of signatures. + u16::try_from(self.signatures.len()).map_err(error)?.write_le(&mut writer)?; + // Write the signatures. + for signature in self.signatures.iter() { + // Write the signature. + signature.write_le(&mut writer)?; } Ok(()) } diff --git a/ledger/narwhal/batch-certificate/src/lib.rs b/ledger/narwhal/batch-certificate/src/lib.rs index 9356b7dcf6..30a0c434a9 100644 --- a/ledger/narwhal/batch-certificate/src/lib.rs +++ b/ledger/narwhal/batch-certificate/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -28,83 +29,30 @@ use narwhal_batch_header::BatchHeader; use narwhal_transmission_id::TransmissionID; use core::hash::{Hash, Hasher}; -use indexmap::{IndexMap, IndexSet}; +use indexmap::IndexSet; use std::collections::HashSet; #[cfg(not(feature = "serial"))] use rayon::prelude::*; #[derive(Clone)] -pub enum BatchCertificate { - // TODO (howardwu): For mainnet - Delete V1 and switch everyone to V2 as the default. - V1 { - /// The certificate ID. - certificate_id: Field, - /// The batch header. - batch_header: BatchHeader, - /// The `(signature, timestamp)` pairs for the batch ID from the committee. - signatures: IndexMap, i64>, - }, - V2 { - /// The batch header. - batch_header: BatchHeader, - /// The signatures for the batch ID from the committee. - signatures: IndexSet>, - }, +pub struct BatchCertificate { + /// The batch header. + batch_header: BatchHeader, + /// The signatures for the batch ID from the committee. + signatures: IndexSet>, } impl BatchCertificate { /// The maximum number of signatures in a batch certificate. - pub const MAX_SIGNATURES: usize = BatchHeader::::MAX_CERTIFICATES; + pub const MAX_SIGNATURES: u16 = BatchHeader::::MAX_CERTIFICATES; } impl BatchCertificate { - // TODO (howardwu): For mainnet - Delete V1 and switch everyone to V2 as the default. - /// Initializes a (deprecated) V1 batch certificate. - pub fn from_v1_deprecated( - certificate_id: Field, - batch_header: BatchHeader, - signatures: IndexMap, i64>, - ) -> Result { - /// Returns the certificate ID. - fn compute_certificate_id( - batch_id: Field, - signatures: &IndexMap, i64>, - ) -> Result> { - let mut preimage = Vec::new(); - // Insert the batch ID. - batch_id.write_le(&mut preimage)?; - // Insert the signatures. - for (signature, timestamp) in signatures { - // Insert the signature. - signature.write_le(&mut preimage)?; - // Insert the timestamp. - timestamp.write_le(&mut preimage)?; - } - // Hash the preimage. - N::hash_bhp1024(&preimage.to_bits_le()) - } - // Ensure that the number of signatures is within bounds. - ensure!(signatures.len() <= Self::MAX_SIGNATURES, "Invalid number of signatures"); - // Compute the certificate ID. - if certificate_id != compute_certificate_id(batch_header.batch_id(), &signatures)? { - bail!("Invalid batch certificate ID") - } - // Verify the signatures are valid. - for (signature, timestamp) in &signatures { - let preimage = [batch_header.batch_id(), Field::from_u64(*timestamp as u64)]; - if !signature.verify(&signature.to_address(), &preimage) { - bail!("Invalid batch certificate signature") - } - } - // Return the V1 batch certificate. - Ok(Self::V1 { certificate_id, batch_header, signatures }) - } - /// Initializes a new batch certificate. pub fn from(batch_header: BatchHeader, signatures: IndexSet>) -> Result { // Ensure that the number of signatures is within bounds. - ensure!(signatures.len() <= Self::MAX_SIGNATURES, "Invalid number of signatures"); + ensure!(signatures.len() <= Self::MAX_SIGNATURES as usize, "Invalid number of signatures"); // Ensure that the signature is from a unique signer and not from the author. let signature_authors = signatures.iter().map(|signature| signature.to_address()).collect::>(); @@ -130,7 +78,7 @@ impl BatchCertificate { // Ensure the signatures are not empty. ensure!(!signatures.is_empty(), "Batch certificate must contain signatures"); // Return the batch certificate. - Ok(Self::V2 { batch_header, signatures }) + Ok(Self { batch_header, signatures }) } } @@ -144,36 +92,19 @@ impl Eq for BatchCertificate {} impl Hash for BatchCertificate { fn hash(&self, state: &mut H) { - match self { - Self::V1 { batch_header, signatures, .. } => { - batch_header.batch_id().hash(state); - (signatures.len() as u64).hash(state); - for signature in signatures.iter() { - signature.hash(state); - } - } - Self::V2 { batch_header, .. } => { - batch_header.batch_id().hash(state); - } - } + self.batch_header.batch_id().hash(state); } } impl BatchCertificate { /// Returns the certificate ID. pub const fn id(&self) -> Field { - match self { - Self::V1 { certificate_id, .. } => *certificate_id, - Self::V2 { batch_header, .. } => batch_header.batch_id(), - } + self.batch_header.batch_id() } /// Returns the batch header. pub const fn batch_header(&self) -> &BatchHeader { - match self { - Self::V1 { batch_header, .. } => batch_header, - Self::V2 { batch_header, .. } => batch_header, - } + &self.batch_header } /// Returns the batch ID. @@ -191,6 +122,16 @@ impl BatchCertificate { self.batch_header().round() } + /// Returns the timestamp of the batch header. + pub fn timestamp(&self) -> i64 { + self.batch_header().timestamp() + } + + /// Returns the committee ID. + pub const fn committee_id(&self) -> Field { + self.batch_header().committee_id() + } + /// Returns the transmission IDs. pub const fn transmission_ids(&self) -> &IndexSet> { self.batch_header().transmission_ids() @@ -201,36 +142,20 @@ impl BatchCertificate { self.batch_header().previous_certificate_ids() } - /// Returns the timestamp of the batch header. - pub fn timestamp(&self) -> i64 { - match self { - Self::V1 { batch_header, signatures, .. } => { - // Return the median timestamp. - let mut timestamps = signatures.values().copied().chain([batch_header.timestamp()]).collect::>(); - timestamps.sort_unstable(); - timestamps[timestamps.len() / 2] - } - Self::V2 { batch_header, .. } => batch_header.timestamp(), - } - } - /// Returns the signatures of the batch ID from the committee. pub fn signatures(&self) -> Box>> { - match self { - Self::V1 { signatures, .. } => Box::new(signatures.keys()), - Self::V2 { signatures, .. } => Box::new(signatures.iter()), - } + Box::new(self.signatures.iter()) } } #[cfg(any(test, feature = "test-helpers"))] pub mod test_helpers { use super::*; - use console::{account::PrivateKey, network::Testnet3, prelude::TestRng, types::Field}; + use console::{account::PrivateKey, network::MainnetV0, prelude::TestRng, types::Field}; use indexmap::IndexSet; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Returns a sample batch certificate, sampled at random. pub fn sample_batch_certificate(rng: &mut TestRng) -> BatchCertificate { @@ -305,7 +230,7 @@ pub mod test_helpers { // Sample the leader certificate. let certificate = sample_batch_certificate_for_round_with_previous_certificate_ids( current_round, - previous_certificate_ids.clone(), + previous_certificate_ids, rng, ); @@ -317,7 +242,7 @@ pub mod test_helpers { mod tests { use super::*; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; #[test] fn test_maximum_signatures() { diff --git a/ledger/narwhal/batch-certificate/src/serialize.rs b/ledger/narwhal/batch-certificate/src/serialize.rs index 1e06e50823..d6c1b0e82d 100644 --- a/ledger/narwhal/batch-certificate/src/serialize.rs +++ b/ledger/narwhal/batch-certificate/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,21 +19,12 @@ impl Serialize for BatchCertificate { /// Serializes the batch certificate to a JSON-string or buffer. fn serialize(&self, serializer: S) -> Result { match serializer.is_human_readable() { - true => match self { - Self::V1 { certificate_id, batch_header, signatures } => { - let mut state = serializer.serialize_struct("BatchCertificate", 3)?; - state.serialize_field("certificate_id", certificate_id)?; - state.serialize_field("batch_header", batch_header)?; - state.serialize_field("signatures", signatures)?; - state.end() - } - Self::V2 { batch_header, signatures } => { - let mut state = serializer.serialize_struct("BatchCertificate", 2)?; - state.serialize_field("batch_header", batch_header)?; - state.serialize_field("signatures", signatures)?; - state.end() - } - }, + true => { + let mut state = serializer.serialize_struct("BatchCertificate", 2)?; + state.serialize_field("batch_header", &self.batch_header)?; + state.serialize_field("signatures", &self.signatures)?; + state.end() + } false => ToBytesSerializer::serialize_with_size_encoding(self, serializer), } } @@ -44,28 +36,11 @@ impl<'de, N: Network> Deserialize<'de> for BatchCertificate { match deserializer.is_human_readable() { true => { let mut value = serde_json::Value::deserialize(deserializer)?; - - // Check if a certificate ID field is present. - let certificate_id = match value.get("certificate_id") { - Some(..) => Some(DeserializeExt::take_from_value::(&mut value, "certificate_id")?), - None => None, - }; - - // Parse for V1 and V2 batch certificates. - if let Some(certificate_id) = certificate_id { - Self::from_v1_deprecated( - certificate_id, - DeserializeExt::take_from_value::(&mut value, "batch_header")?, - DeserializeExt::take_from_value::(&mut value, "signatures")?, - ) - .map_err(de::Error::custom) - } else { - Self::from( - DeserializeExt::take_from_value::(&mut value, "batch_header")?, - DeserializeExt::take_from_value::(&mut value, "signatures")?, - ) - .map_err(de::Error::custom) - } + Self::from( + DeserializeExt::take_from_value::(&mut value, "batch_header")?, + DeserializeExt::take_from_value::(&mut value, "signatures")?, + ) + .map_err(de::Error::custom) } false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "batch certificate"), } diff --git a/ledger/narwhal/batch-certificate/src/string.rs b/ledger/narwhal/batch-certificate/src/string.rs index d94f243ff4..97340d7d29 100644 --- a/ledger/narwhal/batch-certificate/src/string.rs +++ b/ledger/narwhal/batch-certificate/src/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/narwhal/batch-header/Cargo.toml b/ledger/narwhal/batch-header/Cargo.toml index 8ec3fd22cd..69809c4bb3 100644 --- a/ledger/narwhal/batch-header/Cargo.toml +++ b/ledger/narwhal/batch-header/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-narwhal-batch-header" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A batch header for a Narwhal-style memory pool in a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -24,7 +24,7 @@ license = "Apache-2.0" edition = "2021" [features] -default = [ ] +default = [ "rayon" ] serial = [ "console/serial" ] wasm = [ "console/wasm" ] test-helpers = [ "narwhal-transmission-id/test-helpers", "time" ] @@ -32,17 +32,21 @@ test-helpers = [ "narwhal-transmission-id/test-helpers", "time" ] [dependencies.console] package = "snarkvm-console" path = "../../../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.narwhal-transmission-id] package = "snarkvm-ledger-narwhal-transmission-id" path = "../transmission-id" -version = "=0.16.19" +version = "=1.1.0" [dependencies.indexmap] version = "2.0" features = [ "serde" ] +[dependencies.rayon] +version = "1" +optional = true + [dependencies.serde_json] version = "1.0" features = [ "preserve_order" ] diff --git a/ledger/narwhal/batch-header/src/bytes.rs b/ledger/narwhal/batch-header/src/bytes.rs index c46a1f140a..75961f37c1 100644 --- a/ledger/narwhal/batch-header/src/bytes.rs +++ b/ledger/narwhal/batch-header/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,8 +21,7 @@ impl FromBytes for BatchHeader { // Read the version. let version = u8::read_le(&mut reader)?; // Ensure the version is valid. - // TODO (howardwu): For mainnet - Change the version back to 1. - if version != 1 && version != 2 { + if version != 1 { return Err(error("Invalid batch header version")); } @@ -33,14 +33,16 @@ impl FromBytes for BatchHeader { let round = u64::read_le(&mut reader)?; // Read the timestamp. let timestamp = i64::read_le(&mut reader)?; + // Read the committee ID. + let committee_id = Field::read_le(&mut reader)?; // Read the number of transmission IDs. let num_transmission_ids = u32::read_le(&mut reader)?; // Ensure the number of transmission IDs is within bounds. - if num_transmission_ids as usize > Self::MAX_TRANSMISSIONS { + if num_transmission_ids as usize > Self::MAX_TRANSMISSIONS_PER_BATCH { return Err(error(format!( "Number of transmission IDs ({num_transmission_ids}) exceeds the maximum ({})", - Self::MAX_TRANSMISSIONS, + Self::MAX_TRANSMISSIONS_PER_BATCH, ))); } // Read the transmission IDs. @@ -51,59 +53,31 @@ impl FromBytes for BatchHeader { } // Read the number of previous certificate IDs. - let num_previous_certificate_ids = u32::read_le(&mut reader)?; + let num_previous_certificate_ids = u16::read_le(&mut reader)?; // Ensure the number of previous certificate IDs is within bounds. - if num_previous_certificate_ids as usize > Self::MAX_CERTIFICATES { + if num_previous_certificate_ids > Self::MAX_CERTIFICATES { return Err(error(format!( "Number of previous certificate IDs ({num_previous_certificate_ids}) exceeds the maximum ({})", Self::MAX_CERTIFICATES ))); } - // Read the previous certificate IDs. - let mut previous_certificate_ids = IndexSet::new(); - for _ in 0..num_previous_certificate_ids { - // Read the certificate ID. - previous_certificate_ids.insert(Field::read_le(&mut reader)?); - } - // TODO (howardwu): For mainnet - Change this to always encode the number of committed certificate IDs. - // We currently only encode the size and certificates in the new version, for backwards compatibility. - let num_last_election_certificate_ids = if version == 2 { - // Read the number of last election certificate IDs. - u16::read_le(&mut reader)? - } else { - // Set the number of last election certificate IDs to zero. - 0 - }; - // Ensure the number of last election certificate IDs is within bounds. - if num_last_election_certificate_ids as usize > Self::MAX_CERTIFICATES { - return Err(error(format!( - "Number of last election certificate IDs ({num_last_election_certificate_ids}) exceeds the maximum ({})", - Self::MAX_CERTIFICATES - ))); - } - // Read the last election certificate IDs. - let mut last_election_certificate_ids = IndexSet::new(); - for _ in 0..num_last_election_certificate_ids { - // Read the certificate ID. - last_election_certificate_ids.insert(Field::read_le(&mut reader)?); - } + // Read the previous certificate ID bytes. + let mut previous_certificate_id_bytes = + vec![0u8; num_previous_certificate_ids as usize * Field::::size_in_bytes()]; + reader.read_exact(&mut previous_certificate_id_bytes)?; + // Read the previous certificate IDs. + let previous_certificate_ids = cfg_chunks!(previous_certificate_id_bytes, Field::::size_in_bytes()) + .map(Field::read_le) + .collect::, _>>()?; // Read the signature. let signature = Signature::read_le(&mut reader)?; // Construct the batch. - let batch = Self::from( - version, - author, - round, - timestamp, - transmission_ids, - previous_certificate_ids, - last_election_certificate_ids, - signature, - ) - .map_err(|e| error(e.to_string()))?; + let batch = + Self::from(author, round, timestamp, committee_id, transmission_ids, previous_certificate_ids, signature) + .map_err(error)?; // Return the batch. match batch.batch_id == batch_id { @@ -117,8 +91,7 @@ impl ToBytes for BatchHeader { /// Writes the batch header to the buffer. fn write_le(&self, mut writer: W) -> IoResult<()> { // Write the version. - // TODO (howardwu): For mainnet - Change this back to '1u8.write_le(&mut writer)?'; - self.version.write_le(&mut writer)?; + 1u8.write_le(&mut writer)?; // Write the batch ID. self.batch_id.write_le(&mut writer)?; // Write the author. @@ -127,6 +100,8 @@ impl ToBytes for BatchHeader { self.round.write_le(&mut writer)?; // Write the timestamp. self.timestamp.write_le(&mut writer)?; + // Write the committee ID. + self.committee_id.write_le(&mut writer)?; // Write the number of transmission IDs. u32::try_from(self.transmission_ids.len()).map_err(|e| error(e.to_string()))?.write_le(&mut writer)?; // Write the transmission IDs. @@ -135,25 +110,12 @@ impl ToBytes for BatchHeader { transmission_id.write_le(&mut writer)?; } // Write the number of previous certificate IDs. - u32::try_from(self.previous_certificate_ids.len()).map_err(|e| error(e.to_string()))?.write_le(&mut writer)?; + u16::try_from(self.previous_certificate_ids.len()).map_err(|e| error(e.to_string()))?.write_le(&mut writer)?; // Write the previous certificate IDs. for certificate_id in &self.previous_certificate_ids { // Write the certificate ID. certificate_id.write_le(&mut writer)?; } - // TODO (howardwu): For mainnet - Change this to always encode the number of committed certificate IDs. - // We currently only encode the size and certificates in the new version, for backwards compatibility. - if self.version != 1 { - // Write the number of last election certificate IDs. - u16::try_from(self.last_election_certificate_ids.len()) - .map_err(|e| error(e.to_string()))? - .write_le(&mut writer)?; - // Write the last election certificate IDs. - for certificate_id in &self.last_election_certificate_ids { - // Write the certificate ID. - certificate_id.write_le(&mut writer)?; - } - } // Write the signature. self.signature.write_le(&mut writer) } diff --git a/ledger/narwhal/batch-header/src/lib.rs b/ledger/narwhal/batch-header/src/lib.rs index 473641b003..2fa80edf65 100644 --- a/ledger/narwhal/batch-header/src/lib.rs +++ b/ledger/narwhal/batch-header/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -26,17 +27,17 @@ use console::{ prelude::*, types::Field, }; -use indexmap::IndexSet; use narwhal_transmission_id::TransmissionID; +use indexmap::IndexSet; + +#[cfg(not(feature = "serial"))] +use rayon::prelude::*; + #[derive(Clone, PartialEq, Eq)] pub struct BatchHeader { - /// The version of the batch header. - /// TODO (howardwu): For mainnet - Remove this version from the struct, we only use it here for backwards compatibility. - /// NOTE: You must keep the version encoding in the byte serialization, just remove it from the struct in memory. - version: u8, /// The batch ID, defined as the hash of the author, round number, timestamp, transmission IDs, - /// previous batch certificate IDs, and last election certificate IDs. + /// committee ID, previous batch certificate IDs, and last election certificate IDs. batch_id: Field, /// The author of the batch. author: Address, @@ -44,25 +45,26 @@ pub struct BatchHeader { round: u64, /// The timestamp. timestamp: i64, + /// The committee ID. + committee_id: Field, /// The set of `transmission IDs`. transmission_ids: IndexSet>, /// The batch certificate IDs of the previous round. previous_certificate_ids: IndexSet>, - /// The last election batch certificate IDs. - last_election_certificate_ids: IndexSet>, /// The signature of the batch ID from the creator. signature: Signature, } impl BatchHeader { /// The maximum number of certificates in a batch. - pub const MAX_CERTIFICATES: usize = 200; - /// The maximum number of solutions in a batch. - pub const MAX_SOLUTIONS: usize = N::MAX_SOLUTIONS; - /// The maximum number of transactions in a batch. - pub const MAX_TRANSACTIONS: usize = usize::pow(2, console::program::TRANSACTIONS_DEPTH as u32); - /// The maximum number of transmissions in a batch. - pub const MAX_TRANSMISSIONS: usize = Self::MAX_SOLUTIONS + Self::MAX_TRANSACTIONS; + #[cfg(not(any(test, feature = "test-helpers")))] + pub const MAX_CERTIFICATES: u16 = N::MAX_CERTIFICATES; + /// The maximum number of certificates in a batch. + /// This is deliberately set to a high value (100) for testing purposes only. + #[cfg(any(test, feature = "test-helpers"))] + pub const MAX_CERTIFICATES: u16 = 100; + /// The maximum number of rounds to store before garbage collecting. + pub const MAX_GC_ROUNDS: usize = 100; /// The maximum number of transmissions in a batch. /// Note: This limit is set to 50 as part of safety measures to prevent DoS attacks. /// This limit can be increased in the future as performance improves. Alternatively, @@ -76,106 +78,99 @@ impl BatchHeader { private_key: &PrivateKey, round: u64, timestamp: i64, + committee_id: Field, transmission_ids: IndexSet>, previous_certificate_ids: IndexSet>, - last_election_certificate_ids: IndexSet>, rng: &mut R, ) -> Result { - // Set the version. - // TODO (howardwu): For mainnet - Remove this version from the struct, we only use it here for backwards compatibility. - // NOTE: You must keep the version encoding in the byte serialization, just remove it from the struct in memory. - let version = 2u8; - match round { 0 | 1 => { // If the round is zero or one, then there should be no previous certificate IDs. ensure!(previous_certificate_ids.is_empty(), "Invalid round number, must not have certificates"); - // If the round is zero or one, then there should be no last election certificate IDs. - ensure!(last_election_certificate_ids.is_empty(), "Invalid batch, contains election certificates"); } // If the round is not zero and not one, then there should be at least one previous certificate ID. _ => ensure!(!previous_certificate_ids.is_empty(), "Invalid round number, must have certificates"), } // Ensure that the number of transmissions is within bounds. - ensure!(transmission_ids.len() <= Self::MAX_TRANSMISSIONS, "Invalid number of transmission ids"); + ensure!( + transmission_ids.len() <= Self::MAX_TRANSMISSIONS_PER_BATCH, + "Invalid number of transmission IDs ({})", + transmission_ids.len() + ); // Ensure that the number of previous certificate IDs is within bounds. - ensure!(previous_certificate_ids.len() <= Self::MAX_CERTIFICATES, "Invalid number of previous certificate IDs"); - // Ensure the number of last election certificate IDs is within bounds. ensure!( - last_election_certificate_ids.len() <= Self::MAX_CERTIFICATES, - "Invalid number of last election certificate IDs" + previous_certificate_ids.len() <= Self::MAX_CERTIFICATES as usize, + "Invalid number of previous certificate IDs ({})", + previous_certificate_ids.len() ); // Retrieve the address. let author = Address::try_from(private_key)?; // Compute the batch ID. let batch_id = Self::compute_batch_id( - version, author, round, timestamp, + committee_id, &transmission_ids, &previous_certificate_ids, - &last_election_certificate_ids, )?; // Sign the preimage. let signature = private_key.sign(&[batch_id], rng)?; // Return the batch header. Ok(Self { - version, - author, batch_id, + author, round, timestamp, + committee_id, transmission_ids, previous_certificate_ids, - last_election_certificate_ids, signature, }) } /// Initializes a new batch header. pub fn from( - version: u8, author: Address, round: u64, timestamp: i64, + committee_id: Field, transmission_ids: IndexSet>, previous_certificate_ids: IndexSet>, - last_election_certificate_ids: IndexSet>, signature: Signature, ) -> Result { match round { 0 | 1 => { // If the round is zero or one, then there should be no previous certificate IDs. ensure!(previous_certificate_ids.is_empty(), "Invalid round number, must not have certificates"); - // If the round is zero or one, then there should be no last election certificate IDs. - ensure!(last_election_certificate_ids.is_empty(), "Invalid batch, contains election certificates"); } // If the round is not zero and not one, then there should be at least one previous certificate ID. _ => ensure!(!previous_certificate_ids.is_empty(), "Invalid round number, must have certificates"), } // Ensure that the number of transmissions is within bounds. - ensure!(transmission_ids.len() <= Self::MAX_TRANSMISSIONS, "Invalid number of transmission ids"); + ensure!( + transmission_ids.len() <= Self::MAX_TRANSMISSIONS_PER_BATCH, + "Invalid number of transmission IDs ({})", + transmission_ids.len() + ); // Ensure that the number of previous certificate IDs is within bounds. - ensure!(previous_certificate_ids.len() <= Self::MAX_CERTIFICATES, "Invalid number of previous certificate IDs"); - // Ensure the number of last election certificate IDs is within bounds. ensure!( - last_election_certificate_ids.len() <= Self::MAX_CERTIFICATES, - "Invalid number of last election certificate IDs" + previous_certificate_ids.len() <= Self::MAX_CERTIFICATES as usize, + "Invalid number of previous certificate IDs ({})", + previous_certificate_ids.len() ); // Compute the batch ID. let batch_id = Self::compute_batch_id( - version, author, round, timestamp, + committee_id, &transmission_ids, &previous_certificate_ids, - &last_election_certificate_ids, )?; // Verify the signature. if !signature.verify(&author, &[batch_id]) { @@ -183,14 +178,13 @@ impl BatchHeader { } // Return the batch header. Ok(Self { - version, author, batch_id, round, timestamp, + committee_id, transmission_ids, previous_certificate_ids, - last_election_certificate_ids, signature, }) } @@ -217,6 +211,11 @@ impl BatchHeader { self.timestamp } + /// Returns the committee ID. + pub const fn committee_id(&self) -> Field { + self.committee_id + } + /// Returns the transmission IDs. pub const fn transmission_ids(&self) -> &IndexSet> { &self.transmission_ids @@ -227,11 +226,6 @@ impl BatchHeader { &self.previous_certificate_ids } - /// Returns the last election batch certificate IDs. - pub const fn last_election_certificate_ids(&self) -> &IndexSet> { - &self.last_election_certificate_ids - } - /// Returns the signature. pub const fn signature(&self) -> &Signature { &self.signature @@ -258,11 +252,11 @@ impl BatchHeader { #[cfg(any(test, feature = "test-helpers"))] pub mod test_helpers { use super::*; - use console::{account::PrivateKey, network::Testnet3, prelude::TestRng}; + use console::{account::PrivateKey, network::MainnetV0, prelude::TestRng}; use time::OffsetDateTime; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Returns a sample batch header, sampled at random. pub fn sample_batch_header(rng: &mut TestRng) -> BatchHeader { @@ -285,24 +279,16 @@ pub mod test_helpers { ) -> BatchHeader { // Sample a private key. let private_key = PrivateKey::new(rng).unwrap(); + // Sample the committee ID. + let committee_id = Field::::rand(rng); // Sample transmission IDs. let transmission_ids = narwhal_transmission_id::test_helpers::sample_transmission_ids(rng).into_iter().collect::>(); // Checkpoint the timestamp for the batch. let timestamp = OffsetDateTime::now_utc().unix_timestamp(); - // Sample the last election certificate IDs. - let last_election_certificate_ids = (0..5).map(|_| Field::::rand(rng)).collect::>(); // Return the batch header. - BatchHeader::new( - &private_key, - round, - timestamp, - transmission_ids, - previous_certificate_ids, - last_election_certificate_ids, - rng, - ) - .unwrap() + BatchHeader::new(&private_key, round, timestamp, committee_id, transmission_ids, previous_certificate_ids, rng) + .unwrap() } /// Returns a list of sample batch headers, sampled at random. diff --git a/ledger/narwhal/batch-header/src/serialize.rs b/ledger/narwhal/batch-header/src/serialize.rs index 15cefd3a70..7b9e150479 100644 --- a/ledger/narwhal/batch-header/src/serialize.rs +++ b/ledger/narwhal/batch-header/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,16 +20,14 @@ impl Serialize for BatchHeader { fn serialize(&self, serializer: S) -> Result { match serializer.is_human_readable() { true => { - let mut header = serializer.serialize_struct("BatchHeader", 9)?; - // TODO (howardwu): For mainnet - Remove the version field, and update the 'len' above to 8. - header.serialize_field("version", &self.version)?; + let mut header = serializer.serialize_struct("BatchHeader", 8)?; header.serialize_field("batch_id", &self.batch_id)?; header.serialize_field("author", &self.author)?; header.serialize_field("round", &self.round)?; header.serialize_field("timestamp", &self.timestamp)?; + header.serialize_field("committee_id", &self.committee_id)?; header.serialize_field("transmission_ids", &self.transmission_ids)?; header.serialize_field("previous_certificate_ids", &self.previous_certificate_ids)?; - header.serialize_field("last_election_certificate_ids", &self.last_election_certificate_ids)?; header.serialize_field("signature", &self.signature)?; header.end() } @@ -45,31 +44,14 @@ impl<'de, N: Network> Deserialize<'de> for BatchHeader { let mut header = serde_json::Value::deserialize(deserializer)?; let batch_id: Field = DeserializeExt::take_from_value::(&mut header, "batch_id")?; - // TODO (howardwu): For mainnet - Remove the version parsing. - // If the version field is present, then parse the version. - let version = DeserializeExt::take_from_value::(&mut header, "version").unwrap_or(1); - // TODO (howardwu): For mainnet - Remove the version checking. - // Ensure the version is valid. - if version != 1 && version != 2 { - return Err(error("Invalid batch header version")).map_err(de::Error::custom); - } - // TODO (howardwu): For mainnet - Always take from the 'header', no need to use this match case anymore. - // If the version is not 1, then parse the last election certificate IDs. - let last_election_certificate_ids = match version { - 1 => IndexSet::new(), - 2 => DeserializeExt::take_from_value::(&mut header, "last_election_certificate_ids")?, - _ => unreachable!(), - }; - // Recover the header. let batch_header = Self::from( - version, DeserializeExt::take_from_value::(&mut header, "author")?, DeserializeExt::take_from_value::(&mut header, "round")?, DeserializeExt::take_from_value::(&mut header, "timestamp")?, + DeserializeExt::take_from_value::(&mut header, "committee_id")?, DeserializeExt::take_from_value::(&mut header, "transmission_ids")?, DeserializeExt::take_from_value::(&mut header, "previous_certificate_ids")?, - last_election_certificate_ids, DeserializeExt::take_from_value::(&mut header, "signature")?, ) .map_err(de::Error::custom)?; @@ -77,10 +59,10 @@ impl<'de, N: Network> Deserialize<'de> for BatchHeader { // Ensure that the batch ID matches the recovered header. match batch_id == batch_header.batch_id() { true => Ok(batch_header), - false => { - Err(error(format!("Batch ID mismatch: expected {batch_id}, got {}", batch_header.batch_id()))) - .map_err(de::Error::custom) - } + false => Err(de::Error::custom(error(format!( + "Batch ID mismatch: expected {batch_id}, got {}", + batch_header.batch_id() + )))), } } false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "batch header"), diff --git a/ledger/narwhal/batch-header/src/string.rs b/ledger/narwhal/batch-header/src/string.rs index a5f7bb1e2d..35cf77cb22 100644 --- a/ledger/narwhal/batch-header/src/string.rs +++ b/ledger/narwhal/batch-header/src/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/narwhal/batch-header/src/to_id.rs b/ledger/narwhal/batch-header/src/to_id.rs index 1d3eea042b..3d9347063b 100644 --- a/ledger/narwhal/batch-header/src/to_id.rs +++ b/ledger/narwhal/batch-header/src/to_id.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,13 +19,12 @@ impl BatchHeader { /// Returns the batch ID. pub fn to_id(&self) -> Result> { Self::compute_batch_id( - self.version, self.author, self.round, self.timestamp, + self.committee_id, &self.transmission_ids, &self.previous_certificate_ids, - &self.last_election_certificate_ids, ) } } @@ -32,13 +32,12 @@ impl BatchHeader { impl BatchHeader { /// Returns the batch ID. pub fn compute_batch_id( - version: u8, author: Address, round: u64, timestamp: i64, + committee_id: Field, transmission_ids: &IndexSet>, previous_certificate_ids: &IndexSet>, - last_election_certificate_ids: &IndexSet>, ) -> Result> { let mut preimage = Vec::new(); // Insert the author. @@ -47,6 +46,8 @@ impl BatchHeader { round.write_le(&mut preimage)?; // Insert the timestamp. timestamp.write_le(&mut preimage)?; + // Insert the committee ID. + committee_id.write_le(&mut preimage)?; // Insert the number of transmissions. u32::try_from(transmission_ids.len())?.write_le(&mut preimage)?; // Insert the transmission IDs. @@ -60,17 +61,6 @@ impl BatchHeader { // Insert the certificate ID. certificate_id.write_le(&mut preimage)?; } - // TODO (howardwu): For mainnet - Change this to always encode the number of committed certificate IDs. - // We currently only encode the size and certificates only in the new version, for backwards compatibility. - if version != 1 { - // Insert the number of last election certificate IDs. - u32::try_from(last_election_certificate_ids.len())?.write_le(&mut preimage)?; - // Insert the last election certificate IDs. - for certificate_id in last_election_certificate_ids { - // Insert the certificate ID. - certificate_id.write_le(&mut preimage)?; - } - } // Hash the preimage. N::hash_bhp1024(&preimage.to_bits_le()) } diff --git a/ledger/narwhal/data/Cargo.toml b/ledger/narwhal/data/Cargo.toml index a8172b12d9..1b3aeb01ba 100644 --- a/ledger/narwhal/data/Cargo.toml +++ b/ledger/narwhal/data/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-narwhal-data" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A batch certificate for a Narwhal-style memory pool in a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -29,7 +29,7 @@ async = [ "tokio" ] [dependencies.console] package = "snarkvm-console" path = "../../../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.bytes] version = "1" @@ -42,3 +42,11 @@ features = [ "preserve_order" ] optional = true version = "1" features = [ "rt" ] + +[dev-dependencies.ledger-block] +package = "snarkvm-ledger-block" +path = "../../../ledger/block" + +[dev-dependencies.ledger-test-helpers] +package = "snarkvm-ledger-test-helpers" +path = "../../../ledger/test-helpers" diff --git a/ledger/narwhal/data/src/lib.rs b/ledger/narwhal/data/src/lib.rs index 28508ecc54..f45a782f25 100644 --- a/ledger/narwhal/data/src/lib.rs +++ b/ledger/narwhal/data/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -35,6 +36,20 @@ pub enum Data { } impl Data { + pub fn to_checksum(&self) -> Result { + // Convert to bits. + let preimage = match self { + Self::Object(object) => object.to_bytes_le()?.to_bits_le(), + Self::Buffer(bytes) => bytes.deref().to_bits_le(), + }; + // Hash the preimage bits. + let hash = N::hash_sha3_256(&preimage)?; + // Select the number of bits needed to parse the checksum. + let num_bits = usize::try_from(N::TransmissionChecksum::BITS).map_err(error)?; + // Return the checksum. + N::TransmissionChecksum::from_bits_le(&hash[0..num_bits]) + } + pub fn into> + From + FromBytes + ToBytes + Send + 'static>(self) -> Data { match self { Self::Object(x) => Data::Object(x.into()), @@ -206,20 +221,56 @@ impl<'de, T: FromBytes + ToBytes + DeserializeOwned + Send + 'static> Deserializ // Decode from bech32m. let (hrp, data, variant) = bech32::decode(&encoding).map_err(de::Error::custom)?; if hrp != PREFIX { - return Err(error(format!("Invalid data HRP - {hrp}"))).map_err(de::Error::custom); + return Err(de::Error::custom(error(format!("Invalid data HRP - {hrp}")))); }; if data.is_empty() { - return Err(error("Invalid bech32m data (empty)")).map_err(de::Error::custom); + return Err(de::Error::custom(error("Invalid bech32m data (empty)"))); } if variant != bech32::Variant::Bech32m { - return Err(error("Invalid data - variant is not bech32m")).map_err(de::Error::custom); + return Err(de::Error::custom(error("Invalid data - variant is not bech32m"))); } Ok(Self::Buffer(Bytes::from(Vec::from_base32(&data).map_err(de::Error::custom)?))) } - _ => Err(error(format!("Invalid data type - {type_}"))).map_err(de::Error::custom), + _ => Err(de::Error::custom(error(format!("Invalid data type - {type_}")))), } } false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "data"), } } } + +#[cfg(test)] +mod tests { + use super::*; + use console::network::MainnetV0; + use ledger_block::Transaction; + + #[test] + fn test_to_checksum() { + let rng = &mut TestRng::default(); + + // Sample transactions + let transactions = [ + ledger_test_helpers::sample_deployment_transaction(true, rng), + ledger_test_helpers::sample_deployment_transaction(false, rng), + ledger_test_helpers::sample_execution_transaction_with_fee(true, rng), + ledger_test_helpers::sample_execution_transaction_with_fee(false, rng), + ledger_test_helpers::sample_fee_private_transaction(rng), + ledger_test_helpers::sample_fee_public_transaction(rng), + ]; + + for transaction in transactions.into_iter() { + // Convert the transaction to a Data buffer. + let data_bytes: Data> = Data::Buffer(transaction.to_bytes_le().unwrap().into()); + // Convert the transaction to a data object. + let data = Data::Object(transaction); + + // Compute the checksums. + let checksum_1 = data_bytes.to_checksum::().unwrap(); + let checksum_2 = data.to_checksum::().unwrap(); + + // Ensure the checksums are equal. + assert_eq!(checksum_1, checksum_2); + } + } +} diff --git a/ledger/narwhal/src/lib.rs b/ledger/narwhal/src/lib.rs index 0596ee799c..ec54ad513b 100644 --- a/ledger/narwhal/src/lib.rs +++ b/ledger/narwhal/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/narwhal/subdag/Cargo.toml b/ledger/narwhal/subdag/Cargo.toml index 1f0191d3c9..6ecdb7b814 100644 --- a/ledger/narwhal/subdag/Cargo.toml +++ b/ledger/narwhal/subdag/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-narwhal-subdag" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A subdag for a Narwhal-style memory pool in a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -32,22 +32,27 @@ test-helpers = [ "narwhal-batch-certificate/test-helpers" ] [dependencies.console] package = "snarkvm-console" path = "../../../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.narwhal-batch-certificate] package = "snarkvm-ledger-narwhal-batch-certificate" path = "../batch-certificate" -version = "=0.16.19" +version = "=1.1.0" [dependencies.narwhal-batch-header] package = "snarkvm-ledger-narwhal-batch-header" path = "../batch-header" -version = "=0.16.19" +version = "=1.1.0" + +[dependencies.ledger-committee] +package = "snarkvm-ledger-committee" +path = "../../committee" +version = "=1.1.0" [dependencies.narwhal-transmission-id] package = "snarkvm-ledger-narwhal-transmission-id" path = "../transmission-id" -version = "=0.16.19" +version = "=1.1.0" [dependencies.indexmap] version = "2.0" diff --git a/ledger/narwhal/subdag/src/bytes.rs b/ledger/narwhal/subdag/src/bytes.rs index b805dabecb..986931e8f4 100644 --- a/ledger/narwhal/subdag/src/bytes.rs +++ b/ledger/narwhal/subdag/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,15 +21,14 @@ impl FromBytes for Subdag { // Read the version. let version = u8::read_le(&mut reader)?; // Ensure the version is valid. - // TODO (howardwu): For mainnet - Change the version back to 1. - if version != 1 && version != 2 { + if version != 1 { return Err(error(format!("Invalid subdag version ({version})"))); } // Read the number of rounds. let num_rounds = u32::read_le(&mut reader)?; // Ensure the number of rounds is within bounds. - if num_rounds as usize > Self::MAX_ROUNDS { + if num_rounds as u64 > Self::MAX_ROUNDS { return Err(error(format!("Number of rounds ({num_rounds}) exceeds the maximum ({})", Self::MAX_ROUNDS))); } // Read the round certificates. @@ -37,9 +37,9 @@ impl FromBytes for Subdag { // Read the round. let round = u64::read_le(&mut reader)?; // Read the number of certificates. - let num_certificates = u32::read_le(&mut reader)?; + let num_certificates = u16::read_le(&mut reader)?; // Ensure the number of certificates is within bounds. - if num_certificates as usize > BatchHeader::::MAX_CERTIFICATES { + if num_certificates > BatchHeader::::MAX_CERTIFICATES { return Err(error(format!( "Number of certificates ({num_certificates}) exceeds the maximum ({})", BatchHeader::::MAX_CERTIFICATES @@ -55,27 +55,8 @@ impl FromBytes for Subdag { subdag.insert(round, certificates); } - // Read the election certificate IDs. - let mut election_certificate_ids = IndexSet::new(); - // TODO (howardwu): For mainnet - Always attempt to deserialize the election certificate IDs. - if version != 1 { - // Read the number of election certificate IDs. - let num_election_certificate_ids = u16::read_le(&mut reader)?; - // Ensure the number of election certificate IDs is within bounds. - if num_election_certificate_ids as usize > BatchHeader::::MAX_CERTIFICATES { - return Err(error(format!( - "Number of election certificate IDs ({num_election_certificate_ids}) exceeds the maximum ({})", - BatchHeader::::MAX_CERTIFICATES - ))); - } - for _ in 0..num_election_certificate_ids { - // Read the election certificate ID. - election_certificate_ids.insert(Field::read_le(&mut reader)?); - } - } - // Return the subdag. - Self::from(subdag, election_certificate_ids).map_err(error) + Self::from(subdag).map_err(error) } } @@ -83,8 +64,7 @@ impl ToBytes for Subdag { /// Writes the subdag to the buffer. fn write_le(&self, mut writer: W) -> IoResult<()> { // Write the version. - // TODO (howardwu): For mainnet - Change the version back to 1. - 2u8.write_le(&mut writer)?; + 1u8.write_le(&mut writer)?; // Write the number of rounds. u32::try_from(self.subdag.len()).map_err(error)?.write_le(&mut writer)?; // Write the round certificates. @@ -92,20 +72,13 @@ impl ToBytes for Subdag { // Write the round. round.write_le(&mut writer)?; // Write the number of certificates. - u32::try_from(certificates.len()).map_err(error)?.write_le(&mut writer)?; + u16::try_from(certificates.len()).map_err(error)?.write_le(&mut writer)?; // Write the certificates. for certificate in certificates { // Write the certificate. certificate.write_le(&mut writer)?; } } - // Write the number of election certificate IDs. - u16::try_from(self.election_certificate_ids.len()).map_err(error)?.write_le(&mut writer)?; - // Write the election certificate IDs. - for election_certificate_id in &self.election_certificate_ids { - // Write the election certificate ID. - election_certificate_id.write_le(&mut writer)?; - } Ok(()) } } diff --git a/ledger/narwhal/subdag/src/lib.rs b/ledger/narwhal/subdag/src/lib.rs index 3026a094b3..d5f1efc5c6 100644 --- a/ledger/narwhal/subdag/src/lib.rs +++ b/ledger/narwhal/subdag/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,6 +21,7 @@ mod serialize; mod string; use console::{account::Address, prelude::*, program::SUBDAG_CERTIFICATES_DEPTH, types::Field}; +use ledger_committee::Committee; use narwhal_batch_certificate::BatchCertificate; use narwhal_batch_header::BatchHeader; use narwhal_transmission_id::TransmissionID; @@ -78,12 +80,40 @@ fn sanity_check_subdag_with_dfs(subdag: &BTreeMap) -> i64 { + let mut timestamps_and_stake = timestamps_and_stake; + + // Sort the timestamps. + #[cfg(not(feature = "serial"))] + timestamps_and_stake.par_sort_unstable_by_key(|(timestamp, _)| *timestamp); + #[cfg(feature = "serial")] + timestamps_and_stake.sort_unstable_by_key(|(timestamp, _)| *timestamp); + + // Calculate the total stake of the authors. + let total_stake = timestamps_and_stake.iter().map(|(_, stake)| *stake).sum::(); + + // Initialize the current timestamp and accumulated stake. + let mut current_timestamp: i64 = 0; + let mut accumulated_stake: u64 = 0; + + // Find the weighted median timestamp. + for (timestamp, stake) in timestamps_and_stake.iter() { + accumulated_stake = accumulated_stake.saturating_add(*stake); + current_timestamp = *timestamp; + if accumulated_stake.saturating_mul(2) >= total_stake { + break; + } + } + + // Return the weighted median timestamp + current_timestamp +} + #[derive(Clone)] pub struct Subdag { /// The subdag of round certificates. subdag: BTreeMap>>, - /// The election certificate IDs. - election_certificate_ids: IndexSet>, } impl PartialEq for Subdag { @@ -97,35 +127,30 @@ impl Eq for Subdag {} impl Subdag { /// Initializes a new subdag. - pub fn from( - subdag: BTreeMap>>, - election_certificate_ids: IndexSet>, - ) -> Result { + pub fn from(subdag: BTreeMap>>) -> Result { // Ensure the subdag is not empty. ensure!(!subdag.is_empty(), "Subdag cannot be empty"); // Ensure the subdag does not exceed the maximum number of rounds. - ensure!(subdag.len() <= Self::MAX_ROUNDS, "Subdag cannot exceed the maximum number of rounds"); + ensure!( + subdag.len() <= usize::try_from(Self::MAX_ROUNDS)?, + "Subdag cannot exceed the maximum number of rounds" + ); // Ensure the anchor round is even. ensure!(subdag.iter().next_back().map_or(0, |(r, _)| *r) % 2 == 0, "Anchor round must be even"); // Ensure there is only one leader certificate. ensure!(subdag.iter().next_back().map_or(0, |(_, c)| c.len()) == 1, "Subdag cannot have multiple leaders"); - // Ensure the number of election certificate IDs is within bounds. - ensure!( - election_certificate_ids.len() <= BatchHeader::::MAX_CERTIFICATES, - "Number of election certificate IDs exceeds the maximum" - ); // Ensure the rounds are sequential. ensure!(is_sequential(&subdag), "Subdag rounds must be sequential"); // Ensure the subdag structure matches the commit. ensure!(sanity_check_subdag_with_dfs(&subdag), "Subdag structure does not match commit"); // Ensure the leader certificate is an even round. - Ok(Self { subdag, election_certificate_ids }) + Ok(Self { subdag }) } } impl Subdag { /// The maximum number of rounds in a subdag (bounded up to GC depth). - pub const MAX_ROUNDS: usize = 50; + pub const MAX_ROUNDS: u64 = BatchHeader::::MAX_GC_ROUNDS as u64; } impl Subdag { @@ -162,30 +187,23 @@ impl Subdag { self.values().flatten().flat_map(BatchCertificate::transmission_ids) } - /// Returns the timestamp of the anchor round, defined as the median timestamp of the subdag. - pub fn timestamp(&self) -> i64 { - match self.leader_certificate() { - BatchCertificate::V1 { .. } => self.leader_certificate().timestamp(), - BatchCertificate::V2 { .. } => { - // Retrieve the timestamps of the certificates. - let mut timestamps = self.values().flatten().map(BatchCertificate::timestamp).collect::>(); - // Sort the timestamps. - #[cfg(not(feature = "serial"))] - timestamps.par_sort_unstable(); - #[cfg(feature = "serial")] - timestamps.sort_unstable(); - // Return the median timestamp. - timestamps[timestamps.len() / 2] - } - } - } + /// Returns the timestamp of the anchor round, defined as the weighted median timestamp of the subdag. + pub fn timestamp(&self, committee: &Committee) -> i64 { + // Retrieve the anchor round. + let anchor_round = self.anchor_round(); + // Retrieve the timestamps and stakes of the certificates for `anchor_round` - 1. + let timestamps_and_stakes = self + .values() + .flatten() + .filter(|certificate| certificate.round() == anchor_round.saturating_sub(1)) + .map(|certificate| (certificate.timestamp(), committee.get_stake(certificate.author()))) + .collect::>(); - /// Returns the election certificate IDs. - pub fn election_certificate_ids(&self) -> &IndexSet> { - &self.election_certificate_ids + // Return the weighted median timestamp. + weighted_median(timestamps_and_stakes) } - /// Returns the subdag root of the transactions. + /// Returns the subdag root of the certificates. pub fn to_subdag_root(&self) -> Result> { // Prepare the leaves. let leaves = cfg_iter!(self.subdag) @@ -194,10 +212,8 @@ impl Subdag { }) .collect::>(); - // Compute the subdag tree. - let tree = N::merkle_tree_bhp::(&leaves)?; - // Return the subdag root. - Ok(*tree.root()) + // Compute the subdag root. + Ok(*N::merkle_tree_bhp::(&leaves)?.root()) } } @@ -213,11 +229,11 @@ impl Deref for Subdag { #[cfg(any(test, feature = "test-helpers"))] pub mod test_helpers { use super::*; - use console::{network::Testnet3, prelude::TestRng}; + use console::{network::MainnetV0, prelude::TestRng}; - use indexmap::{indexset, IndexSet}; + use indexmap::{IndexSet, indexset}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Returns a sample subdag, sampled at random. pub fn sample_subdag(rng: &mut TestRng) -> Subdag { @@ -265,14 +281,8 @@ pub mod test_helpers { ); subdag.insert(starting_round + 2, indexset![certificate]); - // Initialize the election certificate IDs. - let mut election_certificate_ids = IndexSet::new(); - for _ in 0..AVAILABILITY_THRESHOLD { - election_certificate_ids.insert(rng.gen()); - } - // Return the subdag. - Subdag::from(subdag, election_certificate_ids).unwrap() + Subdag::from(subdag).unwrap() } /// Returns a list of sample subdags, sampled at random. @@ -287,3 +297,85 @@ pub mod test_helpers { sample } } + +#[cfg(test)] +mod tests { + use super::*; + use narwhal_batch_header::BatchHeader; + + type CurrentNetwork = console::network::MainnetV0; + + const ITERATIONS: u64 = 100; + + #[test] + fn test_max_certificates() { + // Determine the maximum number of certificates in a block. + let max_certificates_per_block = + BatchHeader::::MAX_GC_ROUNDS * BatchHeader::::MAX_CERTIFICATES as usize; + + // Note: The maximum number of certificates in a block must be able to be Merklized. + assert!( + max_certificates_per_block <= 2u32.checked_pow(SUBDAG_CERTIFICATES_DEPTH as u32).unwrap() as usize, + "The maximum number of certificates in a block is too large" + ); + } + + #[test] + fn test_weighted_median_simple() { + // Test a simple case with equal weights. + let data = vec![(1, 10), (2, 10), (3, 10)]; + assert_eq!(weighted_median(data), 2); + + // Test a case with a single element. + let data = vec![(5, 10)]; + assert_eq!(weighted_median(data), 5); + + // Test a case with an even number of elements + let data = vec![(1, 10), (2, 30), (3, 20), (4, 40)]; + assert_eq!(weighted_median(data), 3); + + // Test a case with a skewed weight. + let data = vec![(100, 100), (200, 10000), (300, 500)]; + assert_eq!(weighted_median(data), 200); + + // Test a case with a empty set. + assert_eq!(weighted_median(vec![]), 0); + + // Test a case where there is possible truncation. + let data = vec![(1, 1), (2, 1), (3, 1), (4, 1), (5, 1)]; + assert_eq!(weighted_median(data), 3); + + // Test a case where weights of 0 do not affect the median. + let data = vec![(1, 10), (2, 0), (3, 0), (4, 0), (5, 20), (6, 0), (7, 10)]; + assert_eq!(weighted_median(data), 5); + } + + #[test] + fn test_weighted_median_range() { + let mut rng = TestRng::default(); + + for _ in 0..ITERATIONS { + let data: Vec<(i64, u64)> = (0..10).map(|_| (rng.gen_range(1..100), rng.gen_range(10..100))).collect(); + let min = data.iter().min_by_key(|x| x.0).unwrap().0; + let max = data.iter().max_by_key(|x| x.0).unwrap().0; + let median = weighted_median(data); + assert!(median >= min && median <= max); + } + } + + #[test] + fn test_weighted_median_scaled_weights() { + let mut rng = TestRng::default(); + + for _ in 0..ITERATIONS { + let data: Vec<(i64, u64)> = (0..10).map(|_| (rng.gen_range(1..100), rng.gen_range(10..100) * 2)).collect(); + let scaled_data: Vec<(i64, u64)> = data.iter().map(|&(t, s)| (t, s * 10)).collect(); + + if weighted_median(data.clone()) != weighted_median(scaled_data.clone()) { + println!("data: {:?}", data); + println!("scaled_data: {:?}", scaled_data); + } + assert_eq!(weighted_median(data), weighted_median(scaled_data)); + } + } +} diff --git a/ledger/narwhal/subdag/src/serialize.rs b/ledger/narwhal/subdag/src/serialize.rs index fb73011d91..336b173879 100644 --- a/ledger/narwhal/subdag/src/serialize.rs +++ b/ledger/narwhal/subdag/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,9 +20,8 @@ impl Serialize for Subdag { fn serialize(&self, serializer: S) -> Result { match serializer.is_human_readable() { true => { - let mut certificate = serializer.serialize_struct("Subdag", 2)?; + let mut certificate = serializer.serialize_struct("Subdag", 1)?; certificate.serialize_field("subdag", &self.subdag)?; - certificate.serialize_field("election_certificate_ids", &self.election_certificate_ids)?; certificate.end() } false => ToBytesSerializer::serialize_with_size_encoding(self, serializer), @@ -36,11 +36,7 @@ impl<'de, N: Network> Deserialize<'de> for Subdag { true => { let mut value = serde_json::Value::deserialize(deserializer)?; - // TODO (howardwu): For mainnet - Directly take the value, do not check if its missing. - let election_certificate_ids = - DeserializeExt::take_from_value::(&mut value, "election_certificate_ids").unwrap_or_default(); - - Ok(Self::from(DeserializeExt::take_from_value::(&mut value, "subdag")?, election_certificate_ids) + Ok(Self::from(DeserializeExt::take_from_value::(&mut value, "subdag")?) .map_err(de::Error::custom)?) } false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "subdag"), diff --git a/ledger/narwhal/subdag/src/string.rs b/ledger/narwhal/subdag/src/string.rs index 101046abe9..49f69c7305 100644 --- a/ledger/narwhal/subdag/src/string.rs +++ b/ledger/narwhal/subdag/src/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/narwhal/transmission-id/Cargo.toml b/ledger/narwhal/transmission-id/Cargo.toml index 9ab29797eb..4be5f0657c 100644 --- a/ledger/narwhal/transmission-id/Cargo.toml +++ b/ledger/narwhal/transmission-id/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-narwhal-transmission-id" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A transmission ID for a Narwhal-style memory pool in a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -32,12 +32,12 @@ test-helpers = [ ] [dependencies.console] package = "snarkvm-console" path = "../../../console" -version = "=0.16.19" +version = "=1.1.0" -[dependencies.ledger-coinbase] -package = "snarkvm-ledger-coinbase" -path = "../../coinbase" -version = "=0.16.19" +[dependencies.ledger-puzzle] +package = "snarkvm-ledger-puzzle" +path = "../../puzzle" +version = "=1.1.0" [dev-dependencies.bincode] version = "1.3" diff --git a/ledger/narwhal/transmission-id/src/bytes.rs b/ledger/narwhal/transmission-id/src/bytes.rs index a8a49a3d7b..d3a02055d5 100644 --- a/ledger/narwhal/transmission-id/src/bytes.rs +++ b/ledger/narwhal/transmission-id/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -22,8 +23,8 @@ impl FromBytes for TransmissionID { // Match the variant. match variant { 0 => Ok(Self::Ratification), - 1 => Ok(Self::Solution(FromBytes::read_le(&mut reader)?)), - 2 => Ok(Self::Transaction(FromBytes::read_le(&mut reader)?)), + 1 => Ok(Self::Solution(FromBytes::read_le(&mut reader)?, FromBytes::read_le(&mut reader)?)), + 2 => Ok(Self::Transaction(FromBytes::read_le(&mut reader)?, FromBytes::read_le(&mut reader)?)), 3.. => Err(error("Invalid worker transmission ID variant")), } } @@ -35,13 +36,15 @@ impl ToBytes for TransmissionID { // Write the transmission. match self { Self::Ratification => 0u8.write_le(&mut writer), - Self::Solution(id) => { + Self::Solution(id, checksum) => { 1u8.write_le(&mut writer)?; - id.write_le(&mut writer) + id.write_le(&mut writer)?; + checksum.write_le(&mut writer) } - Self::Transaction(id) => { + Self::Transaction(id, checksum) => { 2u8.write_le(&mut writer)?; - id.write_le(&mut writer) + id.write_le(&mut writer)?; + checksum.write_le(&mut writer) } } } diff --git a/ledger/narwhal/transmission-id/src/lib.rs b/ledger/narwhal/transmission-id/src/lib.rs index 43ffea0191..6f333834ba 100644 --- a/ledger/narwhal/transmission-id/src/lib.rs +++ b/ledger/narwhal/transmission-id/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,37 +21,37 @@ mod serialize; mod string; use console::{network::TRANSACTION_PREFIX, prelude::*}; -use ledger_coinbase::{PuzzleCommitment, PUZZLE_COMMITMENT_PREFIX}; +use ledger_puzzle::{SOLUTION_ID_PREFIX, SolutionID}; #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub enum TransmissionID { /// A ratification. Ratification, - /// A prover solution. - Solution(PuzzleCommitment), + /// A solution. + Solution(SolutionID, N::TransmissionChecksum), /// A transaction. - Transaction(N::TransactionID), + Transaction(N::TransactionID, N::TransmissionChecksum), } -impl From> for TransmissionID { - /// Converts the puzzle commitment into a transmission ID. - fn from(puzzle_commitment: PuzzleCommitment) -> Self { - Self::Solution(puzzle_commitment) +impl From<(SolutionID, N::TransmissionChecksum)> for TransmissionID { + /// Converts the solution ID and checksum into a transmission ID. + fn from((solution_id, checksum): (SolutionID, N::TransmissionChecksum)) -> Self { + Self::Solution(solution_id, checksum) } } -impl From<&N::TransactionID> for TransmissionID { - /// Converts the transaction ID into a transmission ID. - fn from(transaction_id: &N::TransactionID) -> Self { - Self::Transaction(*transaction_id) +impl From<(&N::TransactionID, &N::TransmissionChecksum)> for TransmissionID { + /// Converts the transaction ID and checksum into a transmission ID. + fn from((transaction_id, checksum): (&N::TransactionID, &N::TransmissionChecksum)) -> Self { + Self::Transaction(*transaction_id, *checksum) } } impl TransmissionID { - /// Returns the puzzle commitment if the transmission is a solution. - pub fn solution(&self) -> Option> { + /// Returns the solution ID if the transmission is a solution. + pub fn solution(&self) -> Option> { match self { - Self::Solution(puzzle_commitment) => Some(*puzzle_commitment), + Self::Solution(solution_id, _) => Some(*solution_id), _ => None, } } @@ -58,34 +59,49 @@ impl TransmissionID { /// Returns the transaction ID if the transmission is a transaction. pub fn transaction(&self) -> Option { match self { - Self::Transaction(transaction_id) => Some(*transaction_id), + Self::Transaction(transaction_id, _) => Some(*transaction_id), _ => None, } } + + /// Returns the checksum if the transmission is a solution or a transaction. + pub fn checksum(&self) -> Option { + match self { + Self::Ratification => None, + Self::Solution(_, checksum) => Some(*checksum), + Self::Transaction(_, checksum) => Some(*checksum), + } + } } #[cfg(any(test, feature = "test-helpers"))] pub mod test_helpers { use super::*; use console::{ - network::Testnet3, + network::MainnetV0, prelude::{Rng, TestRng, Uniform}, types::Field, }; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Returns a list of sample transmission IDs, sampled at random. pub fn sample_transmission_ids(rng: &mut TestRng) -> Vec> { // Initialize a sample vector. let mut sample = Vec::with_capacity(10); - // Append sample puzzle commitments. + // Append sample solution IDs. for _ in 0..5 { - sample.push(TransmissionID::Solution(PuzzleCommitment::from_g1_affine(rng.gen()))); + sample.push(TransmissionID::Solution( + SolutionID::from(rng.gen::()), + ::TransmissionChecksum::from(rng.gen::()), + )); } // Append sample transaction IDs. for _ in 0..5 { - let id = TransmissionID::Transaction(::TransactionID::from(Field::rand(rng))); + let id = TransmissionID::Transaction( + ::TransactionID::from(Field::rand(rng)), + ::TransmissionChecksum::from(rng.gen::()), + ); sample.push(id); } // Return the sample vector. diff --git a/ledger/narwhal/transmission-id/src/serialize.rs b/ledger/narwhal/transmission-id/src/serialize.rs index 9d5247cea1..d01905fbff 100644 --- a/ledger/narwhal/transmission-id/src/serialize.rs +++ b/ledger/narwhal/transmission-id/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/narwhal/transmission-id/src/string.rs b/ledger/narwhal/transmission-id/src/string.rs index 167ad781ef..8b874a47c1 100644 --- a/ledger/narwhal/transmission-id/src/string.rs +++ b/ledger/narwhal/transmission-id/src/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,11 +20,20 @@ impl FromStr for TransmissionID { /// Initializes the transmission ID from a string. fn from_str(input: &str) -> Result { - if input.starts_with(PUZZLE_COMMITMENT_PREFIX) { - Ok(Self::Solution(PuzzleCommitment::from_str(input)?)) - } else if input.starts_with(TRANSACTION_PREFIX) { + // Split the id and checksum. + let (id, checksum) = input.split_once('.').ok_or_else(|| anyhow!("Invalid transmission ID: {input}"))?; + // Parse the string. + if id.starts_with(SOLUTION_ID_PREFIX) { + Ok(Self::Solution( + SolutionID::from_str(id)?, + N::TransmissionChecksum::from_str(checksum) + .map_err(|_| anyhow!("Failed to parse checksum: {checksum}"))?, + )) + } else if id.starts_with(TRANSACTION_PREFIX) { Ok(Self::Transaction( - N::TransactionID::from_str(input).map_err(|_| anyhow!("Failed to parse transaction ID: {input}"))?, + N::TransactionID::from_str(id).map_err(|_| anyhow!("Failed to parse transaction ID: {id}"))?, + N::TransmissionChecksum::from_str(checksum) + .map_err(|_| anyhow!("Failed to parse checksum: {checksum}"))?, )) } else { bail!("Invalid transmission ID: {input}") @@ -43,8 +53,8 @@ impl Display for TransmissionID { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Self::Ratification => write!(f, "ratification"), - Self::Solution(id) => write!(f, "{}", id), - Self::Transaction(id) => write!(f, "{}", id), + Self::Solution(id, checksum) => write!(f, "{}.{}", id, checksum), + Self::Transaction(id, checksum) => write!(f, "{}.{}", id, checksum), } } } @@ -52,9 +62,9 @@ impl Display for TransmissionID { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_string() { diff --git a/ledger/narwhal/transmission/Cargo.toml b/ledger/narwhal/transmission/Cargo.toml index c209403679..6c71bfbcb6 100644 --- a/ledger/narwhal/transmission/Cargo.toml +++ b/ledger/narwhal/transmission/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-narwhal-transmission" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A transmission for a Narwhal-style memory pool in a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -32,22 +32,22 @@ test-helpers = [ ] [dependencies.console] package = "snarkvm-console" path = "../../../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-block] package = "snarkvm-ledger-block" path = "../../block" -version = "=0.16.19" - -[dependencies.ledger-coinbase] -package = "snarkvm-ledger-coinbase" -path = "../../coinbase" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-narwhal-data] package = "snarkvm-ledger-narwhal-data" path = "../data" -version = "=0.16.19" +version = "=1.1.0" + +[dependencies.ledger-puzzle] +package = "snarkvm-ledger-puzzle" +path = "../../puzzle" +version = "=1.1.0" [dependencies.bytes] version = "1" diff --git a/ledger/narwhal/transmission/src/bytes.rs b/ledger/narwhal/transmission/src/bytes.rs index 7d06ef6077..fc0d946eb6 100644 --- a/ledger/narwhal/transmission/src/bytes.rs +++ b/ledger/narwhal/transmission/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/narwhal/transmission/src/lib.rs b/ledger/narwhal/transmission/src/lib.rs index a18d096241..07fdc25278 100644 --- a/ledger/narwhal/transmission/src/lib.rs +++ b/ledger/narwhal/transmission/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,8 +22,8 @@ mod string; use console::prelude::*; use ledger_block::Transaction; -use ledger_coinbase::ProverSolution; use ledger_narwhal_data::Data; +use ledger_puzzle::Solution; #[derive(Clone, PartialEq, Eq)] pub enum Transmission { @@ -30,15 +31,15 @@ pub enum Transmission { Ratification, /// A prover solution. /// Attention: Observe that the solution is encapsulated in `Data`, and thus possibly unchecked. - Solution(Data>), + Solution(Data>), /// A transaction. /// Attention: Observe that the transaction is encapsulated in `Data`, and thus possibly unchecked. Transaction(Data>), } -impl From> for Transmission { +impl From> for Transmission { /// Converts the prover solution into a transmission. - fn from(solution: ProverSolution) -> Self { + fn from(solution: Solution) -> Self { Self::Solution(Data::Object(solution)) } } @@ -50,9 +51,9 @@ impl From> for Transmission { } } -impl From>> for Transmission { +impl From>> for Transmission { /// Converts the prover solution into a transmission. - fn from(solution: Data>) -> Self { + fn from(solution: Data>) -> Self { Self::Solution(solution) } } @@ -64,17 +65,28 @@ impl From>> for Transmission { } } +impl Transmission { + /// Returns the checksum of the transmission. + pub fn to_checksum(&self) -> Result> { + match self { + Self::Ratification => Ok(None), + Self::Solution(solution) => solution.to_checksum::().map(Some), + Self::Transaction(transaction) => transaction.to_checksum::().map(Some), + } + } +} + #[cfg(any(test, feature = "test-helpers"))] pub mod test_helpers { use super::*; use console::{ - network::Testnet3, + network::MainnetV0, prelude::{Rng, TestRng}, }; use ::bytes::Bytes; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Returns a list of sample transmissions, sampled at random. pub fn sample_transmissions(rng: &mut TestRng) -> Vec> { diff --git a/ledger/narwhal/transmission/src/serialize.rs b/ledger/narwhal/transmission/src/serialize.rs index 4657a7ff76..e986992592 100644 --- a/ledger/narwhal/transmission/src/serialize.rs +++ b/ledger/narwhal/transmission/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -61,7 +62,7 @@ impl<'de, N: Network> Deserialize<'de> for Transmission { DeserializeExt::take_from_value::(&mut transmission, "transmission") .map_err(de::Error::custom)?, )), - _ => Err(error("Invalid transmission type")).map_err(de::Error::custom), + _ => Err(de::Error::custom(error("Invalid transmission type"))), } } false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "transmission"), diff --git a/ledger/narwhal/transmission/src/string.rs b/ledger/narwhal/transmission/src/string.rs index f1a93b89ff..6502889bbd 100644 --- a/ledger/narwhal/transmission/src/string.rs +++ b/ledger/narwhal/transmission/src/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/coinbase/Cargo.toml b/ledger/puzzle/Cargo.toml similarity index 56% rename from ledger/coinbase/Cargo.toml rename to ledger/puzzle/Cargo.toml index dbb5b6ce3f..a7b15e7b17 100644 --- a/ledger/coinbase/Cargo.toml +++ b/ledger/puzzle/Cargo.toml @@ -1,10 +1,10 @@ [package] -name = "snarkvm-ledger-coinbase" -version = "0.16.19" +name = "snarkvm-ledger-puzzle" +version = "1.1.0" authors = [ "The Aleo Team " ] -description = "Coinbase puzzle for a decentralized virtual machine" +description = "Puzzle for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -24,54 +24,27 @@ license = "Apache-2.0" edition = "2021" [[bench]] -name = "coinbase_puzzle" -path = "benches/coinbase_puzzle.rs" +name = "puzzle" +path = "benches/puzzle.rs" harness = false required-features = [ "setup" ] [features] -default = [ ] +default = [ "indexmap/rayon", "rayon" ] cuda = [ "snarkvm-algorithms/cuda" ] -serial = [ - "console/serial", - "snarkvm-algorithms/serial", - "snarkvm-curves/serial", - "snarkvm-fields/serial", - "snarkvm-utilities/serial" -] +serial = [ "console/serial", "snarkvm-algorithms/serial" ] setup = [ ] timer = [ "aleo-std/timer" ] -wasm = [ - "console/wasm", - "snarkvm-algorithms/wasm", - "snarkvm-utilities/wasm" -] +wasm = [ "console/wasm", "snarkvm-algorithms/wasm" ] [dependencies.console] package = "snarkvm-console" path = "../../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.snarkvm-algorithms] path = "../../algorithms" -version = "=0.16.19" - -[dependencies.snarkvm-curves] -path = "../../curves" -version = "=0.16.19" - -[dependencies.snarkvm-fields] -path = "../../fields" -version = "=0.16.19" - -[dependencies.snarkvm-synthesizer-snark] -path = "../../synthesizer/snark" -version = "=0.16.19" - -[dependencies.snarkvm-utilities] -path = "../../utilities" -version = "=0.16.19" -default-features = false +version = "=1.1.0" [dependencies.aleo-std] version = "0.1.24" @@ -83,16 +56,28 @@ version = "1.0.73" [dependencies.bincode] version = "1" -[dependencies.blake2] -version = "0.10" -default-features = false - [dependencies.indexmap] version = "2.0" features = [ "serde", "rayon" ] +[dependencies.lru] +version = "0.12" + +[dependencies.once_cell] +version = "1.18" + +[dependencies.parking_lot] +version = "0.12" + +[dependencies.rand] +version = "0.8" + +[dependencies.rand_chacha] +version = "0.3.1" + [dependencies.rayon] version = "1" +optional = true [dependencies.serde_json] version = "1.0" @@ -108,3 +93,6 @@ version = "0.5.1" [dev-dependencies.rand] version = "0.8" + +[dev-dependencies.snarkvm-ledger-puzzle-epoch] +path = "epoch" diff --git a/ledger/coinbase/LICENSE.md b/ledger/puzzle/LICENSE.md similarity index 100% rename from ledger/coinbase/LICENSE.md rename to ledger/puzzle/LICENSE.md diff --git a/ledger/coinbase/README.md b/ledger/puzzle/README.md similarity index 51% rename from ledger/coinbase/README.md rename to ledger/puzzle/README.md index 81948b6954..0350fbee9d 100644 --- a/ledger/coinbase/README.md +++ b/ledger/puzzle/README.md @@ -1,5 +1,5 @@ -# snarkvm-ledger-coinbase +# snarkvm-ledger-puzzle -[![Crates.io](https://img.shields.io/crates/v/snarkvm-ledger-coinbase.svg?color=neon)](https://crates.io/crates/snarkvm-ledger-coinbase) +[![Crates.io](https://img.shields.io/crates/v/snarkvm-ledger-puzzle.svg?color=neon)](https://crates.io/crates/snarkvm-ledger-puzzle) [![Authors](https://img.shields.io/badge/authors-Aleo-orange.svg)](https://aleo.org) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE.md) diff --git a/ledger/puzzle/benches/puzzle.rs b/ledger/puzzle/benches/puzzle.rs new file mode 100644 index 0000000000..6018d894ce --- /dev/null +++ b/ledger/puzzle/benches/puzzle.rs @@ -0,0 +1,83 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +#![allow(clippy::single_element_loop)] + +#[macro_use] +extern crate criterion; + +use console::{ + account::*, + network::{MainnetV0, Network}, +}; +use snarkvm_ledger_puzzle::{Puzzle, PuzzleSolutions}; +use snarkvm_ledger_puzzle_epoch::MerklePuzzle; + +use criterion::Criterion; +use rand::{self, CryptoRng, RngCore, thread_rng}; + +fn sample_address_and_counter(rng: &mut (impl CryptoRng + RngCore)) -> (Address, u64) { + let private_key = PrivateKey::new(rng).unwrap(); + let address = Address::try_from(private_key).unwrap(); + let counter = rng.next_u64(); + (address, counter) +} + +fn puzzle_prove(c: &mut Criterion) { + let rng = &mut thread_rng(); + + // Initialize a new puzzle. + let puzzle = Puzzle::::new::>(); + + // Initialize an epoch hash. + let epoch_hash = rng.gen(); + + c.bench_function("Puzzle::prove", |b| { + let (address, counter) = sample_address_and_counter(rng); + b.iter(|| puzzle.prove(epoch_hash, address, counter, None).unwrap()) + }); +} + +fn puzzle_verify(c: &mut Criterion) { + let rng = &mut thread_rng(); + + // Initialize a new puzzle. + let puzzle = Puzzle::::new::>(); + + // Initialize an epoch hash. + let epoch_hash = rng.gen(); + + for batch_size in [1, 2, ::MAX_SOLUTIONS] { + let solutions = (0..batch_size) + .map(|_| { + let (address, counter) = sample_address_and_counter(rng); + puzzle.prove(epoch_hash, address, counter, None).unwrap() + }) + .collect::>(); + let solutions = PuzzleSolutions::new(solutions).unwrap(); + + c.bench_function("Puzzle::check_solutions", |b| { + b.iter(|| puzzle.check_solutions(&solutions, epoch_hash, 0u64).unwrap()) + }); + } +} + +criterion_group! { + name = puzzle; + config = Criterion::default().sample_size(10); + targets = puzzle_prove, puzzle_verify, +} + +criterion_main!(puzzle); diff --git a/ledger/puzzle/epoch/Cargo.toml b/ledger/puzzle/epoch/Cargo.toml new file mode 100644 index 0000000000..94ba127cf4 --- /dev/null +++ b/ledger/puzzle/epoch/Cargo.toml @@ -0,0 +1,102 @@ +[package] +name = "snarkvm-ledger-puzzle-epoch" +version = "1.1.0" +authors = [ "The Aleo Team " ] +description = "Epoch puzzle for a decentralized virtual machine" +homepage = "https://aleo.org" +repository = "https://github.com/AleoNet/snarkVM" +keywords = [ + "aleo", + "cryptography", + "blockchain", + "decentralized", + "zero-knowledge" +] +categories = [ + "compilers", + "cryptography", + "mathematics", + "wasm", + "web-programming" +] +include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] +license = "Apache-2.0" +edition = "2021" + +[features] +default = [ "synthesis", "rayon" ] +serial = [ "console/serial", "snarkvm-ledger-puzzle/serial" ] +merkle = [ ] +synthesis = [ + "aleo-std", + "circuit", + "lru", + "parking_lot", + "snarkvm-synthesizer-process", + "snarkvm-synthesizer-program" +] +timer = [ "aleo-std/timer" ] +wasm = [ "console/wasm" ] + +[dependencies.circuit] +package = "snarkvm-circuit" +path = "../../../circuit" +version = "=1.1.0" +optional = true + +[dependencies.console] +package = "snarkvm-console" +path = "../../../console" +version = "=1.1.0" + +[dependencies.snarkvm-ledger-puzzle] +path = "../." +version = "=1.1.0" + +[dependencies.snarkvm-synthesizer-process] +path = "../../../synthesizer/process" +version = "=1.1.0" +optional = true + +[dependencies.snarkvm-synthesizer-program] +path = "../../../synthesizer/program" +version = "=1.1.0" +optional = true + +[dependencies.aleo-std] +version = "0.1.24" +default-features = false +optional = true + +[dependencies.anyhow] +version = "1.0.73" + +[dependencies.colored] +version = "2" + +[dependencies.indexmap] +version = "2.0" +features = [ "serde", "rayon" ] + +[dependencies.lru] +version = "0.12" +optional = true + +[dependencies.parking_lot] +version = "0.12" +optional = true + +[dependencies.rand] +version = "0.8" + +[dependencies.rand_chacha] +version = "0.3.1" + +[dependencies.rayon] +version = "1" +optional = true + +[dev-dependencies.console] +package = "snarkvm-console" +path = "../../../console" +features = [ "test" ] diff --git a/ledger/puzzle/epoch/LICENSE.md b/ledger/puzzle/epoch/LICENSE.md new file mode 100644 index 0000000000..d0af96c393 --- /dev/null +++ b/ledger/puzzle/epoch/LICENSE.md @@ -0,0 +1,194 @@ +Apache License +============== + +_Version 2.0, January 2004_ +_<>_ + +### Terms and Conditions for use, reproduction, and distribution + +#### 1. Definitions + +“License” shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +“Licensor” shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +“Legal Entity” shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, “control” means **(i)** the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the +outstanding shares, or **(iii)** beneficial ownership of such entity. + +“You” (or “Your”) shall mean an individual or Legal Entity exercising +permissions granted by this License. + +“Source” form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +“Object” form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +“Work” shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +“Derivative Works” shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +“Contribution” shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +“submitted” means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as “Not a Contribution.” + +“Contributor” shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +#### 2. Grant of Copyright License + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +#### 3. Grant of Patent License + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +#### 4. Redistribution + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +* **(a)** You must give any other recipients of the Work or Derivative Works a copy of +this License; and +* **(b)** You must cause any modified files to carry prominent notices stating that You +changed the files; and +* **(c)** You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. + +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +#### 5. Submission of Contributions + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +#### 6. Trademarks + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +#### 7. Disclaimer of Warranty + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +#### 8. Limitation of Liability + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +#### 9. Accepting Warranty or Additional Liability + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +_END OF TERMS AND CONDITIONS_ + +### APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets `[]` replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same “printed page” as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/ledger/puzzle/epoch/README.md b/ledger/puzzle/epoch/README.md new file mode 100644 index 0000000000..680ac3ac3b --- /dev/null +++ b/ledger/puzzle/epoch/README.md @@ -0,0 +1,5 @@ +# snarkvm-ledger-puzzle-epoch + +[![Crates.io](https://img.shields.io/crates/v/snarkvm-ledger-puzzle-epoch.svg?color=neon)](https://crates.io/crates/snarkvm-ledger-puzzle-epoch) +[![Authors](https://img.shields.io/badge/authors-Aleo-orange.svg)](https://aleo.org) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE.md) diff --git a/ledger/puzzle/epoch/docs/resources/k-ary-tree.png b/ledger/puzzle/epoch/docs/resources/k-ary-tree.png new file mode 100644 index 0000000000..1ce98e563e Binary files /dev/null and b/ledger/puzzle/epoch/docs/resources/k-ary-tree.png differ diff --git a/ledger/puzzle/epoch/docs/resources/merkle-puzzle.png b/ledger/puzzle/epoch/docs/resources/merkle-puzzle.png new file mode 100644 index 0000000000..93f3c09f99 Binary files /dev/null and b/ledger/puzzle/epoch/docs/resources/merkle-puzzle.png differ diff --git a/ledger/puzzle/epoch/docs/resources/synthesis-puzzle.png b/ledger/puzzle/epoch/docs/resources/synthesis-puzzle.png new file mode 100644 index 0000000000..3ddbe6110b Binary files /dev/null and b/ledger/puzzle/epoch/docs/resources/synthesis-puzzle.png differ diff --git a/ledger/puzzle/epoch/docs/spec.md b/ledger/puzzle/epoch/docs/spec.md new file mode 100644 index 0000000000..6eb61626bc --- /dev/null +++ b/ledger/puzzle/epoch/docs/spec.md @@ -0,0 +1,1043 @@ +# Aleo Mainnet Puzzle + +[Introduction](#introduction) + +[Goals](#goals) + +[Design](#design) + +[Security Analysis](#security-analysis) + +[Implementation](#implementation) + +[Testing](#testing) + +[Benchmarks](#benchmarks) + +[Governance](#governance) + +# Introduction + +The Aleo blockchain introduces a computational puzzle aimed at +incentivizing the acceleration of zkSNARKs and Aleo-specific program +optimizations. Historically, puzzles on Aleo's test networks targeted +the generation of entire proofs or focused on optimizing computationally +intensive aspects of proof generation, such as Multi-Scalar +Multiplications (MSM) and Number Theoretic Transforms (NTT). However, +advancements in these areas have reduced their dominance in proof +generation time, prompting a new focus for the next iteration. + +The puzzle sets its sights on enhancing synthesis, otherwise known as +witness generation. This area is particularly crucial for Aleo, as it +represents a significant portion of the time spent in generating proof +for Aleo programs. By directing efforts towards synthesis, the puzzle +aims to address a critical bottleneck specific to Aleo's ecosystem, +ensuring a more streamlined and efficient process for developers and +users alike. This strategic emphasis not only caters to the unique needs +of Aleo's platform but also fosters innovation and optimizations in the +broader ecosystem. + +# Goals + +The puzzle has been designed with the following goals in mind. + +- **Hardness:** Ensure that no adversary can compute solutions to the + puzzle faster than through random guessing. This requires the system + to be memoryless, or non-amortizable, meaning that the probability + of winning does not depend on the time spent computing a solution. + + +- **System Safety:** The design and its implementation must prevent + attacker-controlled inputs from causing denial of service (DoS) + attacks, crashes, code execution, or any other unexpected changes to + the system. + + +- **Uniquely-Determined Circuits:** Maintain the soundness and + uniqueness of opcode circuits in zero-knowledge proofs, preventing + the existence of multiple valid assignments that could allow for + cheaper puzzle attempts. + + +- **Consistency in Resource Consumption:** Distribute the puzzle + running time and resource consumption to minimize variance and the + risk of extreme behaviors, aiming for a distribution that is more + Gaussian-like than power-law-like. + + +- **Maximizing Usefulness:** The majority of the computation should + focus on "useful" algorithms. + +# Design + +## Overview + +We provide a high-level description of the puzzle's use in the protocol +below . + +1. Provers construct puzzle solutions and broadcast them to the + network. + + +2. Validators aggregate solutions and transactions into a set for the + next block via the consensus mechanism. + + - The set of solutions cannot exceed the `MAX_SOLUTIONS` allowed + in a block. + + - Validators are not required to verify solutions beforehand. + + +3. During block production, validators will process solutions in order, + accepting up to `MAX_SOLUTIONS` valid solutions and aborting the + rest. The ledger state is updated accordingly. + + - The validator maintains a ledger which stores the: + - `latest_epoch_hash`: The latest epoch hash. + + - `latest_proof_target`: The minimum target a solution must + reach to be accepted. + + - `cumulative_proof_target`: The aggregated sum of proof + targets for valid solutions, from the previous block. + + - `coinbase_target`: The expected sum of proof targets, + which acts as a threshold for difficulty adjustment. + + - A solution is valid if its: + + - `epoch_hash` matches the ledger's `latest_epoch_hash` + + - `proof_target`, computed for each solution, meets the + `latest_proof_target`. + + - Fewer than `MAX_SOLUTIONS` solutions have already been + accepted for this block. + + - A valid solution is rewarded proportionally to its share of the + sum of the `proof_target`s for the set of accepted solutions. + + - Each `proof_target` is added to `cumulative_proof_target`. + + - If the updated `cumulative_proof_target` exceeds the + `coinbase_target`, the next `coinbase_target` and next + `latest_proof_target` is updated according to a defined + retargeting algorithm. + + - If the block height reaches the next epoch, the + `latest_epoch_hash` is updated. + +The puzzle itself has two instantiations: the **Synthesis Puzzle** and +the **Merkle Puzzle**. The latter is smaller and used for testing +purposes. The two share common components and provide the same interface +to submit solutions. The two differ in the computational component +emphasized in the puzzle. The Merkle puzzle is intended to function as a +de-featured version of the synthesis puzzle. + +## Common Components + +### Inputs + +Both versions of the puzzle take the same set of inputs: + +- `address: Address**` The address that is rewarded, if the + puzzle solution is valid for the current proof target. + +- `epoch_hash: N::Blockhash` The current epoch block hash. A valid + solution for the current epoch must use the current epoch hash. If + any other epoch hash is used, the puzzle solution should **always** + be invalid. + +- `counter: u64` A counter that is varied across multiple attempts + of the puzzle for a given address and epoch hash. + +This 3-tuple of `(address, epoch_hash, counter)` defines a unique +attempt at a puzzle solution. This set of inputs is used to form a +per-attempt `nonce`, which is then used to seed an RNG to +deterministically generate unique, random internal values for a given +puzzle attempt. The internal values differ between the Synthesis Puzzle +and Merkle Puzzle. + +### K-ary Merkle Tree + +- Both versions of the puzzle use a K-ary Merkle Tree of `DEPTH` 8 + and `ARITY` 8. + +- The leaf and path hash functions is SHA-256. + +- A diagram of a K-ary Merkle Tree of `DEPTH` 5 and `ARITY + 8 is given below. + +![](resources/k-ary-tree.png) + +- Both versions of the puzzle produce a Merkle root, which is + converted into a solution `proof_target`. The target is compared + against the `latest_proof_target` which determines whether or not + the solution is valid. + +## Synthesis Puzzle + +The synthesis puzzle emphasizes synthesizing a valid R1CS assignment as +the key computational element of the puzzle. + +The steps for constructing a solution for synthesis puzzle are given +below: + +1. Construct an attempt-specific `nonce` from the `address`, + `epoch_hash`, and `counter`. + +2. Sample an `EpochProgram` using the `epoch_hash`. + +3. Sample an attempt-specific set of inputs using an RNG seeded by the + `nonce`. + +4. Synthesize the R1CS for the `EpochProgram` and puzzle inputs. + +5. Convert the R1CS assignment into a sequence of Merkle leaves. + +6. Compute the Merkle root and convert it into a `proof_target`. + +7. If the `latest_proof_target` meets the `proof_target`, submit + the `address`, `epoch_hash`, and `counter` as a solution. + Otherwise, repeat the steps above. + +### Sampling Programs + +Each epoch, an `EpochProgram` is sampled using the `epoch_hash`. The +`epoch_hash` is used to seed an RNG, which selects a sequence of +abstract instructions according to some fixed distribution. The abstract +instructions are then concretized into a valid program using the +`Register Table` to correctly track the active set of registers. + +Instructions are sampled from a defined instruction set by weight. The +weight is set according to the output entropy. + +Each entry in the instruction set is a vector of at most +`NUM_SEQUENCE_INSTRUCTIONS` is returned, each consisting of a tuple +with: + +- The instruction as [defined here](https://developer.aleo.org/aleo/opcodes). + +- The operands, which can be: + + - `Ephemeral` + + - `Input` + + - `Literal` + + - `Register` + + - `RegisterOffset` + +- The destinations. + + - `Ephemeral` + + - `Register` + +#### Destinations +Ephemeral destinations are locally available registers that are not +added to the register table. They can be used later in the sequence, but +are not available afterwards. + +Register destinations are registers stored in the register table. + +#### Operands +Register operands indicate that the register to be used must be the most +recent element in the register table. + +Ephemeral operands are registers locally available to the sequence. They +must be an ephemeral destination from a previous instruction in the +sequence. + +Input operands reference the original inputs to the program. + +Literal operands specify constants to be used as operands. + +Register offsets indicate that the register to be used must be from the +`RegisterTable`, offset by an index. That is, the 0-th index is the +most recent element in the register table, the 1-st index is the second +most recent and so on. + +#### An Example + +Below is an example of a defined sequence of instructions in the +instruction set. + +```rust +(vec![ + (Instruction::IsEq, + vec![ + Operand::Register(LiteralType::Field), + Operand::Literal(Literal::Field(Field::zero()))], + vec![ + Destination::Ephemeral(LiteralType::Boolean, 0) + ]), + (Instruction::Ternary, + vec![ + Operand::Ephemeral(LiteralType::Boolean, 0), + Operand::Input(LiteralType::Field, 0), + Operand::Register(LiteralType::Field)], + vec![ + Destination::Ephemeral(LiteralType::Field, 1)]), + (Instruction::Div, + vec![ + Operand::RegisterOffset(LiteralType::Field, 1), + Operand::Ephemeral(LiteralType::Field, 1)], + vec![Destination::Register(LiteralType::Field)])], +VERY_LOW) +``` + +This sequence, + +1. Loads the most recent `Field` register, checks if it is equal to + zero, stores the result into a new destination register, and stores + the register as the 0-th ephemeral register. + +2. Checks if the value in the 0-th ephemeral register is `true`. If + so, loads the 0-th input `Field` register. Otherwise, loads the + most recent `Field` register from the register table. Stores the + result into a new destination register, and stores the register as + the 1-st ephemeral register. + +3. Loads the 2-nd most recent `Field` register from the register + table, divides it by the 1-st ephemeral register, stores the result + into a new destination register, and stores the register as the most + recent `Field` register in the register table. + +### Register Table + +The register table initializes and stores active registers while +constructing the epoch program. +The table contains a 2-deep stack of registers for each `LiteralType`. +The table is initialized according to the preamble below. + +**Preamble** + +```aleo +input r0 as boolean.public; +input r1 as boolean.public; +input r2 as i8.public; +input r3 as i8.public; +input r4 as i16.public; +input r5 as i16.public; +input r6 as i32.public; +input r7 as i32.public; +input r8 as i64.public; +input r9 as i64.public; +input r10 as i128.public; +input r11 as i128.public; +input r12 as field.public; +input r13 as field.public; + +is.eq r1 r0 into r14; +is.eq r3 r2 into r15; +is.eq r5 r4 into r16; +is.eq r7 r6 into r17; +is.eq r9 r8 into r18; +is.eq r11 r10 into r19; + +hash.psd2 r12 into r20 as u8; +hash.psd2 r13 into r21 as u8; +hash.psd2 r12 into r22 as u16; +hash.psd2 r13 into r23 as u16; +hash.psd2 r12 into r24 as u32; +hash.psd2 r13 into r25 as u32; +hash.psd2 r12 into r26 as u64; +hash.psd2 r13 into r27 as u64; +hash.psd2 r12 into r28 as u128; +hash.psd2 r13 into r29 as u128; + +mul.w r3 r2 into r30; +mul.w r5 r4 into r31; +mul.w r7 r6 into r32; +mul.w r9 r8 into r33; +mul.w r11 r10 into r34; + +ternary r15 r30 r2 into r35; +ternary r16 r31 r4 into r36; +ternary r17 r32 r6 into r37; +ternary r18 r33 r8 into r38; +ternary r19 r34 r10 into r39; +``` + +#### Instruction Variants + +Below are the all instruction variants in the puzzle and whether or not +they are sampled. + +- `Abs`: No +- `AbsWrapped`: Yes +- `Add`: Yes +- `AddWrapped`: Yes +- `And`: Yes +- `AssertEq`: No +- `AssertNeq`: No +- `BranchEq`: No +- `BranchNeq`: No +- `Cast`: No +- `CastLossy`: Yes +- `CommitBhp256`: No +- `CommitBhp512`: No +- `CommitBhp768`: No +- `CommitBhp1024`: No +- `CommitPed64`: No +- `CommitPed128`: No +- `Div`: Yes +- `DivWrapped`: Yes +- `Double`: No +- `Gt`: Yes +- `Gte`: Yes +- `HashBhp256`: Yes +- `HashBhp512`: No +- `HashBhp768`: No +- `HashBhp1024`: No +- `HashKeccak256`: No +- `HashKeccak384`: No +- `HashKeccak512`: No +- `HashPed64`: Yes +- `HashPed128`: No +- `HashPsd2`: No +- `HashPsd4`: No +- `HashPsd8`: No +- `HashSha3256`: No +- `HashSha3384`: No +- `HashSha3512`: No +- `Inv`: Yes +- `IsEq`: Yes +- `IsNeq`: Yes +- `Lt`: Yes +- `Lte`: Yes +- `Mod`: Yes +- `Mul`: Yes +- `MulWrapped`: Yes +- `Nand`: Yes +- `Neg`: Yes +- `Nor`: Yes +- `Not`: Yes +- `Or`: Yes +- `Pow`: Yes +- `PowWrapped`: Yes +- `Rem`: No +- `RemWrapped`: Yes +- `Shl`: No +- `ShlWrapped`: Yes +- `Shr`: No +- `ShrWrapped`: Yes +- `Sqrt`: No +- `Square`: Yes +- `Sub`: No +- `SubWrapped`: Yes +- `Ternary`: Yes +- `Xor`: Yes + +### Diagram + +![](resources/synthesis-puzzle.png) + +### Pseudocode + +``` +############################################################################# +# Inputs +############################################################################# + +# The address to be rewarded +Address address + +# The block hash of the latest epoch +N::Blockhash epoch_hash + +# The counter +u64 counter + +# The target difficulty +u64 puzzle_target + +############################################################################# +# Sample the epoch program, once per epoch +############################################################################# + +EpochProgram program = EpochProgram::new(epoch_hash) + +############################################################################# +# Construct a valid solution +############################################################################# + +counter = 0 +while (1) + # Generate nonce for the RNG + # Note, this nonce should be unique to **all** attempts + u64 nonce = sha2(sha2(address, epoch_hash, counter)).to_u64() + + # Seed the RNG using nonce + rng = chacha(nonce) + + # Construct the inputs to the program + Vec inputs = program.construct_inputs(rng) + + # Construct the leaves of the Merkle Tree + Vec> leaves = program.to_leaves(inputs); + + # Generate the root of a SHA3-256 Merkle Tree with arity 8 over the leaves + u256 root = merkle_tree(leaves) + + # Get the lower 64 bits of the root + u64 root_as_u64 = root.to_u64() + + # Compute the target + u64 target = if root_as_u64 == 0u64 { + u64::MAX + } else { + u64::MAX / root_as_u64 + } + + # If the candidate does not meet the target, try again + if target < puzzle_target + counter++ + next + + return (counter, root) +``` + +## Merkle Puzzle + +The merkle puzzle emphasizes computing the root of a Merkle tree as the +key computational element of the puzzle. + +The steps for constructing a solution for the Merkle puzzle are given +below: + +1. Construct an attempt-specific `nonce` from the `address`, + `epoch_hash`, and `counter`. + +2. Sample the number of Merkle leaves using the `epoch_hash`. + +3. Sample the Merkle leaves using an RNG, seeded by the `nonce`. + +4. Compute the Merkle root and convert it into a `target`. + +5. If the `target` meets the `proof_target`, submit the + `address`, `epoch_hash`, and `counter` as a solution. + Otherwise, repeat the steps above. + +### Diagram + +![](resources/merkle-puzzle.png) + +### Pseudocode + +``` +############################################################################# +# Inputs +############################################################################# + +# The address to be rewarded +Address address + +# The block hash of the latest epoch +N::Blockhash epoch_hash + +# The counter +u64 counter + +# The target difficulty +u64 puzzle_target + +############################################################################# +# Sample the number of leaves in the Merkle Tree, once per epoch +############################################################################# + +# Seed the RNG using the lower 64 bits of the epoch hash +u64 epoch_hash_as_u64 = epoch_hash.to_u64() +epoch_rng = chacha(epoch_hash_to_u64) + +# Sample the number of leaves +u32 num_leaves = epoch_rng.sample_range(100000, 200000) + +############################################################################# +# Construct a valid solution +############################################################################# + +counter = 0 +while (1) + # Generate nonce for the RNG + # Note, this nonce should be unique to **all** attempts + u64 nonce = sha2(sha2(addr, epoch_hash, counter)).to_u64() + + # Seed the RNG using nonce + rng = chacha(nonce) + + # Construct the leaves of the Merkle Tree + Vec> leaves = rng.sample_leaves(num_leaves) + + # Generate the root of a SHA3-256 Merkle Tree with arity 8 over the leaves + u256 root = merkle_tree(leaves) + + # Get the lower 64 bits of the root + u64 root_as_u64 = root.to_u64() + + # Compute the target + u64 target = if root_as_u64 == 0u64 { + u64::MAX + } else { + u64::MAX / root_as_u64 + } + + # If the candidate does not meet the target, try again + if target < puzzle_target + counter++ + next + + return (counter, root) +``` + +# Security Analysis + +## Hardness + +Precomputation of instructions into a lookup table is generally not an +effective strategy given that the size of a lookup table grows +exponentially in the number of inputs and outputs of the operation. +However, it might be possible when there are many chained operations +operating over a small input space, and when solutions can be submitted +for a particular program for a long enough time. We did not identify +instructions at risk of precomputation. + +In order for the solution to the entire puzzle to not be predictable, we +need the value of intermediate registers to also not be predictable. If +they were, it could enable precomputation, but also more parallelization +than intended, by allowing synthesis to be initiated from multiple +points in the circuit concurrently. The risk of parallelization is +reduced if: + +1. There are very few operations with low output entropy. This is the +case in Aleo's PoW, because instructions with low output entropy have +been given a low sampling weight. Note that we can distinguish two ways +in which the predictability of intermediate registers can be measured: + +- If *individual* operators and operands have low output entropy. For + example, the output entropy of **is.eq** over randomly sampled u8 + inputs is **0.037** + $= \ - 1\ *\ \frac{2^{8}}{2^{16}}\log\frac{2^{8}}{2^{16}} + \frac{2^{16} - {\ 2}^{8}}{2^{16}}\log\frac{2^{16} - {\ 2}^{8}}{2^{16}}$. + +- If *combinations* of operators and operands have low output entropy. + For example, the outputs of f(X, Y, Z) = { **sub** (**add** X Y) Z } + where (X, Y, Z) are randomly sampled u8 inputs has a gaussian + distribution with [standard + deviation](https://en.wikipedia.org/wiki/Standard_deviation#Identities_and_mathematical_properties) + of ~128 and resulting [output + entropy](https://en.wikipedia.org/wiki/Entropy_(information_theory)#Entropy_for_continuous_random_variables) + of 6.27 bits. Different distributions and lower standard deviations + result in lower output entropy. + +2. Sampled programs are structured in such a way that they periodically +operate on values from older registers. This is the case in Aleo's PoW, +because various operations access much earlier registers using +`RegisterOffset`. + +## The easy program problem + +RandomX suffers from the [easy program problem](https://github.com/tevador/RandomX/blob/master/doc/design.md#12-the-easy-program-problem), +whereby an attacker with hardware optimized for a subset of operations +might keep sampling programs, thereby landing on programs for which it +has an unfair advantage. They resolve this by [chaining multiple programs together](https://github.com/tevador/RandomX/blob/master/doc/design.md#a-the-effect-of-chaining-vm-executions), +whereby the output of the previous program determines the input for the +next. This ensures miners which want to have a high chance of success +need to support the full instruction and operand set. + +In contrast to RandomX, Aleo's PoW programs are fixed per epoch. Still, +it is possible for a program to mostly contain a subset of operations, +and for a miner to be specialized in that subset of operations. The +solution for this is to ensure operations (with high output entropy) are +equally sampled and empirically validate that a significant enough +portion of programs contains the desired range of operations. + +# Implementation + +## Key Components + +### Puzzle Trait + +- `PuzzleTrait` defines the interface for all puzzles. + +- Both **Synthesis Puzzle** and **Merkle Puzzle** satisfy this + interface. + +### Puzzle + +- An instance of the puzzle, either the **Synthesis Puzzle** or + **Merkle Puzzle.** + +### Solution + +- A puzzle solution. + +- Constructed from an **address**, **epoch_hash**, and **counter.** + +### SolutionID + +- A unique identifier for a puzzle solution. + +- The `SolutionID` must be unique for all solutions submitted to the + network. + +- The protocol checks for uniqueness and rejects solutions whose + solution IDs have already been recorded by the ledger. + +### PuzzleSolutions + +- An aggregate of valid puzzle solutions. + +## Constants + +### GENESIS_COINBASE_TARGET + +- The coinbase target for the genesis block. This should be + `MAX_SOLUTIONS * GENESIS_PROOF_TARGET`. This is the minimum + allowed coinbase target. + +### GENESIS_PROOF_TARGET + +- The proof target for the genesis block. This is the minimum allowed + proof target. + +### MAX_SOLUTIONS + +- The maximum number of valid solutions in a block. A block may be + constructed with a greater number of valid solutions, but only + `MAX_SOLUTIONS` should be accepted. The rest, regardless of + validity should be aborted. + +# Testing + +### `merkle::test_num_leaves` + +- Checks that the sampled number of leaves for a given epoch is within + the expected range. + +### `merkle::test_to_leaves` + +- Checks that the number of leaves generated by + `MerklePuzzle::to_leaves` generates the correct number of leaves. + +### `merkle::test_to_all_leaves` + +- Check that the number of leaves generated for each epoch hash by + `MerklePuzzle::to_all_leaves` is correct and matches the leaves + generated by `MerklePuzzle::to_leaves`. + +### `instruction_set::check_weights_are_valid` + +- Check that the sum of the weights of the sampled instructions do not + exceed `u16::MAX`. + +### `instruction_set::check_ephemeral_registers_are_valid` + +- Check that each instruction sequence in `instruction_set`: + + - uses sequentially increasing ephemeral registers as + destinations. + + - uses valid ephemeral registers as operands. + +### `instruction_set::check_register_offsets_are_valid` + +- Check that `PuzzleOperand::RegisterOffset`s do not look back by + more than 1 register. + +- This is necessary to ensure that the generated instructions use + `RegisterTable` properly. + +### `instruction_set::check_that_instructions_are_valid` + +- Check that each instruction sequence does not exceed + `NUM_SEQUENCE_INSTRUCTIONS` + +- Check that no instruction is a `BranchEq` or `BranchNeq`. + +### `instruction_type::test_puzzle_instruction_type` + +- Check that `PuzzleInstructionType` is correctly initialized based + on its numerical variant. + +### `instruction_type::test_puzzle_instruction_type_all` + +- Check that `NUM_PUZZLE_INSTRUCTION_VARIANTS` matches the number of + `PuzzleInstructionType`s. + +- Check that each instruction type matches its expected numerical + variant. + +### `instruction_type::test_puzzle_instruction_type_opcode` + +- Check that each `PuzzleInstructionType` variant has a defined + opcode. + +### `instruction_type::test_puzzle_instruction_type_num_literals` + +- Check that the number of operands for each `PuzzleInstructionType` + variant is within the expected range. + +### `synthesis::helpers::test_sample_instructions` + +- Checks that the number of instructions sampled for a given epoch is + within the expected range. + +### `synthesis::helpers::test_sample_program` + +- Checks that the epoch program sampled for a given epoch is + well-formed: + + - The program is syntactically valid. + + - The number of inputs is correct. + + - The number of instructions is within the expected range. + +### `synthesis::helpers::test_sample_instructions_is_deterministic` + +- Checks that the sets of instructions sampled for the same epoch + match. + +### `synthesis::helpers::register_table::test_register_table` + +- Check that the register table: + + - contains the correct number of entries. + + - contains the correct `LiteralType`s. + + - contains the correct number of registers per `LiteralType`. + + - initializes to the correct `next_register_locator`. + +### `synthesis::helpers::register_table::test_get_k_th_last_register` + +- Checks that for each `LiteralType` in the `RegisterTable` that + getting the k-th last register retrieves the expected register. + +### `synthesis::helpers::register_table::test_input_block_is_well_formed` + +- Check that a `Program` formed from `RegisterTable::input_block` + forms a valid program with the `NUM_INPUTS` inputs and + `NUM_PREAMBLE_INSTRUCTIONS` instructions. + +### `synthesis::test_get_epoch_program` + +- Check that the sampled `EpochProgram` matches given the same epoch + hash. + +### `synthesis::test_to_leaves` + +- Checks that the sampled inputs for the sampled `EpochProgram` + matches given the same epoch hash and RNG seed. + +### `synthesis::test_to_all_leaves` + +- Check that the number of leaves generated for each epoch hash and + seed by `SynthesisPuzzle::to_all_leaves` is correct and matches + those generated by `SynthesisPuzzle::to_leaves`. + +### `synthesis::program::test_new_is_deterministic` + +- Checks that the programs sampled for the same epoch match + +### `synthesis::program_test_instructions_succeeds` + +- Checks that the instructions can be correctly retrieved from an + `EpochProgram` + +### `synthesis::program::to_leaves::test_next_power_of_n` + +- Check that the next power of `n` greater than `base` is correct. + +### `synthesis::program::test_next_power_of_n_edge_cases` + +- Check that the next power of `n` for `n` equal to `0` or `1` + returns `None`. + +### `synthesis::program::test_next_power_of_n_overflow` + +- Check that the next power of `n` returns `None` on overflow. + +### `puzzle::test_puzzle` + +- For various numbers of solutions: + + - check that `Puzzle::prove` correctly generates a solution. + + - check that `Puzzle::check_solutions` succeeds for the correct + epoch hash and target. + + - check that `Puzzle::check_solutions` fails for the incorrect + epoch hash. + +### `puzzle::test_prove_with_minimum_proof_target` + +- Checks that `Puzzle::prove` produces a invalid solution for a + proof target greater than the solution's proof target. + +- Checks that `Puzzle::prove` produces a valid solution for a proof + target equal to the solution's proof target. + +### `puzzle::test_prove_with_no_minimum_proof_target` + +- Checks that `Puzzle::prove` produces a valid solution, if the + proof target is 0. + +### `puzzle::test_check_solutions_with_duplicate_nonces` + +- Check that a `PuzzleSolutions` object cannot be instantiated with + duplicate solutions. + +### `puzzle::test_get_proof_targets_without_cache` + +- Check that the proof target is correctly computed without caching in + the `Puzzle` object. + +### `puzzle::test_get_proof_targets_with_partial_cache` + +- Check that the proof target is correctly computed with caching in + the `Puzzle` object. + +### `puzzle::solutions::test_new_is_not_empty` + +- Check that `PuzzleSolutions` cannot be initialized without a + solution. + +### `puzzle::solutions::test_len` + +- Check that `PuzzleSolutions::len` returns the correct number of + solutions. + +### `puzzle::solutions::test_is_empty` + +- Check that `PuzzleSolutions`, initialized with solutions, is not + empty. + +### `puzzle::solutions::test_solution_ids` + +- Check that `PuzzleSolutions::solution_ids` returns the correct + number of solutions. + +### `puzzle::solutions::test_get_solution` + +- Check that `PuzzleSolutions::get_solution` returns the correct + solution. + +### `puzzle::solutions::test_to_accumulator_point` + +- Check that `PuzzleSolutions::to_accumulator_point` returns the + expected value. + +### `ledger::test_duplicate_solutions_ids` + +- Constructs a valid solution, meeting the proof target. + +- Attempts to create a block with two instances of the valid solution + and checks that block production fails. + +- Attempts to create a block with one instance of the valid solution + and checks that block production succeeds. + +### `ledger::test_excess_invalid_solution_ids` + +- Samples `MAX_SOLUTIONS` valid solutions, each meeting the required + proof target. + +- Samples `MAX_SOLUTIONS` invalid solutions, each failing to meet + the required proof target. + +- Shuffles the valid and invalid solutions together. + +- Checks that the valid solutions are all accepted, while the invalid + solutions are rejected. + +### `ledger::test_excess_valid_solution_ids` + +- Samples `2 * MAX_SOLUTIONS` valid solutions, each meeting the + required proof target. + +- Checks that the first `MAX_SOLUTIONS` solutions are accepted, + while the rest are aborted. + +### `vm::test_vm_puzzle` + +- Checks that the VM correctly downcasts the puzzle instance and uses + the underlying traits to generate a valid solution. + +# Benchmarks + +The benchmarks were run on a 2021 Apple M1 Max with 32 GB RAM. + +## Synthesis Puzzle + +### `Puzzle::prove` + +| \# of Instructions | Runtime (ms) | +| ------------------ | ------------ | +| 10 | 68.87 | +| 100 | 119.5 | +| 1000 | 423.6 | + +### `Puzzle::get_all_leaves` +| \# of Solutions | \# of Instructions | Runtime (ms) | +| ---------------------- | ------------------ | ------------ | +| 1 | 10 | 58.58 | +| 1 | 100 | 85.80 | +| 1 | 1000 | 359.2 | +| 2 | 100 | 96.42 | +| 4 | 100 | 99.292 | + +### `Puzzle::check_solutions` +| \# of Solutions | \# of Instructions | Runtime (ms) | +| ----------------------- | ------------------ | ------------ | +| 1 | 10 | 69.08 | +| 1 | 100 | 120.7 | +| 1 | 1000 | 433.1 | +| 2 | 100 | 142.5 | +| 4 | 100 | 183.7 | + +Note that the number of leaves produced by an instance of the Synthesis +Puzzle is dependent on the program constructed from the sampled epoch +hash. Each benchmark iteration samples a new epoch program and each +benchmark run performs 50 iterations. + +## Merkle Puzzle + +### `Puzzle::prove` +| \# of Leaves | Runtime (ms) | +| ------------- | ------------ | +| 10 | 0.048 | +| 100 | 0.285 | +| 1000 | 1.142 | +| 10000 | 9.989 | +| 100000 | 96.52 | +| 1000000 | 942.7 | + +### `Puzzle::get_all_leaves` +| \# of Solutions | \# of Leaves | Runtime (ms) | +| ---------------------- | ------------ | ------------ | +| 1 | 1000 | 0.461 | +| 1 | 10000 | 4.594 | +| 1 | 100000 | 54.74 | +| 1 | 1000000 | 581.4 | +| 2 | 100000 | 62.44 | +| 4 | 100000 | 59.76 | + +## `Puzzle::check_solutions` +| \# of Solutions | \# of Leaves | Runtime (ms) | +| ----------------------- | ------------ | ------------ | +| 1 | 1000 | 1.412 | +| 1 | 10000 | 9.993 | +| 1 | 100000 | 99.47 | +| 1 | 1000000 | 920.2 | +| 2 | 100000 | 126.7 | +| 4 | 100000 | 200.99 | + +# Governance + +The governance of the puzzle will be handled by the Aleo Network +Foundation, through the defined protocol upgrade process. diff --git a/ledger/puzzle/epoch/src/lib.rs b/ledger/puzzle/epoch/src/lib.rs new file mode 100644 index 0000000000..8328514422 --- /dev/null +++ b/ledger/puzzle/epoch/src/lib.rs @@ -0,0 +1,24 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +#[cfg(feature = "merkle")] +pub mod merkle; +#[cfg(feature = "merkle")] +pub use merkle::*; + +#[cfg(feature = "synthesis")] +pub mod synthesis; +#[cfg(feature = "synthesis")] +pub use synthesis::*; diff --git a/ledger/puzzle/epoch/src/merkle/mod.rs b/ledger/puzzle/epoch/src/merkle/mod.rs new file mode 100644 index 0000000000..9161e7e452 --- /dev/null +++ b/ledger/puzzle/epoch/src/merkle/mod.rs @@ -0,0 +1,135 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 console::{ + network::Network, + prelude::{FromBytes, ToBits as TBits, ToBytes, Uniform, cfg_into_iter}, + types::Field, +}; +use snarkvm_ledger_puzzle::PuzzleTrait; + +use anyhow::Result; +use core::marker::PhantomData; +use rand::{Rng, SeedableRng}; +use rand_chacha::ChaChaRng; + +#[cfg(not(feature = "serial"))] +use rayon::prelude::*; + +const MIN_NUMBER_OF_LEAVES: usize = 100_000; +const MAX_NUMBER_OF_LEAVES: usize = 200_000; + +pub struct MerklePuzzle(PhantomData); + +impl PuzzleTrait for MerklePuzzle { + /// Initializes a new instance of the puzzle. + fn new() -> Self { + Self(PhantomData) + } + + /// Returns the leaves for the puzzle, given the epoch hash and seeded RNG. + fn to_leaves(&self, epoch_hash: N::BlockHash, rng: &mut ChaChaRng) -> Result>> { + // Sample a random number of leaves. + let num_leaves = self.num_leaves(epoch_hash)?; + // Sample random field elements for each of the leaves, and convert them to bits. + let leaves = (0..num_leaves).map(|_| Field::::rand(rng).to_bits_le()).collect::>(); + // Return the leaves. + Ok(leaves) + } + + /// Returns the batches of leaves for the puzzle, given the epoch hash and seeded RNGs. + fn to_all_leaves(&self, epoch_hash: N::BlockHash, rngs: Vec) -> Result>>> { + // Sample a random number of leaves. + let num_leaves = self.num_leaves(epoch_hash)?; + // Construct the epoch inputs. + let leaves = cfg_into_iter!(rngs) + .map(|mut rng| { + // Sample random field elements for each of the leaves, and convert them to bits. + (0..num_leaves).map(|_| Field::::rand(&mut rng).to_bits_le()).collect::>() + }) + .collect::>(); + // Return the leaves. + Ok(leaves) + } +} + +impl MerklePuzzle { + /// Returns the number of leaves given the epoch hash. + pub fn num_leaves(&self, epoch_hash: N::BlockHash) -> Result { + // Prepare the seed. + let seed = u64::from_bytes_le(&epoch_hash.to_bytes_le()?[0..8])?; + // Seed a random number generator from the epoch hash. + let mut epoch_rng = ChaChaRng::seed_from_u64(seed); + // Sample a random number of leaves. + Ok(epoch_rng.gen_range(MIN_NUMBER_OF_LEAVES..=MAX_NUMBER_OF_LEAVES)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + type CurrentNetwork = console::network::MainnetV0; + + #[test] + fn test_num_leaves() { + // Initialize the epoch hash. + let epoch_hash = ::BlockHash::default(); + // Initialize the puzzle. + let puzzle = MerklePuzzle::::new(); + // Sample the number of leaves. + let num_leaves = puzzle.num_leaves(epoch_hash).unwrap(); + // Ensure the number of leaves is within the expected range. + assert!((MIN_NUMBER_OF_LEAVES..=MAX_NUMBER_OF_LEAVES).contains(&num_leaves)); + } + + #[test] + fn test_to_leaves() { + // Initialize the epoch hash. + let epoch_hash = ::BlockHash::default(); + // Initialize the puzzle. + let puzzle = MerklePuzzle::::new(); + // Sample the number of leaves. + let num_leaves = puzzle.num_leaves(epoch_hash).unwrap(); + // Sample the leaves. + let leaves = puzzle.to_leaves(epoch_hash, &mut ChaChaRng::seed_from_u64(0)).unwrap(); + // Ensure the number of leaves is within the expected range. + assert_eq!(leaves.len(), num_leaves); + } + + #[test] + fn test_to_all_leaves() { + // Initialize the epoch hash. + let epoch_hash = ::BlockHash::default(); + // Initialize the puzzle. + let puzzle = MerklePuzzle::::new(); + // Sample the number of leaves. + let num_leaves = puzzle.num_leaves(epoch_hash).unwrap(); + // Sample the leaves. + let leaves = + puzzle.to_all_leaves(epoch_hash, vec![ChaChaRng::seed_from_u64(0), ChaChaRng::seed_from_u64(1)]).unwrap(); + // Ensure the number of leaves is within the expected range. + assert_eq!(leaves.len(), 2); + assert_eq!(leaves[0].len(), num_leaves); + assert_eq!(leaves[1].len(), num_leaves); + + // Now, ensure it matches with the call to `to_leaves`. + let leaves_single = puzzle.to_leaves(epoch_hash, &mut ChaChaRng::seed_from_u64(0)).unwrap(); + assert_eq!(leaves_single, leaves[0]); + + let leaves_single = puzzle.to_leaves(epoch_hash, &mut ChaChaRng::seed_from_u64(1)).unwrap(); + assert_eq!(leaves_single, leaves[1]); + } +} diff --git a/ledger/puzzle/epoch/src/synthesis/helpers/destination.rs b/ledger/puzzle/epoch/src/synthesis/helpers/destination.rs new file mode 100644 index 0000000000..b9be02f2e9 --- /dev/null +++ b/ledger/puzzle/epoch/src/synthesis/helpers/destination.rs @@ -0,0 +1,36 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 console::program::LiteralType; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub enum PuzzleDestination { + Ephemeral(LiteralType, u16), + Register(LiteralType), +} + +impl PuzzleDestination { + /// Returns whether or not the puzzle operand is an ephemeral register. + #[inline] + pub fn is_ephemeral(&self) -> bool { + matches!(self, Self::Ephemeral(_, _)) + } + + /// Returns whether or not the puzzle operand is a register. + #[inline] + pub fn is_register(&self) -> bool { + matches!(self, Self::Register(_)) + } +} diff --git a/ledger/puzzle/epoch/src/synthesis/helpers/instruction_set.rs b/ledger/puzzle/epoch/src/synthesis/helpers/instruction_set.rs new file mode 100644 index 0000000000..81f7bf27ab --- /dev/null +++ b/ledger/puzzle/epoch/src/synthesis/helpers/instruction_set.rs @@ -0,0 +1,2837 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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::synthesis::helpers::{PuzzleDestination, PuzzleInstructionType, PuzzleOperand}; +use console::{ + prelude::Zero, + program::{Field, Literal, LiteralType, Network}, + types::{I8, I16, I32, I64, I128, U8, U16, U32, U64, U128}, +}; + +type Instruction = PuzzleInstructionType; +type Operand = PuzzleOperand; +type Destination = PuzzleDestination; + +/// A type alias for the instruction set. +/// The instruction set is a vector of tuples, where each tuple contains: +/// - A vector of tuples, where each tuple contains: +/// - The instruction. +/// - The operands. +/// - The destination types. +/// - The sampling weight of the instruction set. +pub type InstructionSet = Vec<(Vec<(Instruction, Vec>, Vec)>, u16)>; + +// TODO: ultimately we can replace variables with constants and remove the non_snake_case +#[rustfmt::skip] +pub fn instruction_set() -> InstructionSet { + // Initialize constants for the instruction weights. + const DEFAULT: u16 = 512; + const DEFAULT_BOOLEAN: u16 = 4; + const DEFAULT_U8: u16 = 4; + const DEFAULT_U16: u16 = 256; + const DEFAULT_U32: u16 = 512; + const DEFAULT_U64: u16 = 512; + const DEFAULT_U128: u16 = 512; + const DEFAULT_I8: u16 = 4; + const DEFAULT_I16: u16 = 256; + const DEFAULT_I32: u16 = 512; + const DEFAULT_I64: u16 = 512; + const DEFAULT_I128: u16 = 512; + + const NUM_CAST: u16 = 200; + const NUM_POWER: u16 = 20; + + const VERY_LOW: u16 = 4; + const LOW: u16 = 40; + const MEDIUM_LOW: u16 = 128; + + const DIV_DIVIDER: u16 = 128; + const U128_DIVIDER: u16 = 512; + + vec![ + // abs + (vec![(Instruction::Abs, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::Abs, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::Abs, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::Abs, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::Abs, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + // abs.w + (vec![(Instruction::AbsWrapped, vec![Operand::Register(LiteralType::I8)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::AbsWrapped, vec![Operand::Register(LiteralType::I16)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], LOW), + (vec![(Instruction::AbsWrapped, vec![Operand::Register(LiteralType::I32)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], LOW), + (vec![(Instruction::AbsWrapped, vec![Operand::Register(LiteralType::I64)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], LOW), + (vec![(Instruction::AbsWrapped, vec![Operand::Register(LiteralType::I128)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], LOW), + // add + (vec![(Instruction::Add, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], DEFAULT), + (vec![(Instruction::Add, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::Add, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::Add, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::Add, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::Add, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::Add, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::Add, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::Add, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::Add, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::Add, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // add.w + (vec![(Instruction::AddWrapped, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], DEFAULT_I8), + (vec![(Instruction::AddWrapped, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], DEFAULT_I16), + (vec![(Instruction::AddWrapped, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], DEFAULT_I32), + (vec![(Instruction::AddWrapped, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], DEFAULT_I64), + (vec![(Instruction::AddWrapped, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], DEFAULT_I128), + (vec![(Instruction::AddWrapped, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], DEFAULT_U8), + (vec![(Instruction::AddWrapped, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], DEFAULT_U16), + (vec![(Instruction::AddWrapped, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], DEFAULT_U32), + (vec![(Instruction::AddWrapped, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], DEFAULT_U64), + (vec![(Instruction::AddWrapped, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], DEFAULT_U128), + // and + (vec![(Instruction::And, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::Boolean)], vec![Destination::Ephemeral(LiteralType::Boolean, 0)])], DEFAULT_BOOLEAN), + (vec![(Instruction::And, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::And, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], LOW), + (vec![(Instruction::And, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], LOW), + (vec![(Instruction::And, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], LOW), + (vec![(Instruction::And, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], LOW), + (vec![(Instruction::And, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], DEFAULT_U8), + (vec![(Instruction::And, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], LOW), + (vec![(Instruction::And, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], LOW), + (vec![(Instruction::And, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], LOW), + (vec![(Instruction::And, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], LOW), + // assert.eq + (vec![(Instruction::AssertEq, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::Boolean)], vec![])], 0), + (vec![(Instruction::AssertEq, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![])], 0), + (vec![(Instruction::AssertEq, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![])], 0), + (vec![(Instruction::AssertEq, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![])], 0), + (vec![(Instruction::AssertEq, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![])], 0), + (vec![(Instruction::AssertEq, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![])], 0), + (vec![(Instruction::AssertEq, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![])], 0), + (vec![(Instruction::AssertEq, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![])], 0), + (vec![(Instruction::AssertEq, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![])], 0), + (vec![(Instruction::AssertEq, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![])], 0), + (vec![(Instruction::AssertEq, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![])], 0), + (vec![(Instruction::AssertEq, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![])], 0), + // assert.neq + (vec![(Instruction::AssertNeq, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::Boolean)], vec![])], 0), + (vec![(Instruction::AssertNeq, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![])], 0), + (vec![(Instruction::AssertNeq, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![])], 0), + (vec![(Instruction::AssertNeq, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![])], 0), + (vec![(Instruction::AssertNeq, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![])], 0), + (vec![(Instruction::AssertNeq, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![])], 0), + (vec![(Instruction::AssertNeq, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![])], 0), + (vec![(Instruction::AssertNeq, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![])], 0), + (vec![(Instruction::AssertNeq, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![])], 0), + (vec![(Instruction::AssertNeq, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![])], 0), + (vec![(Instruction::AssertNeq, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![])], 0), + (vec![(Instruction::AssertNeq, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![])], 0), + // cast + (vec![(Instruction::Cast, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::Cast, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::Cast, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::Cast, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::Cast, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + // cast.lossy + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)]), + (Instruction::CastLossy, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], NUM_CAST), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)]), + (Instruction::CastLossy, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], NUM_CAST), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)]), + (Instruction::CastLossy, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], NUM_CAST), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)]), + (Instruction::CastLossy, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], NUM_CAST), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)]), + (Instruction::CastLossy, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], NUM_CAST), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)]), + (Instruction::CastLossy, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], NUM_CAST), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)]), + (Instruction::CastLossy, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], NUM_CAST), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)]), + (Instruction::CastLossy, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], NUM_CAST), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)]), + (Instruction::CastLossy, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], NUM_CAST), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)]), + (Instruction::CastLossy, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], NUM_CAST), + // div + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::Field), Operand::Literal(Literal::Field(Field::zero()))], vec![Destination::Ephemeral(LiteralType::Boolean, 0)]), + (Instruction::Ternary, vec![Operand::Ephemeral(LiteralType::Boolean, 0), Operand::Input(LiteralType::Field, 0), Operand::Register(LiteralType::Field)], vec![Destination::Ephemeral(LiteralType::Field, 1)]), + (Instruction::Div, vec![Operand::RegisterOffset(LiteralType::Field, 1), Operand::Ephemeral(LiteralType::Field, 1)], vec![Destination::Register(LiteralType::Field)])], VERY_LOW), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I8), Operand::Literal(Literal::I8(I8::new(1)))], vec![Destination::Ephemeral(LiteralType::I8, 0)]), + (Instruction::Div, vec![Operand::RegisterOffset(LiteralType::I8, 1), Operand::Ephemeral(LiteralType::I8, 0)], vec![Destination::Ephemeral(LiteralType::I8, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I16), Operand::Literal(Literal::I16(I16::new(1)))], vec![Destination::Ephemeral(LiteralType::I16, 0)]), + (Instruction::Div, vec![Operand::RegisterOffset(LiteralType::I16, 1), Operand::Ephemeral(LiteralType::I16, 0)], vec![Destination::Ephemeral(LiteralType::I16, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I32), Operand::Literal(Literal::I32(I32::new(1)))], vec![Destination::Ephemeral(LiteralType::I32, 0)]), + (Instruction::Div, vec![Operand::RegisterOffset(LiteralType::I32, 1), Operand::Ephemeral(LiteralType::I32, 0)], vec![Destination::Ephemeral(LiteralType::I32, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I64), Operand::Literal(Literal::I64(I64::new(1)))], vec![Destination::Ephemeral(LiteralType::I64, 0)]), + (Instruction::Div, vec![Operand::RegisterOffset(LiteralType::I64, 1), Operand::Ephemeral(LiteralType::I64, 0)], vec![Destination::Ephemeral(LiteralType::I64, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I128), Operand::Literal(Literal::I128(I128::new(1)))], vec![Destination::Ephemeral(LiteralType::I128, 0)]), + (Instruction::Div, vec![Operand::RegisterOffset(LiteralType::I128, 1), Operand::Ephemeral(LiteralType::I128, 0)], vec![Destination::Ephemeral(LiteralType::I128, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U8), Operand::Literal(Literal::U8(U8::new(1)))], vec![Destination::Ephemeral(LiteralType::U8, 0)]), + (Instruction::Div, vec![Operand::RegisterOffset(LiteralType::U8, 1), Operand::Ephemeral(LiteralType::U8, 0)], vec![Destination::Ephemeral(LiteralType::U8, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U16), Operand::Literal(Literal::U16(U16::new(1)))], vec![Destination::Ephemeral(LiteralType::U16, 0)]), + (Instruction::Div, vec![Operand::RegisterOffset(LiteralType::U16, 1), Operand::Ephemeral(LiteralType::U16, 0)], vec![Destination::Ephemeral(LiteralType::U16, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U32), Operand::Literal(Literal::U32(U32::new(1)))], vec![Destination::Ephemeral(LiteralType::U32, 0)]), + (Instruction::Div, vec![Operand::RegisterOffset(LiteralType::U32, 1), Operand::Ephemeral(LiteralType::U32, 0)], vec![Destination::Ephemeral(LiteralType::U32, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U64), Operand::Literal(Literal::U64(U64::new(1)))], vec![Destination::Ephemeral(LiteralType::U64, 0)]), + (Instruction::Div, vec![Operand::RegisterOffset(LiteralType::U64, 1), Operand::Ephemeral(LiteralType::U64, 0)], vec![Destination::Ephemeral(LiteralType::U64, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U128), Operand::Literal(Literal::U128(U128::new(1)))], vec![Destination::Ephemeral(LiteralType::U128, 0)]), + (Instruction::Div, vec![Operand::RegisterOffset(LiteralType::U128, 1), Operand::Ephemeral(LiteralType::U128, 0)], vec![Destination::Ephemeral(LiteralType::U128, 1)])], 0), + // div.w + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I8), Operand::Literal(Literal::I8(I8::new(1)))], vec![Destination::Ephemeral(LiteralType::I8, 0)]), + (Instruction::DivWrapped, vec![Operand::RegisterOffset(LiteralType::I8, 1), Operand::Ephemeral(LiteralType::I8, 0)], vec![Destination::Ephemeral(LiteralType::I8, 1)])], 1), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I16), Operand::Literal(Literal::I16(I16::new(1)))], vec![Destination::Ephemeral(LiteralType::I16, 0)]), + (Instruction::DivWrapped, vec![Operand::RegisterOffset(LiteralType::I16, 1), Operand::Ephemeral(LiteralType::I16, 0)], vec![Destination::Ephemeral(LiteralType::I16, 1)])], DEFAULT_I16 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I32), Operand::Literal(Literal::I32(I32::new(1)))], vec![Destination::Ephemeral(LiteralType::I32, 0)]), + (Instruction::DivWrapped, vec![Operand::RegisterOffset(LiteralType::I32, 1), Operand::Ephemeral(LiteralType::I32, 0)], vec![Destination::Ephemeral(LiteralType::I32, 1)])], DEFAULT_I32 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I64), Operand::Literal(Literal::I64(I64::new(1)))], vec![Destination::Ephemeral(LiteralType::I64, 0)]), + (Instruction::DivWrapped, vec![Operand::RegisterOffset(LiteralType::I64, 1), Operand::Ephemeral(LiteralType::I64, 0)], vec![Destination::Ephemeral(LiteralType::I64, 1)])], DEFAULT_I64 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I128), Operand::Literal(Literal::I128(I128::new(1)))], vec![Destination::Ephemeral(LiteralType::I128, 0)]), + (Instruction::DivWrapped, vec![Operand::RegisterOffset(LiteralType::I128, 1), Operand::Ephemeral(LiteralType::I128, 0)], vec![Destination::Ephemeral(LiteralType::I128, 1)])], DEFAULT_I128 / U128_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U8), Operand::Literal(Literal::U8(U8::new(1)))], vec![Destination::Ephemeral(LiteralType::U8, 0)]), + (Instruction::DivWrapped, vec![Operand::RegisterOffset(LiteralType::U8, 1), Operand::Ephemeral(LiteralType::U8, 0)], vec![Destination::Ephemeral(LiteralType::U8, 1)])], 1), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U16), Operand::Literal(Literal::U16(U16::new(1)))], vec![Destination::Ephemeral(LiteralType::U16, 0)]), + (Instruction::DivWrapped, vec![Operand::RegisterOffset(LiteralType::U16, 1), Operand::Ephemeral(LiteralType::U16, 0)], vec![Destination::Ephemeral(LiteralType::U16, 1)])], DEFAULT_U16 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U32), Operand::Literal(Literal::U32(U32::new(1)))], vec![Destination::Ephemeral(LiteralType::U32, 0)]), + (Instruction::DivWrapped, vec![Operand::RegisterOffset(LiteralType::U32, 1), Operand::Ephemeral(LiteralType::U32, 0)], vec![Destination::Ephemeral(LiteralType::U32, 1)])], DEFAULT_U32 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U64), Operand::Literal(Literal::U64(U64::new(1)))], vec![Destination::Ephemeral(LiteralType::U64, 0)]), + (Instruction::DivWrapped, vec![Operand::RegisterOffset(LiteralType::U64, 1), Operand::Ephemeral(LiteralType::U64, 0)], vec![Destination::Ephemeral(LiteralType::U64, 1)])], DEFAULT_U64 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U128), Operand::Literal(Literal::U128(U128::new(1)))], vec![Destination::Ephemeral(LiteralType::U128, 0)]), + (Instruction::DivWrapped, vec![Operand::RegisterOffset(LiteralType::U128, 1), Operand::Ephemeral(LiteralType::U128, 0)], vec![Destination::Ephemeral(LiteralType::U128, 1)])], DEFAULT_U128 / U128_DIVIDER), + // double + (vec![(Instruction::Double, vec![Operand::Register(LiteralType::Field)], vec![Destination::Ephemeral(LiteralType::Field, 0)])], 0), + // gt + (vec![(Instruction::Gt, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gt, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_I8), + (vec![(Instruction::Gt, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gt, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gt, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gt, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gt, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_U8), + (vec![(Instruction::Gt, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gt, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gt, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gt, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + // gte + (vec![(Instruction::Gte, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gte, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_I8), + (vec![(Instruction::Gte, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gte, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gte, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gte, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gte, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_U8), + (vec![(Instruction::Gte, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gte, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gte, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Gte, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + // hash.bhp256 + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 1), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 1), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 1), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 1), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 1), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 1), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 1), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 1), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 1), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 1), + // hash.bhp512 + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.bhp768 + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp768, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.bhp1024 + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashBhp1024, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.keccak256 + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.keccak384 + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.keccak512 + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashKeccak512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.ped64 + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 1), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 1), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 1), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 1), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 1), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 1), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed64, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.ped128 + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPed128, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.psd2 + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd2, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.psd4 + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd4, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.psd8 + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashPsd8, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.sha3_256 + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3256, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.sha3_384 + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3384, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // hash.sha3_512 + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Field)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::HashSha3512, vec![Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // inv + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::Field), Operand::Literal(Literal::Field(Field::zero()))], vec![Destination::Ephemeral(LiteralType::Boolean, 0)]), + (Instruction::Ternary, vec![Operand::Ephemeral(LiteralType::Boolean, 0), Operand::Input(LiteralType::Field, 0), Operand::Register(LiteralType::Field)], vec![Destination::Ephemeral(LiteralType::Field, 1)]), + (Instruction::Inv, vec![Operand::Ephemeral(LiteralType::Field, 1)], vec![Destination::Register(LiteralType::Field)])], VERY_LOW), + // is.eq + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_BOOLEAN), + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_I8), + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_U8), + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsEq, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + // is.neq + (vec![(Instruction::IsNeq, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsNeq, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsNeq, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsNeq, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsNeq, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsNeq, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsNeq, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsNeq, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsNeq, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsNeq, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsNeq, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + (vec![(Instruction::IsNeq, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], VERY_LOW), + // lt + (vec![(Instruction::Lt, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lt, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_I8), + (vec![(Instruction::Lt, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lt, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lt, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lt, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lt, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_U8), + (vec![(Instruction::Lt, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lt, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lt, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lt, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + // lte + (vec![(Instruction::Lte, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lte, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_I8), + (vec![(Instruction::Lte, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lte, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lte, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lte, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lte, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_U8), + (vec![(Instruction::Lte, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lte, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lte, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + (vec![(Instruction::Lte, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::Boolean)])], MEDIUM_LOW), + // mod + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U8), Operand::Literal(Literal::U8(U8::new(1)))], vec![Destination::Ephemeral(LiteralType::U8, 0)]), + (Instruction::Mod, vec![Operand::RegisterOffset(LiteralType::U8, 1), Operand::Ephemeral(LiteralType::U8, 0)], vec![Destination::Ephemeral(LiteralType::U8, 1)])], 1), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U16), Operand::Literal(Literal::U16(U16::new(1)))], vec![Destination::Ephemeral(LiteralType::U16, 0)]), + (Instruction::Mod, vec![Operand::RegisterOffset(LiteralType::U16, 1), Operand::Ephemeral(LiteralType::U16, 0)], vec![Destination::Ephemeral(LiteralType::U16, 1)])], DEFAULT_U16 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U32), Operand::Literal(Literal::U32(U32::new(1)))], vec![Destination::Ephemeral(LiteralType::U32, 0)]), + (Instruction::Mod, vec![Operand::RegisterOffset(LiteralType::U32, 1), Operand::Ephemeral(LiteralType::U32, 0)], vec![Destination::Ephemeral(LiteralType::U32, 1)])], DEFAULT_U32 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U64), Operand::Literal(Literal::U64(U64::new(1)))], vec![Destination::Ephemeral(LiteralType::U64, 0)]), + (Instruction::Mod, vec![Operand::RegisterOffset(LiteralType::U64, 1), Operand::Ephemeral(LiteralType::U64, 0)], vec![Destination::Ephemeral(LiteralType::U64, 1)])], DEFAULT_U64 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U128), Operand::Literal(Literal::U128(U128::new(1)))], vec![Destination::Ephemeral(LiteralType::U128, 0)]), + (Instruction::Mod, vec![Operand::RegisterOffset(LiteralType::U128, 1), Operand::Ephemeral(LiteralType::U128, 0)], vec![Destination::Ephemeral(LiteralType::U128, 1)])], DEFAULT_U128 / U128_DIVIDER), + // mul + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], DEFAULT), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::Mul, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // mul.w + (vec![(Instruction::MulWrapped, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], DEFAULT_I8), + (vec![(Instruction::MulWrapped, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], LOW), + (vec![(Instruction::MulWrapped, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], LOW), + (vec![(Instruction::MulWrapped, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], LOW), + (vec![(Instruction::MulWrapped, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], LOW), + (vec![(Instruction::MulWrapped, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], DEFAULT_U8), + (vec![(Instruction::MulWrapped, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], LOW), + (vec![(Instruction::MulWrapped, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], LOW), + (vec![(Instruction::MulWrapped, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], LOW), + (vec![(Instruction::MulWrapped, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], LOW), + // nand + (vec![(Instruction::Nand, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_BOOLEAN), + // neg + (vec![(Instruction::Neg, vec![Operand::Register(LiteralType::Field)], vec![Destination::Ephemeral(LiteralType::Field, 0)])], 0), + (vec![ + (Instruction::IsEq, vec![Operand::Register(LiteralType::I8), Operand::Literal(Literal::I8(I8::new(-128)))], vec![Destination::Register(LiteralType::Boolean)]), + (Instruction::AddWrapped, vec![Operand::Register(LiteralType::I8), Operand::Literal(Literal::I8(I8::new(1)))], vec![Destination::Ephemeral(LiteralType::I8, 0)]), + (Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Ephemeral(LiteralType::I8, 0), Operand::Register(LiteralType::I8)], vec![Destination::Ephemeral(LiteralType::I8, 1)]), + (Instruction::Neg, vec![Operand::Ephemeral(LiteralType::I8, 1)], vec![Destination::Ephemeral(LiteralType::I8, 2)]),], DEFAULT_I8), + (vec![ + (Instruction::IsEq, vec![Operand::Register(LiteralType::I16), Operand::Literal(Literal::I16(I16::new(-32768)))], vec![Destination::Register(LiteralType::Boolean)]), + (Instruction::AddWrapped, vec![Operand::Register(LiteralType::I16), Operand::Literal(Literal::I16(I16::new(1)))], vec![Destination::Ephemeral(LiteralType::I16, 0)]), + (Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Ephemeral(LiteralType::I16, 0), Operand::Register(LiteralType::I16)], vec![Destination::Ephemeral(LiteralType::I16, 1)]), + (Instruction::Neg, vec![Operand::Ephemeral(LiteralType::I16, 1)], vec![Destination::Ephemeral(LiteralType::I16, 2)]),], DEFAULT_I16 / 2), + (vec![ + (Instruction::IsEq, vec![Operand::Register(LiteralType::I32), Operand::Literal(Literal::I32(I32::new(-2147483648)))], vec![Destination::Register(LiteralType::Boolean)]), + (Instruction::AddWrapped, vec![Operand::Register(LiteralType::I32), Operand::Literal(Literal::I32(I32::new(1)))], vec![Destination::Ephemeral(LiteralType::I32, 0)]), + (Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Ephemeral(LiteralType::I32, 0), Operand::Register(LiteralType::I32)], vec![Destination::Ephemeral(LiteralType::I32, 1)]), + (Instruction::Neg, vec![Operand::Ephemeral(LiteralType::I32, 1)], vec![Destination::Ephemeral(LiteralType::I32, 2)]),], DEFAULT_I32 / 2), + (vec![ + (Instruction::IsEq, vec![Operand::Register(LiteralType::I64), Operand::Literal(Literal::I64(I64::new(-9223372036854775808)))], vec![Destination::Register(LiteralType::Boolean)]), + (Instruction::AddWrapped, vec![Operand::Register(LiteralType::I64), Operand::Literal(Literal::I64(I64::new(1)))], vec![Destination::Ephemeral(LiteralType::I64, 0)]), + (Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Ephemeral(LiteralType::I64, 0), Operand::Register(LiteralType::I64)], vec![Destination::Ephemeral(LiteralType::I64, 1)]), + (Instruction::Neg, vec![Operand::Ephemeral(LiteralType::I64, 1)], vec![Destination::Ephemeral(LiteralType::I64, 2)]),], DEFAULT_I64 / 2), + (vec![ + (Instruction::IsEq, vec![Operand::Register(LiteralType::I128), Operand::Literal(Literal::I128(I128::new(-170141183460469231731687303715884105728)))], vec![Destination::Register(LiteralType::Boolean)]), + (Instruction::AddWrapped, vec![Operand::Register(LiteralType::I128), Operand::Literal(Literal::I128(I128::new(1)))], vec![Destination::Ephemeral(LiteralType::I128, 0)]), + (Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Ephemeral(LiteralType::I128, 0), Operand::Register(LiteralType::I128)], vec![Destination::Ephemeral(LiteralType::I128, 1)]), + (Instruction::Neg, vec![Operand::Ephemeral(LiteralType::I128, 1)], vec![Destination::Ephemeral(LiteralType::I128, 2)]),], DEFAULT_I128 / 2), + // nor + (vec![(Instruction::Nor, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_BOOLEAN), + // not + (vec![(Instruction::Not, vec![Operand::Register(LiteralType::Boolean)], vec![Destination::Ephemeral(LiteralType::Boolean, 0)])], VERY_LOW), + (vec![(Instruction::Not, vec![Operand::Register(LiteralType::I8)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], VERY_LOW), + (vec![(Instruction::Not, vec![Operand::Register(LiteralType::I16)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], VERY_LOW), + (vec![(Instruction::Not, vec![Operand::Register(LiteralType::I32)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], VERY_LOW), + (vec![(Instruction::Not, vec![Operand::Register(LiteralType::I64)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], VERY_LOW), + (vec![(Instruction::Not, vec![Operand::Register(LiteralType::I128)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], VERY_LOW), + (vec![(Instruction::Not, vec![Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], VERY_LOW), + (vec![(Instruction::Not, vec![Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], VERY_LOW), + (vec![(Instruction::Not, vec![Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], VERY_LOW), + (vec![(Instruction::Not, vec![Operand::Register(LiteralType::U64)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], VERY_LOW), + (vec![(Instruction::Not, vec![Operand::Register(LiteralType::U128)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], VERY_LOW), + // or + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::Boolean)], vec![Destination::Ephemeral(LiteralType::Boolean, 0)])], DEFAULT_BOOLEAN), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], VERY_LOW), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], VERY_LOW), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], VERY_LOW), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], VERY_LOW), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], DEFAULT_U8), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], VERY_LOW), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], VERY_LOW), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], VERY_LOW), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], VERY_LOW), + // pow + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Register(LiteralType::Field)])], VERY_LOW), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], 0), + (vec![(Instruction::Pow, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], 0), + // pow.w + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], DEFAULT_U8), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], DEFAULT_U8), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], DEFAULT_U8), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], NUM_POWER), + (vec![(Instruction::PowWrapped, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], NUM_POWER), + // rem + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I8), Operand::Literal(Literal::I8(I8::new(1)))], vec![Destination::Ephemeral(LiteralType::I8, 0)]), + (Instruction::Rem, vec![Operand::RegisterOffset(LiteralType::I8, 1), Operand::Ephemeral(LiteralType::I8, 0)], vec![Destination::Ephemeral(LiteralType::I8, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I16), Operand::Literal(Literal::I16(I16::new(1)))], vec![Destination::Ephemeral(LiteralType::I16, 0)]), + (Instruction::Rem, vec![Operand::RegisterOffset(LiteralType::I16, 1), Operand::Ephemeral(LiteralType::I16, 0)], vec![Destination::Ephemeral(LiteralType::I16, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I32), Operand::Literal(Literal::I32(I32::new(1)))], vec![Destination::Ephemeral(LiteralType::I32, 0)]), + (Instruction::Rem, vec![Operand::RegisterOffset(LiteralType::I32, 1), Operand::Ephemeral(LiteralType::I32, 0)], vec![Destination::Ephemeral(LiteralType::I32, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I64), Operand::Literal(Literal::I64(I64::new(1)))], vec![Destination::Ephemeral(LiteralType::I64, 0)]), + (Instruction::Rem, vec![Operand::RegisterOffset(LiteralType::I64, 1), Operand::Ephemeral(LiteralType::I64, 0)], vec![Destination::Ephemeral(LiteralType::I64, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I128), Operand::Literal(Literal::I128(I128::new(1)))], vec![Destination::Ephemeral(LiteralType::I128, 0)]), + (Instruction::Rem, vec![Operand::RegisterOffset(LiteralType::I128, 1), Operand::Ephemeral(LiteralType::I128, 0)], vec![Destination::Ephemeral(LiteralType::I128, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U8), Operand::Literal(Literal::U8(U8::new(1)))], vec![Destination::Ephemeral(LiteralType::U8, 0)]), + (Instruction::Rem, vec![Operand::RegisterOffset(LiteralType::U8, 1), Operand::Ephemeral(LiteralType::U8, 0)], vec![Destination::Ephemeral(LiteralType::U8, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U16), Operand::Literal(Literal::U16(U16::new(1)))], vec![Destination::Ephemeral(LiteralType::U16, 0)]), + (Instruction::Rem, vec![Operand::RegisterOffset(LiteralType::U16, 1), Operand::Ephemeral(LiteralType::U16, 0)], vec![Destination::Ephemeral(LiteralType::U16, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U32), Operand::Literal(Literal::U32(U32::new(1)))], vec![Destination::Ephemeral(LiteralType::U32, 0)]), + (Instruction::Rem, vec![Operand::RegisterOffset(LiteralType::U32, 1), Operand::Ephemeral(LiteralType::U32, 0)], vec![Destination::Ephemeral(LiteralType::U32, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U64), Operand::Literal(Literal::U64(U64::new(1)))], vec![Destination::Ephemeral(LiteralType::U64, 0)]), + (Instruction::Rem, vec![Operand::RegisterOffset(LiteralType::U64, 1), Operand::Ephemeral(LiteralType::U64, 0)], vec![Destination::Ephemeral(LiteralType::U64, 1)])], 0), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U128), Operand::Literal(Literal::U128(U128::new(1)))], vec![Destination::Ephemeral(LiteralType::U128, 0)]), + (Instruction::Rem, vec![Operand::RegisterOffset(LiteralType::U128, 1), Operand::Ephemeral(LiteralType::U128, 0)], vec![Destination::Ephemeral(LiteralType::U128, 1)])], 0), + // rem.w + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I8), Operand::Literal(Literal::I8(I8::new(1)))], vec![Destination::Ephemeral(LiteralType::I8, 0)]), + (Instruction::RemWrapped, vec![Operand::RegisterOffset(LiteralType::I8, 1), Operand::Ephemeral(LiteralType::I8, 0)], vec![Destination::Ephemeral(LiteralType::I8, 1)])], 1), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I16), Operand::Literal(Literal::I16(I16::new(1)))], vec![Destination::Ephemeral(LiteralType::I16, 0)]), + (Instruction::RemWrapped, vec![Operand::RegisterOffset(LiteralType::I16, 1), Operand::Ephemeral(LiteralType::I16, 0)], vec![Destination::Ephemeral(LiteralType::I16, 1)])], DEFAULT_I16 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I32), Operand::Literal(Literal::I32(I32::new(1)))], vec![Destination::Ephemeral(LiteralType::I32, 0)]), + (Instruction::RemWrapped, vec![Operand::RegisterOffset(LiteralType::I32, 1), Operand::Ephemeral(LiteralType::I32, 0)], vec![Destination::Ephemeral(LiteralType::I32, 1)])], DEFAULT_I32 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I64), Operand::Literal(Literal::I64(I64::new(1)))], vec![Destination::Ephemeral(LiteralType::I64, 0)]), + (Instruction::RemWrapped, vec![Operand::RegisterOffset(LiteralType::I64, 1), Operand::Ephemeral(LiteralType::I64, 0)], vec![Destination::Ephemeral(LiteralType::I64, 1)])], DEFAULT_I64 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::I128), Operand::Literal(Literal::I128(I128::new(1)))], vec![Destination::Ephemeral(LiteralType::I128, 0)]), + (Instruction::RemWrapped, vec![Operand::RegisterOffset(LiteralType::I128, 1), Operand::Ephemeral(LiteralType::I128, 0)], vec![Destination::Ephemeral(LiteralType::I128, 1)])], DEFAULT_I128 / U128_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U8), Operand::Literal(Literal::U8(U8::new(1)))], vec![Destination::Ephemeral(LiteralType::U8, 0)]), + (Instruction::RemWrapped, vec![Operand::RegisterOffset(LiteralType::U8, 1), Operand::Ephemeral(LiteralType::U8, 0)], vec![Destination::Ephemeral(LiteralType::U8, 1)])], 1), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U16), Operand::Literal(Literal::U16(U16::new(1)))], vec![Destination::Ephemeral(LiteralType::U16, 0)]), + (Instruction::RemWrapped, vec![Operand::RegisterOffset(LiteralType::U16, 1), Operand::Ephemeral(LiteralType::U16, 0)], vec![Destination::Ephemeral(LiteralType::U16, 1)])], DEFAULT_U16 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U32), Operand::Literal(Literal::U32(U32::new(1)))], vec![Destination::Ephemeral(LiteralType::U32, 0)]), + (Instruction::RemWrapped, vec![Operand::RegisterOffset(LiteralType::U32, 1), Operand::Ephemeral(LiteralType::U32, 0)], vec![Destination::Ephemeral(LiteralType::U32, 1)])], DEFAULT_U32 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U64), Operand::Literal(Literal::U64(U64::new(1)))], vec![Destination::Ephemeral(LiteralType::U64, 0)]), + (Instruction::RemWrapped, vec![Operand::RegisterOffset(LiteralType::U64, 1), Operand::Ephemeral(LiteralType::U64, 0)], vec![Destination::Ephemeral(LiteralType::U64, 1)])], DEFAULT_U64 / DIV_DIVIDER), + (vec![(Instruction::Or, vec![Operand::Register(LiteralType::U128), Operand::Literal(Literal::U128(U128::new(1)))], vec![Destination::Ephemeral(LiteralType::U128, 0)]), + (Instruction::RemWrapped, vec![Operand::RegisterOffset(LiteralType::U128, 1), Operand::Ephemeral(LiteralType::U128, 0)], vec![Destination::Ephemeral(LiteralType::U128, 1)])], DEFAULT_U128 / U128_DIVIDER), + // shl + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], 0), + (vec![(Instruction::Shl, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], 0), + // shl.w + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], DEFAULT_U8), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], DEFAULT_U8), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], DEFAULT_U8), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], LOW), + (vec![(Instruction::ShlWrapped, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], LOW), + // shr + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], 0), + (vec![(Instruction::Shr, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], 0), + // shr.w + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], VERY_LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], VERY_LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], VERY_LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], DEFAULT_U8), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], DEFAULT_U8), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], DEFAULT_U8), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], VERY_LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], VERY_LOW), + (vec![(Instruction::ShrWrapped, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], VERY_LOW), + // sqrt + (vec![(Instruction::Sqrt, vec![Operand::Register(LiteralType::Field)], vec![Destination::Ephemeral(LiteralType::Field, 0)])], 0), + // square + (vec![(Instruction::Square, vec![Operand::RegisterOffset(LiteralType::Field, 1)], vec![Destination::Register(LiteralType::Field)])], 4 * DEFAULT), + // sub + (vec![(Instruction::Sub, vec![Operand::Register(LiteralType::Field), Operand::Register(LiteralType::Field)], vec![Destination::Ephemeral(LiteralType::Field, 0)])], 0), + (vec![(Instruction::Sub, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], 0), + (vec![(Instruction::Sub, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], 0), + (vec![(Instruction::Sub, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], 0), + (vec![(Instruction::Sub, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], 0), + (vec![(Instruction::Sub, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], 0), + (vec![(Instruction::Sub, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], 0), + (vec![(Instruction::Sub, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], 0), + (vec![(Instruction::Sub, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], 0), + (vec![(Instruction::Sub, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], 0), + (vec![(Instruction::Sub, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], 0), + // sub.w + (vec![(Instruction::SubWrapped, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], VERY_LOW), + (vec![(Instruction::SubWrapped, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], DEFAULT_I16/4), + (vec![(Instruction::SubWrapped, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], DEFAULT_I32/4), + (vec![(Instruction::SubWrapped, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], DEFAULT_I64/4), + (vec![(Instruction::SubWrapped, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], DEFAULT_I128/4), + (vec![(Instruction::SubWrapped, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], VERY_LOW), + (vec![(Instruction::SubWrapped, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], DEFAULT_U16/4), + (vec![(Instruction::SubWrapped, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], DEFAULT_U32/4), + (vec![(Instruction::SubWrapped, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], DEFAULT_U64/4), + (vec![(Instruction::SubWrapped, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], DEFAULT_U128/4), + // ternary + (vec![(Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::Boolean)], vec![Destination::Ephemeral(LiteralType::Boolean, 0)])], 0), + (vec![(Instruction::IsEq, vec![Operand::RegisterOffset(LiteralType::Field, 1), Operand::Literal(Literal::Field(Field::zero()))], vec![Destination::Ephemeral(LiteralType::Boolean, 0)]), + (Instruction::Ternary, vec![Operand::Ephemeral(LiteralType::Boolean, 0), Operand::Input(LiteralType::Field, 0), Operand::RegisterOffset(LiteralType::Field, 1)], vec![Destination::Register(LiteralType::Field)])], DEFAULT), + (vec![(Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::Group), Operand::Register(LiteralType::Group)], vec![Destination::Ephemeral(LiteralType::Group, 0)])], 0), + (vec![(Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Ephemeral(LiteralType::I8, 0)])], DEFAULT_I8), + (vec![(Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Ephemeral(LiteralType::I16, 0)])], LOW), + (vec![(Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Ephemeral(LiteralType::I32, 0)])], LOW), + (vec![(Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Ephemeral(LiteralType::I64, 0)])], LOW), + (vec![(Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Ephemeral(LiteralType::I128, 0)])], LOW), + (vec![(Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Ephemeral(LiteralType::U8, 0)])], DEFAULT_U8), + (vec![(Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Ephemeral(LiteralType::U16, 0)])], LOW), + (vec![(Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Ephemeral(LiteralType::U32, 0)])], LOW), + (vec![(Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Ephemeral(LiteralType::U64, 0)])], LOW), + (vec![(Instruction::Ternary, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Ephemeral(LiteralType::U128, 0)])], LOW), + // xor + (vec![(Instruction::Xor, vec![Operand::Register(LiteralType::Boolean), Operand::Register(LiteralType::Boolean)], vec![Destination::Register(LiteralType::Boolean)])], DEFAULT_BOOLEAN), + (vec![(Instruction::Xor, vec![Operand::Register(LiteralType::I8), Operand::Register(LiteralType::I8)], vec![Destination::Register(LiteralType::I8)])], DEFAULT_I8), + (vec![(Instruction::Xor, vec![Operand::Register(LiteralType::I16), Operand::Register(LiteralType::I16)], vec![Destination::Register(LiteralType::I16)])], DEFAULT_I16), + (vec![(Instruction::Xor, vec![Operand::Register(LiteralType::I32), Operand::Register(LiteralType::I32)], vec![Destination::Register(LiteralType::I32)])], DEFAULT_I32), + (vec![(Instruction::Xor, vec![Operand::Register(LiteralType::I64), Operand::Register(LiteralType::I64)], vec![Destination::Register(LiteralType::I64)])], DEFAULT_I64), + (vec![(Instruction::Xor, vec![Operand::Register(LiteralType::I128), Operand::Register(LiteralType::I128)], vec![Destination::Register(LiteralType::I128)])], DEFAULT_I128), + (vec![(Instruction::Xor, vec![Operand::Register(LiteralType::U8), Operand::Register(LiteralType::U8)], vec![Destination::Register(LiteralType::U8)])], DEFAULT_U8), + (vec![(Instruction::Xor, vec![Operand::Register(LiteralType::U16), Operand::Register(LiteralType::U16)], vec![Destination::Register(LiteralType::U16)])], DEFAULT_U16), + (vec![(Instruction::Xor, vec![Operand::Register(LiteralType::U32), Operand::Register(LiteralType::U32)], vec![Destination::Register(LiteralType::U32)])], DEFAULT_U32), + (vec![(Instruction::Xor, vec![Operand::Register(LiteralType::U64), Operand::Register(LiteralType::U64)], vec![Destination::Register(LiteralType::U64)])], DEFAULT_U64), + (vec![(Instruction::Xor, vec![Operand::Register(LiteralType::U128), Operand::Register(LiteralType::U128)], vec![Destination::Register(LiteralType::U128)])], DEFAULT_U128), + ] +} + +#[cfg(test)] +mod test { + use super::*; + use crate::synthesis::helpers::NUM_SEQUENCE_INSTRUCTIONS; + use std::collections::HashSet; + + type CurrentNetwork = console::network::MainnetV0; + + #[test] + fn check_weights_are_valid() { + // Get the instruction set. + let instruction_set = instruction_set::(); + + // Initialize the sum. + let mut sum = 0u16; + + // Sum the weights together, checking that an overflow does not occur. + for (_, weight) in instruction_set { + let result = sum.checked_add(weight); + assert!(result.is_some()); + sum = result.unwrap(); + } + } + + #[test] + fn check_ephemeral_registers_are_valid() { + // Get the instruction set. + let instruction_set = instruction_set::(); + + // For each instruction sequence, + // - check that the ephemeral destination registers are sequentially increasing. + // - check that the ephemeral operands exist. + for (sequence, _) in instruction_set { + // Initialize the `next_expected_ephemeral_register`. + let mut next_expected_ephemeral_register = 0u16; + // Initialize the storage for the ephemeral registers seen thus far. + let mut ephemeral_registers = HashSet::new(); + + for (_, operands, destinations) in sequence { + // First, process all of the operands in the sequence. + for operand in operands { + // Check that the index of the ephemeral register exists. + if let PuzzleOperand::Ephemeral(_, index) = operand { + assert!(ephemeral_registers.contains(&index)); + } + } + + // Then, process all of the destination registers in the sequence. + for destination in destinations { + // Check that the index of the destination register matches the expected one. + if let PuzzleDestination::Ephemeral(_, index) = destination { + assert_eq!(index, next_expected_ephemeral_register); + next_expected_ephemeral_register += 1; + ephemeral_registers.insert(index); + } + } + } + } + } + + #[test] + fn check_register_offsets_are_valid() { + // Get the instruction set. + let instruction_set = instruction_set::(); + + // For each instruction sequence, check that the register offsets do not exceed 1. + for (sequence, _) in instruction_set { + for (_, operands, _) in sequence { + // Check each of the operands. + for operand in operands { + // Check that the index of the ephemeral register exists. + if let PuzzleOperand::RegisterOffset(_, offset) = operand { + assert!(offset <= 1); + } + } + } + } + } + + #[test] + fn check_that_instructions_are_valid() { + // Get the instruction set. + let instruction_set = instruction_set::(); + + // Check that each instruction sequence is valid. + for (sequence, _) in instruction_set { + // Check that the sequence length does not exceed `NUM_SEQUENCE_INSTRUCTIONS`. + assert!(sequence.len() <= NUM_SEQUENCE_INSTRUCTIONS); + for (instruction, _, _) in sequence { + // Check that the instruction is not a `branch`. + assert!(!matches!(instruction, Instruction::BranchEq | Instruction::BranchNeq)); + } + } + } +} diff --git a/ledger/puzzle/epoch/src/synthesis/helpers/instruction_type.rs b/ledger/puzzle/epoch/src/synthesis/helpers/instruction_type.rs new file mode 100644 index 0000000000..7eeb59d0fe --- /dev/null +++ b/ledger/puzzle/epoch/src/synthesis/helpers/instruction_type.rs @@ -0,0 +1,420 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 std::fmt::Display; + +/// The number of puzzle instruction variants. +pub const NUM_PUZZLE_INSTRUCTION_VARIANTS: u8 = 64; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum PuzzleInstructionType { + Abs, + AbsWrapped, + Add, + AddWrapped, + And, + AssertEq, + AssertNeq, + BranchEq, + BranchNeq, + Cast, + CastLossy, + CommitBhp256, + CommitBhp512, + CommitBhp768, + CommitBhp1024, + CommitPed64, + CommitPed128, + Div, + DivWrapped, + Double, + Gt, + Gte, + HashBhp256, + HashBhp512, + HashBhp768, + HashBhp1024, + HashKeccak256, + HashKeccak384, + HashKeccak512, + HashPed64, + HashPed128, + HashPsd2, + HashPsd4, + HashPsd8, + HashSha3256, + HashSha3384, + HashSha3512, + Inv, + IsEq, + IsNeq, + Lt, + Lte, + Mod, + Mul, + MulWrapped, + Nand, + Neg, + Nor, + Not, + Or, + Pow, + PowWrapped, + Rem, + RemWrapped, + Shl, + ShlWrapped, + Shr, + ShrWrapped, + Sqrt, + Square, + Sub, + SubWrapped, + Ternary, + Xor, +} + +impl PuzzleInstructionType { + /// All puzzle instruction variants. + /// + /// Note: This is used as a compile-time safety check that `NUM_PUZZLE_INSTRUCTION_VARIANTS` is correct. + pub const ALL: [Self; NUM_PUZZLE_INSTRUCTION_VARIANTS as usize] = [ + Self::Abs, + Self::AbsWrapped, + Self::Add, + Self::AddWrapped, + Self::And, + Self::AssertEq, + Self::AssertNeq, + Self::BranchEq, + Self::BranchNeq, + Self::Cast, + Self::CastLossy, + Self::CommitBhp256, + Self::CommitBhp512, + Self::CommitBhp768, + Self::CommitBhp1024, + Self::CommitPed64, + Self::CommitPed128, + Self::Div, + Self::DivWrapped, + Self::Double, + Self::Gt, + Self::Gte, + Self::HashBhp256, + Self::HashBhp512, + Self::HashBhp768, + Self::HashBhp1024, + Self::HashKeccak256, + Self::HashKeccak384, + Self::HashKeccak512, + Self::HashPed64, + Self::HashPed128, + Self::HashPsd2, + Self::HashPsd4, + Self::HashPsd8, + Self::HashSha3256, + Self::HashSha3384, + Self::HashSha3512, + Self::Inv, + Self::IsEq, + Self::IsNeq, + Self::Lt, + Self::Lte, + Self::Mod, + Self::Mul, + Self::MulWrapped, + Self::Nand, + Self::Neg, + Self::Nor, + Self::Not, + Self::Or, + Self::Pow, + Self::PowWrapped, + Self::Rem, + Self::RemWrapped, + Self::Shl, + Self::ShlWrapped, + Self::Shr, + Self::ShrWrapped, + Self::Sqrt, + Self::Square, + Self::Sub, + Self::SubWrapped, + Self::Ternary, + Self::Xor, + ]; + + /// Initializes a new puzzle instruction type. + pub fn new(variant: u8) -> Self { + match variant { + 0 => Self::Abs, + 1 => Self::AbsWrapped, + 2 => Self::Add, + 3 => Self::AddWrapped, + 4 => Self::And, + 5 => Self::AssertEq, + 6 => Self::AssertNeq, + 7 => Self::BranchEq, + 8 => Self::BranchNeq, + 9 => Self::Cast, + 10 => Self::CastLossy, + 11 => Self::CommitBhp256, + 12 => Self::CommitBhp512, + 13 => Self::CommitBhp768, + 14 => Self::CommitBhp1024, + 15 => Self::CommitPed64, + 16 => Self::CommitPed128, + 17 => Self::Div, + 18 => Self::DivWrapped, + 19 => Self::Double, + 20 => Self::Gt, + 21 => Self::Gte, + 22 => Self::HashBhp256, + 23 => Self::HashBhp512, + 24 => Self::HashBhp768, + 25 => Self::HashBhp1024, + 26 => Self::HashKeccak256, + 27 => Self::HashKeccak384, + 28 => Self::HashKeccak512, + 29 => Self::HashPed64, + 30 => Self::HashPed128, + 31 => Self::HashPsd2, + 32 => Self::HashPsd4, + 33 => Self::HashPsd8, + 34 => Self::HashSha3256, + 35 => Self::HashSha3384, + 36 => Self::HashSha3512, + 37 => Self::Inv, + 38 => Self::IsEq, + 39 => Self::IsNeq, + 40 => Self::Lt, + 41 => Self::Lte, + 42 => Self::Mod, + 43 => Self::Mul, + 44 => Self::MulWrapped, + 45 => Self::Nand, + 46 => Self::Neg, + 47 => Self::Nor, + 48 => Self::Not, + 49 => Self::Or, + 50 => Self::Pow, + 51 => Self::PowWrapped, + 52 => Self::Rem, + 53 => Self::RemWrapped, + 54 => Self::Shl, + 55 => Self::ShlWrapped, + 56 => Self::Shr, + 57 => Self::ShrWrapped, + 58 => Self::Sqrt, + 59 => Self::Square, + 60 => Self::Sub, + 61 => Self::SubWrapped, + 62 => Self::Ternary, + 63 => Self::Xor, + 64.. => unreachable!("Invalid puzzle instruction variant"), + } + } + + /// Returns the puzzle instruction variant. + pub fn variant(&self) -> u8 { + *self as u8 + } + + /// Returns the puzzle instruction opcode. + pub fn opcode(&self) -> &'static str { + match self { + Self::Abs => "abs", + Self::AbsWrapped => "abs.w", + Self::Add => "add", + Self::AddWrapped => "add.w", + Self::And => "and", + Self::AssertEq => "assert.eq", + Self::AssertNeq => "assert.neq", + Self::BranchEq => "branch.eq", + Self::BranchNeq => "branch.neq", + Self::Cast => "cast", + Self::CastLossy => "cast.lossy", + Self::CommitBhp256 => "commit.bhp256", + Self::CommitBhp512 => "commit.bhp512", + Self::CommitBhp768 => "commit.bhp768", + Self::CommitBhp1024 => "commit.bhp1024", + Self::CommitPed64 => "commit.ped64", + Self::CommitPed128 => "commit.ped128", + Self::Div => "div", + Self::DivWrapped => "div.w", + Self::Double => "double", + Self::Gt => "gt", + Self::Gte => "gte", + Self::HashBhp256 => "hash.bhp256", + Self::HashBhp512 => "hash.bhp512", + Self::HashBhp768 => "hash.bhp768", + Self::HashBhp1024 => "hash.bhp1024", + Self::HashKeccak256 => "hash.keccak256", + Self::HashKeccak384 => "hash.keccak384", + Self::HashKeccak512 => "hash.keccak512", + Self::HashPed64 => "hash.ped64", + Self::HashPed128 => "hash.ped128", + Self::HashPsd2 => "hash.psd2", + Self::HashPsd4 => "hash.psd4", + Self::HashPsd8 => "hash.psd8", + Self::HashSha3256 => "hash.sha3_256", + Self::HashSha3384 => "hash.sha3_384", + Self::HashSha3512 => "hash.sha3_512", + Self::Inv => "inv", + Self::IsEq => "is.eq", + Self::IsNeq => "is.neq", + Self::Lt => "lt", + Self::Lte => "lte", + Self::Mod => "mod", + Self::Mul => "mul", + Self::MulWrapped => "mul.w", + Self::Nand => "nand", + Self::Neg => "neg", + Self::Nor => "nor", + Self::Not => "not", + Self::Or => "or", + Self::Pow => "pow", + Self::PowWrapped => "pow.w", + Self::Rem => "rem", + Self::RemWrapped => "rem.w", + Self::Shl => "shl", + Self::ShlWrapped => "shl.w", + Self::Shr => "shr", + Self::ShrWrapped => "shr.w", + Self::Sqrt => "sqrt", + Self::Square => "square", + Self::Sub => "sub", + Self::SubWrapped => "sub.w", + Self::Ternary => "ternary", + Self::Xor => "xor", + } + } + + /// Returns the number of operands required by the puzzle instruction type. + pub fn num_operands(&self) -> usize { + match self { + Self::Abs => 1, + Self::AbsWrapped => 1, + Self::Add => 2, + Self::AddWrapped => 2, + Self::And => 2, + Self::AssertEq => 2, + Self::AssertNeq => 2, + Self::BranchEq => 2, + Self::BranchNeq => 2, + Self::Cast => 1, + Self::CastLossy => 1, + Self::CommitBhp256 => 2, + Self::CommitBhp512 => 2, + Self::CommitBhp768 => 2, + Self::CommitBhp1024 => 2, + Self::CommitPed64 => 2, + Self::CommitPed128 => 2, + Self::Div => 2, + Self::DivWrapped => 2, + Self::Double => 1, + Self::Gt => 2, + Self::Gte => 2, + Self::HashBhp256 => 1, + Self::HashBhp512 => 1, + Self::HashBhp768 => 1, + Self::HashBhp1024 => 1, + Self::HashKeccak256 => 1, + Self::HashKeccak384 => 1, + Self::HashKeccak512 => 1, + Self::HashPed64 => 1, + Self::HashPed128 => 1, + Self::HashPsd2 => 1, + Self::HashPsd4 => 1, + Self::HashPsd8 => 1, + Self::HashSha3256 => 1, + Self::HashSha3384 => 1, + Self::HashSha3512 => 1, + Self::Inv => 1, + Self::IsEq => 2, + Self::IsNeq => 2, + Self::Lt => 2, + Self::Lte => 2, + Self::Mod => 2, + Self::Mul => 2, + Self::MulWrapped => 2, + Self::Nand => 2, + Self::Neg => 1, + Self::Nor => 2, + Self::Not => 1, + Self::Or => 2, + Self::Pow => 2, + Self::PowWrapped => 2, + Self::Rem => 2, + Self::RemWrapped => 2, + Self::Shl => 2, + Self::ShlWrapped => 2, + Self::Shr => 2, + Self::ShrWrapped => 2, + Self::Sqrt => 1, + Self::Square => 1, + Self::Sub => 2, + Self::SubWrapped => 2, + Self::Ternary => 3, + Self::Xor => 2, + } + } +} + +impl Display for PuzzleInstructionType { + /// Returns the display string for the instruction type. + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.opcode()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_puzzle_instruction_type() { + for instruction_variant in 0..NUM_PUZZLE_INSTRUCTION_VARIANTS { + let instruction_type = PuzzleInstructionType::new(instruction_variant); + assert_eq!(instruction_type.variant(), instruction_variant); + } + } + + #[test] + fn test_puzzle_instruction_type_all() { + assert_eq!(PuzzleInstructionType::ALL.len(), NUM_PUZZLE_INSTRUCTION_VARIANTS as usize); + for (instruction_variant, instruction_type) in PuzzleInstructionType::ALL.iter().enumerate() { + assert_eq!(instruction_type.variant(), u8::try_from(instruction_variant).unwrap()); + } + } + + #[test] + fn test_puzzle_instruction_type_opcode() { + for instruction_type in PuzzleInstructionType::ALL.iter() { + let opcode = instruction_type.opcode(); + assert!(!opcode.is_empty()); + } + } + + #[test] + fn test_puzzle_instruction_type_num_operands() { + for instruction_type in PuzzleInstructionType::ALL.iter() { + let num_operands = instruction_type.num_operands(); + assert!(num_operands > 0); + assert!(num_operands <= 3); + } + } +} diff --git a/ledger/puzzle/epoch/src/synthesis/helpers/mod.rs b/ledger/puzzle/epoch/src/synthesis/helpers/mod.rs new file mode 100644 index 0000000000..b63ce3d79a --- /dev/null +++ b/ledger/puzzle/epoch/src/synthesis/helpers/mod.rs @@ -0,0 +1,445 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +mod destination; +pub use destination::*; + +mod instruction_set; +pub use instruction_set::*; + +mod instruction_type; +pub use instruction_type::*; + +mod operand; +pub use operand::*; + +mod register; +pub use register::*; + +mod register_table; +pub use register_table::*; + +use console::{ + network::Network, + prelude::{FromBytes, ToBytes}, + program::LiteralType, +}; +use snarkvm_synthesizer_program::Instruction; + +use anyhow::Result; +use indexmap::IndexSet; +use rand::{SeedableRng, prelude::*}; +use rand_chacha::ChaChaRng; +use std::{collections::HashMap, str::FromStr}; + +/// The number of instructions to sample. +const NUM_INSTRUCTIONS: usize = 100; +/// Instruction count of the longest sequence. +const NUM_SEQUENCE_INSTRUCTIONS: usize = 4; + +/// Samples instructions for the given epoch. +pub(crate) fn sample_instructions( + epoch_hash: N::BlockHash, + register_table: &mut RegisterTable, +) -> Result>> { + // Initialize the RNG from the lower 64 bits of the epoch hash. + let lower = u64::from_bytes_le(&epoch_hash.to_bytes_le()?[0..8])?; + let mut rng = ChaChaRng::seed_from_u64(lower); + + // Initialize storage for the instructions. + let mut instructions = IndexSet::with_capacity(NUM_INSTRUCTIONS); + + // Initialize the instruction set weights. + let instruction_set_weights = instruction_set::(); + + // Initialize a counter for opcodes in the program. + let mut opcode_count = 0; + + 'outer: for _ in 0..NUM_INSTRUCTIONS { + // Ensure that we do not exceed the instruction count limit in the middle of a sequence. + if opcode_count > NUM_INSTRUCTIONS.saturating_sub(NUM_SEQUENCE_INSTRUCTIONS) { + break; + } + + // Initialize the instruction and selected literals. + let (sequence, _) = instruction_set_weights.choose_weighted(&mut rng, |(_, weight)| *weight).cloned().unwrap(); + + // Initialize a cache for the ephemeral registers. + // This is a mapping from the locator to the one assigned to it in the instruction sequence. + let mut cache_ephemeral = HashMap::::new(); + + // Initialize the constructed sequence. + let mut constructed_sequence = Vec::with_capacity(sequence.len()); + + for (instruction_type, instruction_operands, instruction_destinations) in sequence { + // Retrieve the number of operands required by the instruction type. + let num_operands = instruction_type.num_operands(); + + // Check if the number of operands is correct. + if num_operands != instruction_operands.len() { + match cfg!(debug_assertions) { + true => panic!("Invalid number of operands for {instruction_type}"), + false => eprintln!("Invalid number of operands for {instruction_type}"), + } + // Move to the next instruction type. + continue 'outer; + } + + // Check that the instruction is not a `branch`. + if matches!(instruction_type, PuzzleInstructionType::BranchEq | PuzzleInstructionType::BranchNeq) { + match cfg!(debug_assertions) { + true => panic!("Branch instructions are not allowed."), + false => eprintln!("Branch instructions are not allowed."), + } + // Move to the next instruction type. + continue 'outer; + } + + // Initialize the operands. + let mut operands = Vec::new(); + + // Initialize a cache for the literal types. + let mut cache_types = HashMap::::new(); + + // Construct the corresponding operand for each literal. + for operand in &instruction_operands { + match operand { + // If the operand is a literal, use the it directly. + PuzzleOperand::Literal(literal) => operands.push(literal.to_string()), + // If the operand is an ephemeral register, use the one defined in the instruction sequence. + PuzzleOperand::Ephemeral(_, index) => { + // Retrieve the ephemeral register. + let Some(locator) = cache_ephemeral.get(index) else { + match cfg!(debug_assertions) { + true => panic!("Ephemeral cache does not contain a register for index {index}"), + false => eprintln!("Ephemeral cache does not contain a register for index {index}"), + } + // Move to the next instruction type. + continue 'outer; + }; + // Insert the operand into the operands. + operands.push(locator.to_string()); + } + // If the operand is an input register, select the appropriate one from the register table. + PuzzleOperand::Input(literal_type, index) => { + // Retrieve the input register. + let Some(register) = register_table.get_input_at_index(literal_type, *index as usize) else { + match cfg!(debug_assertions) { + true => panic!("Register table does not contain input {literal_type} at index {index}"), + false => { + eprintln!("Register table does not contain input {literal_type} at index {index}") + } + } + // Move to the next instruction type. + continue 'outer; + }; + + // Insert the operand into the operands. + operands.push(register.to_string()); + } + // If the operand is a register, select one from the register table. + PuzzleOperand::Register(literal_type) => { + // Check if the register table contains the literal type. + if !register_table.contains_key(literal_type) { + match cfg!(debug_assertions) { + true => panic!("Register table does not contain {literal_type}"), + false => eprintln!("Register table does not contain {literal_type}"), + } + // Move to the next instruction type. + continue 'outer; + } + + // Retrieve the offset, incrementing if it exists, and otherwise initializing to zero. + let offset = *cache_types.entry(*literal_type).and_modify(|offset| *offset += 1).or_insert(0); + + // Retrieve the registers for the literal type. + let Ok(register) = register_table.get_k_th_last_register(literal_type, offset) else { + match cfg!(debug_assertions) { + true => panic!("Failed to retrieve registers for {literal_type} at offset {offset}"), + false => { + eprintln!("Failed to retrieve registers for {literal_type} at offset {offset}") + } + } + // Move to the next instruction type. + continue 'outer; + }; + + // Insert the operand into the operands. + operands.push(register.to_string()); + } + // If the operand is a register, with an explicit offset, get the appropriate register from the table. + PuzzleOperand::RegisterOffset(literal_type, offset) => { + // Check if the register table contains the literal type. + if !register_table.contains_key(literal_type) { + match cfg!(debug_assertions) { + true => panic!("Register table does not contain {literal_type}"), + false => eprintln!("Register table does not contain {literal_type}"), + } + // Move to the next instruction type. + continue 'outer; + } + + // Retrieve the k-th last register for the literal type. + let Ok(register) = register_table.get_k_th_last_register(literal_type, *offset as usize) else { + match cfg!(debug_assertions) { + true => panic!("Failed to retrieve register for {literal_type} at offset {offset}"), + false => eprintln!("Failed to retrieve register for {literal_type} at offset {offset}"), + } + // Move to the next instruction type. + continue 'outer; + }; + + // Insert the operand into the operands. + operands.push(register.to_string()); + } + } + } + + // Initialize the destinations. + let mut destinations = IndexSet::new(); + + for destination in &instruction_destinations { + // Get the next register locator. + let locator = match register_table.get_next_locator() { + Ok(register_locator) => register_locator, + Err(e) => { + match cfg!(debug_assertions) { + true => panic!("Failed to retrieve next register locator - {e}"), + false => eprintln!("Failed to retrieve next register locator - {e}"), + } + // Move to the next instruction type. + continue 'outer; + } + }; + // Initialize the destination register. + let register = PuzzleRegister::new_locator(locator); + + match destination { + // If the destination is an ephemeral register, insert it into the cache. + PuzzleDestination::Ephemeral(_, index) => { + cache_ephemeral.insert(*index, register); + } + // If the destination is a register, insert it into the register table. + PuzzleDestination::Register(literal_type) => { + if let Err(e) = register_table.insert(*literal_type, register) { + match cfg!(debug_assertions) { + true => panic!("Failed to insert register into register table - {e}"), + false => eprintln!("Failed to insert register into register table - {e}"), + } + // Move to the next instruction type. + continue 'outer; + } + } + } + destinations.insert(register); + } + + // Construct the instruction string. + let mut instruction_string = instruction_type.opcode().to_string(); + instruction_string.push(' '); + instruction_string.push_str(&operands.join(" ")); + instruction_string.push_str(" into "); + instruction_string.push_str( + &destinations.iter().map(|destination| format!("{destination}")).collect::>().join(" "), + ); + // If the instruction is a cast, commit or hash, append the target type. + if matches!( + instruction_type, + PuzzleInstructionType::Cast + | PuzzleInstructionType::CastLossy + | PuzzleInstructionType::CommitBhp256 + | PuzzleInstructionType::CommitBhp512 + | PuzzleInstructionType::CommitBhp768 + | PuzzleInstructionType::CommitBhp1024 + | PuzzleInstructionType::CommitPed64 + | PuzzleInstructionType::CommitPed128 + | PuzzleInstructionType::HashBhp256 + | PuzzleInstructionType::HashBhp512 + | PuzzleInstructionType::HashBhp768 + | PuzzleInstructionType::HashBhp1024 + | PuzzleInstructionType::HashKeccak256 + | PuzzleInstructionType::HashKeccak384 + | PuzzleInstructionType::HashKeccak512 + | PuzzleInstructionType::HashPed64 + | PuzzleInstructionType::HashPed128 + | PuzzleInstructionType::HashPsd2 + | PuzzleInstructionType::HashPsd4 + | PuzzleInstructionType::HashPsd8 + | PuzzleInstructionType::HashSha3256 + | PuzzleInstructionType::HashSha3384 + | PuzzleInstructionType::HashSha3512 + ) { + // Check that there is at least one destination. + if instruction_destinations.is_empty() { + match cfg!(debug_assertions) { + true => panic!("No destination for the `cast`, `commit`, or `hash` instruction"), + false => eprintln!("No destination for the `cast`, `commit`, or `hash` instruction"), + } + // Move to the next instruction type. + continue 'outer; + } + // Check the the first destination is a register. + match instruction_destinations[0] { + PuzzleDestination::Ephemeral(literal_type, _) | PuzzleDestination::Register(literal_type) => { + instruction_string.push_str(&format!(" as {literal_type}")); + } + } + } + instruction_string.push(';'); + + // Attempt to parse the instruction. + let Ok(instruction) = Instruction::::from_str(&instruction_string) else { + match cfg!(debug_assertions) { + true => panic!("Failed to parse instruction: {instruction_string}"), + false => eprintln!("Failed to parse instruction: {instruction_string}"), + } + // Move to the next instruction type. + continue 'outer; + }; + + // Check that the instruction is not already contained in the instructions. + if instructions.contains(&instruction) { + match cfg!(debug_assertions) { + true => panic!("Duplicate instruction: {instruction_string}"), + false => eprintln!("Duplicate instruction: {instruction_string}"), + } + // Move to the next instruction type. + continue 'outer; + } + + // Add the instruction to the constructed sequence. + constructed_sequence.push(instruction); + } + // Add the constructed sequence to the instructions. + // This is done to ensure that partial sequences are not added to the instructions. + // Note that we already check that the instructions are unique. + for instruction in constructed_sequence { + instructions.insert(instruction); + opcode_count += 1; + } + } + + Ok(instructions) +} + +#[cfg(test)] +pub(crate) mod tests { + use super::*; + use crate::synthesis::helpers::register_table::tests::{NUM_INPUTS, NUM_PREAMBLE_INSTRUCTIONS}; + + use console::{prelude::TestRng, program::Identifier}; + use snarkvm_synthesizer_program::Program; + + type CurrentNetwork = console::network::MainnetV0; + + const ITERATIONS: u64 = 25; + + #[test] + fn test_sample_instructions() { + let mut rng = TestRng::default(); + + for _ in 0..ITERATIONS { + // Sample the epoch hash. + let epoch_hash = rng.gen(); + + // Initialize the register table. + let mut register_table = RegisterTable::new(); + // Sample the instructions. + let instructions = sample_instructions::(epoch_hash, &mut register_table).unwrap(); + + // Define the minimum instruction length. + let min = NUM_INSTRUCTIONS.saturating_sub(NUM_SEQUENCE_INSTRUCTIONS); + // Define the maximum instruction length. + let max = NUM_INSTRUCTIONS; + + // Check that the number of instructions is within the expected range. + assert!( + (min..=max).contains(&instructions.len()), + "Expected {} instructions to be in the range {min}..={max}", + instructions.len() + ); + } + } + + #[test] + fn test_sample_program() { + let mut rng = TestRng::default(); + + for _ in 0..ITERATIONS { + // Sample the epoch hash. + let epoch_hash = rng.gen(); + + // Initialize the register table. + let mut register_table = RegisterTable::new(); + // Sample the instructions. + let instructions = sample_instructions::(epoch_hash, &mut register_table).unwrap(); + + // Construct the program inputs, as a string. + let input_string = register_table.input_block().to_string(); + + // Construct the program instructions, as a string. + let mut instruction_string = String::new(); + for instruction in instructions.iter() { + instruction_string.push_str(&format!(" {instruction}\n")); + } + + // Construct the program string. + let program_string = format!(r"program puzzle.aleo;function synthesize:{input_string}{instruction_string}"); + + // Construct the program. + let program = Program::::from_str(&program_string).unwrap(); + + // Get the function. + let function = program.get_function_ref(&Identifier::from_str("synthesize").unwrap()).unwrap(); + + // Check that the number of inputs is correct. + assert_eq!(function.inputs().len(), NUM_INPUTS, "Update me if the design is changed."); + + // Check that the number of instructions is within the expected range. + let min = NUM_PREAMBLE_INSTRUCTIONS + NUM_INSTRUCTIONS.saturating_sub(NUM_SEQUENCE_INSTRUCTIONS); + let max = NUM_PREAMBLE_INSTRUCTIONS + NUM_INSTRUCTIONS; + assert!( + (min..=max).contains(&function.instructions().len()), + "Expected {} instructions to be in the range {min}..={max}", + function.instructions().len() + ); + } + } + + #[test] + fn test_sample_instructions_is_deterministic() { + for seed in 0..ITERATIONS { + let mut rng = TestRng::fixed(seed); + + // Sample the epoch hash. + let epoch_hash = rng.gen(); + + // Initialize the register table. + let mut register_table = RegisterTable::new(); + // Sample the instructions. + let instructions_1 = sample_instructions::(epoch_hash, &mut register_table).unwrap(); + + for _ in 0..ITERATIONS { + // Initialize the register table. + let mut register_table = RegisterTable::new(); + // Sample the instructions. + let instructions_2 = sample_instructions::(epoch_hash, &mut register_table).unwrap(); + + // Check that the instructions are the same. + assert_eq!(instructions_1, instructions_2); + } + } + } +} diff --git a/ledger/puzzle/epoch/src/synthesis/helpers/operand.rs b/ledger/puzzle/epoch/src/synthesis/helpers/operand.rs new file mode 100644 index 0000000000..9e81033969 --- /dev/null +++ b/ledger/puzzle/epoch/src/synthesis/helpers/operand.rs @@ -0,0 +1,60 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 console::{ + prelude::Network, + program::{Literal, LiteralType}, +}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub enum PuzzleOperand { + Ephemeral(LiteralType, u16), + Input(LiteralType, u16), + Literal(Literal), + Register(LiteralType), + RegisterOffset(LiteralType, u16), +} + +impl PuzzleOperand { + /// Returns whether or not the puzzle operand is an ephemeral register. + #[inline] + pub fn is_ephemeral(&self) -> bool { + matches!(self, Self::Ephemeral(_, _)) + } + + /// Returns whether or not the puzzle operand is an input register. + #[inline] + pub fn is_input(&self) -> bool { + matches!(self, Self::Input(_, _)) + } + + /// Returns whether or not the puzzle operand is a literal. + #[inline] + pub fn is_literal(&self) -> bool { + matches!(self, Self::Literal(_)) + } + + /// Returns whether or not the puzzle operand is a register. + #[inline] + pub fn is_register(&self) -> bool { + matches!(self, Self::Register(_)) + } + + /// Returns whether or not the puzzle operand is a register offset. + #[inline] + pub fn is_register_offset(&self) -> bool { + matches!(self, Self::RegisterOffset(_, _)) + } +} diff --git a/ledger/puzzle/epoch/src/synthesis/helpers/register.rs b/ledger/puzzle/epoch/src/synthesis/helpers/register.rs new file mode 100644 index 0000000000..7767e03327 --- /dev/null +++ b/ledger/puzzle/epoch/src/synthesis/helpers/register.rs @@ -0,0 +1,44 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 std::fmt::Display; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum PuzzleRegister { + Locator(u64), +} + +impl From for PuzzleRegister { + /// Initializes a new register locator. + fn from(locator: u64) -> Self { + Self::new_locator(locator) + } +} + +impl PuzzleRegister { + /// Initializes a new register locator. + pub const fn new_locator(locator: u64) -> Self { + Self::Locator(locator) + } +} + +impl Display for PuzzleRegister { + /// Returns the display string for the register. + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Locator(locator) => write!(f, "r{locator}"), + } + } +} diff --git a/ledger/puzzle/epoch/src/synthesis/helpers/register_table.rs b/ledger/puzzle/epoch/src/synthesis/helpers/register_table.rs new file mode 100644 index 0000000000..bbf87ba585 --- /dev/null +++ b/ledger/puzzle/epoch/src/synthesis/helpers/register_table.rs @@ -0,0 +1,360 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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::synthesis::helpers::{LiteralType, PuzzleRegister}; + +use anyhow::{Result, anyhow, bail}; +use indexmap::{IndexMap, IndexSet, indexmap, indexset}; + +/// A register table is used to track the registers for each literal type. +/// +/// For example, the following is an example of what a register table (in use) might look like: +/// ```ignore +/// field => { r0, r1, r7, r10 } +/// u8 => { r2, r3, r6, r8 } +/// u16 => { r4, r5, r9 } +/// ``` +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct RegisterTable { + /// The input block. + input_block: String, + /// The input register types (ordered). + input_register_types: Vec, + /// The mapping of literal type to its input registers. + input_registers: IndexMap>, + /// The mapping of literal type to its registers. + register_table: IndexMap>, + /// The tracker for the next register locator. + next_register_locator: u64, +} + +impl RegisterTable { + /// Initializes a new register table. + pub fn new() -> Self { + // Set the input block. + let input_block = r" + input r0 as boolean.public; + input r1 as boolean.public; + input r2 as i8.public; + input r3 as i8.public; + input r4 as i16.public; + input r5 as i16.public; + input r6 as i32.public; + input r7 as i32.public; + input r8 as i64.public; + input r9 as i64.public; + input r10 as i128.public; + input r11 as i128.public; + input r12 as field.public; + input r13 as field.public; + + is.eq r1 r0 into r14; + is.eq r3 r2 into r15; + is.eq r5 r4 into r16; + is.eq r7 r6 into r17; + is.eq r9 r8 into r18; + is.eq r11 r10 into r19; + + hash.psd2 r12 into r20 as u8; + hash.psd2 r13 into r21 as u8; + + hash.psd2 r12 into r22 as u16; + hash.psd2 r13 into r23 as u16; + + hash.psd2 r12 into r24 as u32; + hash.psd2 r13 into r25 as u32; + + hash.psd2 r12 into r26 as u64; + hash.psd2 r13 into r27 as u64; + + hash.psd2 r12 into r28 as u128; + hash.psd2 r13 into r29 as u128; + + mul.w r3 r2 into r30; + mul.w r5 r4 into r31; + mul.w r7 r6 into r32; + mul.w r9 r8 into r33; + mul.w r11 r10 into r34; + + ternary r15 r30 r2 into r35; + ternary r16 r31 r4 into r36; + ternary r17 r32 r6 into r37; + ternary r18 r33 r8 into r38; + ternary r19 r34 r10 into r39; +" + .to_string(); + + // Set the input register types. + let input_register_types = vec![ + LiteralType::Boolean, + LiteralType::Boolean, + LiteralType::I8, + LiteralType::I8, + LiteralType::I16, + LiteralType::I16, + LiteralType::I32, + LiteralType::I32, + LiteralType::I64, + LiteralType::I64, + LiteralType::I128, + LiteralType::I128, + LiteralType::Field, + LiteralType::Field, + ]; + + // Construct the input registers. + let input_registers = indexmap! { + LiteralType::Boolean => indexset![PuzzleRegister::new_locator(0), PuzzleRegister::new_locator(1)], + LiteralType::I8 => indexset![PuzzleRegister::new_locator(2), PuzzleRegister::new_locator(3)], + LiteralType::I16 => indexset![PuzzleRegister::new_locator(4), PuzzleRegister::new_locator(5)], + LiteralType::I32 => indexset![PuzzleRegister::new_locator(6), PuzzleRegister::new_locator(7)], + LiteralType::I64 => indexset![PuzzleRegister::new_locator(8), PuzzleRegister::new_locator(9)], + LiteralType::I128 => indexset![PuzzleRegister::new_locator(10), PuzzleRegister::new_locator(11)], + LiteralType::Field => indexset![PuzzleRegister::new_locator(12), PuzzleRegister::new_locator(13)], + }; + + // Construct the register table. + let register_table = indexmap! { + LiteralType::Boolean => indexset![PuzzleRegister::new_locator(0), PuzzleRegister::new_locator(1)], + LiteralType::I8 => indexset![PuzzleRegister::new_locator(3), PuzzleRegister::new_locator(35)], + LiteralType::I16 => indexset![PuzzleRegister::new_locator(5), PuzzleRegister::new_locator(36)], + LiteralType::I32 => indexset![PuzzleRegister::new_locator(7), PuzzleRegister::new_locator(37)], + LiteralType::I64 => indexset![PuzzleRegister::new_locator(9), PuzzleRegister::new_locator(38)], + LiteralType::I128 => indexset![PuzzleRegister::new_locator(11), PuzzleRegister::new_locator(39)], + LiteralType::Field => indexset![PuzzleRegister::new_locator(12), PuzzleRegister::new_locator(13)], + LiteralType::U8 => indexset![PuzzleRegister::new_locator(20), PuzzleRegister::new_locator(21)], + LiteralType::U16 => indexset![PuzzleRegister::new_locator(22), PuzzleRegister::new_locator(23)], + LiteralType::U32 => indexset![PuzzleRegister::new_locator(24), PuzzleRegister::new_locator(25)], + LiteralType::U64 => indexset![PuzzleRegister::new_locator(26), PuzzleRegister::new_locator(27)], + LiteralType::U128 => indexset![PuzzleRegister::new_locator(28), PuzzleRegister::new_locator(29)], + }; + + // Set the next register locator. + let next_register_locator = 40; + + // Return the register table. + Self { input_block, input_register_types, input_registers, register_table, next_register_locator } + } +} + +impl RegisterTable { + /// Returns the input block. + #[inline] + pub fn input_block(&self) -> &str { + &self.input_block + } + + /// Returns the input register types. + #[inline] + pub fn input_register_types(&self) -> &[LiteralType] { + &self.input_register_types + } + + /// Returns and increments the next register locator. + #[inline] + pub fn get_next_locator(&mut self) -> Result { + // Get the current locator. + let locator = self.next_register_locator; + // Update the next register locator. + self.next_register_locator = self + .next_register_locator + .checked_add(1) + .ok_or_else(|| anyhow!("Failed to update the next register locator"))?; + // Return the result. + Ok(locator) + } + + /// Inserts the given literal type and register locator into the register table. + #[inline] + pub fn insert(&mut self, literal_type: LiteralType, register: PuzzleRegister) -> Result<()> { + // Retrieve the registers for the given literal type. + let Some(registers) = self.register_table.get_mut(&literal_type) else { + bail!("Failed to retrieve registers for literal type {literal_type:?} in the register table"); + }; + + // Insert the register into the registers. + registers.insert(register); + + Ok(()) + } + + /// Returns the k-th last register for the given literal type in the register table. + #[inline] + pub fn get_k_th_last_register(&self, literal_type: &LiteralType, k: usize) -> Result { + // Retrieve the registers for the given literal type. + let Some(registers) = self.register_table.get(literal_type) else { + bail!("Failed to retrieve registers for literal type {literal_type:?} in the register table"); + }; + + // Get the k-th last register. + let index = registers.len().saturating_sub(k).saturating_sub(1); + match registers.get_index(index) { + Some(register) => Ok(*register), + None => bail!("Invalid offset {k} for registers for literal type {literal_type:?} in the register table"), + } + } +} + +impl RegisterTable { + /// Returns `true` if the register table is empty. + #[inline] + pub fn is_empty(&self) -> bool { + self.register_table.is_empty() + } + + /// Returns the number of literal types in the register table. + #[inline] + pub fn len(&self) -> usize { + self.register_table.len() + } + + /// Returns `true` if the input registers contain the given literal type. + #[inline] + pub fn contains_input(&self, literal_type: &LiteralType) -> bool { + self.input_registers.contains_key(literal_type) + } + + /// Returns `true` if the register table contains the given literal type. + #[inline] + pub fn contains_key(&self, literal_type: &LiteralType) -> bool { + self.register_table.contains_key(literal_type) + } + + /// Returns a reference to the registers for the given literal type in the register table. + #[inline] + pub fn get(&self, literal_type: &LiteralType) -> Option<&IndexSet> { + self.register_table.get(literal_type) + } + + /// Returns a reference to the input register at an index for the given literal type. + #[inline] + pub fn get_input_at_index(&self, literal_type: &LiteralType, index: usize) -> Option<&PuzzleRegister> { + self.input_registers.get(literal_type).and_then(|registers| registers.get_index(index)) + } + + /// Returns an iterator over the register table. + #[inline] + pub fn iter(&self) -> impl Iterator)> { + self.register_table.iter() + } + + /// Returns the literal types in the register table. + #[inline] + pub fn keys(&self) -> impl Iterator { + self.register_table.keys() + } + + /// Returns the registers in the register table. + #[inline] + pub fn values(&self) -> impl Iterator> { + self.register_table.values() + } +} + +impl IntoIterator for RegisterTable { + type IntoIter = indexmap::map::IntoIter>; + type Item = (LiteralType, IndexSet); + + /// Returns the literal types and registers in the register table. + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.register_table.into_iter() + } +} + +#[cfg(test)] +pub(crate) mod tests { + use super::*; + use console::{network::MainnetV0, program::Identifier}; + use snarkvm_synthesizer_program::Program; + use std::str::FromStr; + + type CurrentNetwork = MainnetV0; + + pub const NUM_PREAMBLE_INSTRUCTIONS: usize = 26; + pub const NUM_INPUTS: usize = 14; + + #[test] + fn test_register_table() { + // The multiplier is hardcoded. + let multiplier = 2; + + // Initialize a new register table. + let register_table = RegisterTable::new(); + + // Check if the register table is empty. + assert!(!register_table.is_empty()); + // Check the number of literal types in the register table. + assert_eq!(register_table.len(), 12); + // Check each literal type in the register table. + assert!(register_table.contains_key(&LiteralType::Boolean)); + assert!(register_table.contains_key(&LiteralType::Field)); + assert!(register_table.contains_key(&LiteralType::I8)); + assert!(register_table.contains_key(&LiteralType::I16)); + assert!(register_table.contains_key(&LiteralType::I32)); + assert!(register_table.contains_key(&LiteralType::I64)); + assert!(register_table.contains_key(&LiteralType::I128)); + assert!(register_table.contains_key(&LiteralType::U8)); + assert!(register_table.contains_key(&LiteralType::U16)); + assert!(register_table.contains_key(&LiteralType::U32)); + assert!(register_table.contains_key(&LiteralType::U64)); + assert!(register_table.contains_key(&LiteralType::U128)); + // Check if the register table contains the registers. + for (_, registers) in register_table.iter() { + assert_eq!(registers.len(), multiplier); + } + // Check the next register locator. + assert_eq!(register_table.next_register_locator, 40, "Update me if the design has changed"); + } + + #[test] + fn test_get_k_th_last_register() { + // Initialize a new register table. + let register_table = RegisterTable::new(); + + for (literal_type, expected_registers) in register_table.iter() { + // Check the 'get' function. + assert_eq!(register_table.get(literal_type), Some(expected_registers)); + // Check the 'get_k_th_last_register' function. + let mut registers = IndexSet::new(); + for k in (0..expected_registers.len()).rev() { + let register = register_table.get_k_th_last_register(literal_type, k).unwrap(); + registers.insert(register); + } + // Check that `registers` matches the `expected_registers`. + assert_eq!(®isters, expected_registers); + } + } + + #[test] + fn test_input_block_is_well_formed() { + // Initialize a new register table. + let register_table = RegisterTable::new(); + + // Initialize a program using the input block. + let program = Program::::from_str(&format!( + "program puzzle.aleo;function synthesize:{}", + register_table.input_block() + )) + .unwrap(); + + // Get the function. + let function = program.get_function_ref(&Identifier::from_str("synthesize").unwrap()).unwrap(); + + // Check that the number of inputs and instructions is well-formed. + assert_eq!(function.inputs().len(), NUM_INPUTS, "Update me if the design has changed"); + assert_eq!(function.instructions().len(), NUM_PREAMBLE_INSTRUCTIONS, "Update me if the design has changed"); + } +} diff --git a/ledger/puzzle/epoch/src/synthesis/mod.rs b/ledger/puzzle/epoch/src/synthesis/mod.rs new file mode 100644 index 0000000000..1441baea82 --- /dev/null +++ b/ledger/puzzle/epoch/src/synthesis/mod.rs @@ -0,0 +1,190 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +mod helpers; +pub use helpers::*; + +mod program; +pub use program::*; + +use circuit::Aleo; +use console::network::Network; +use snarkvm_ledger_puzzle::PuzzleTrait; + +use anyhow::{Result, bail}; +use core::{marker::PhantomData, num::NonZeroUsize}; +use lru::LruCache; +use parking_lot::RwLock; +use rand_chacha::ChaChaRng; +use std::sync::Arc; + +pub struct SynthesisPuzzle> { + /// The LRU cache of epoch programs. + epoch_program_cache: Arc>>>, + /// PhantomData. + _phantom: PhantomData, +} + +impl> PuzzleTrait for SynthesisPuzzle { + /// Initializes a new instance of the puzzle. + fn new() -> Self { + Self { + epoch_program_cache: Arc::new(RwLock::new(LruCache::new(NonZeroUsize::new(16).unwrap()))), + _phantom: PhantomData, + } + } + + /// Returns the leaves for the puzzle, given the epoch hash and seeded RNG. + /// + /// Note: This function uses a thread to ensure the circuit is synthesized in a thread-safe environment. + /// This ensures that `SynthesisPuzzle` can be used in a multi-threaded environment. + fn to_leaves(&self, epoch_hash: N::BlockHash, rng: &mut ChaChaRng) -> Result>> { + // Retrieve the epoch program. + let epoch_program = self.get_epoch_program(epoch_hash)?; + // Construct the epoch program inputs. + let inputs = epoch_program.construct_inputs(rng)?; + // Spawn a thread to ensure the circuit is synthesized in a thread-safe environment. + let handle = std::thread::spawn(move || { + // Synthesize the circuit and return the assignment. + epoch_program.to_leaves::(inputs) + }); + // Return the leaves. + match handle.join() { + Ok(Ok(leaves)) => Ok(leaves), + Ok(Err(error)) => Err(error), + Err(error) => bail!("Failed to join thread in 'SynthesisPuzzle::to_leaves': {error:?}"), + } + } + + /// Returns the batches of leaves for the puzzle, given the epoch hash and seeded RNGs. + /// + /// Note: This function uses a thread to ensure the circuit is synthesized in a thread-safe environment. + /// This ensures that `SynthesisPuzzle` can be used in a multi-threaded environment. + fn to_all_leaves(&self, epoch_hash: N::BlockHash, rngs: Vec) -> Result>>> { + // Retrieve the number of instances. + let num_instances = rngs.len(); + // Retrieve the epoch program. + let epoch_program = self.get_epoch_program(epoch_hash)?; + // Initialize the list of handles. + let mut handles = Vec::with_capacity(num_instances); + // Construct the epoch program inputs. + for mut rng in rngs { + let epoch_program = epoch_program.clone(); + // Spawn a thread to ensure the circuit is synthesized in a thread-safe environment. + handles.push(std::thread::spawn(move || { + // Construct the epoch program inputs. + let inputs = epoch_program.construct_inputs(&mut rng)?; + // Synthesize the circuit and return the assignment. + epoch_program.to_leaves::(inputs) + })); + } + // Collect the leaves. + let mut leaves = Vec::with_capacity(num_instances); + for handle in handles { + leaves.push(match handle.join() { + Ok(Ok(leaves)) => leaves, + Ok(Err(error)) => return Err(error), + Err(error) => bail!("Failed to join threads in 'SynthesisPuzzle::to_all_leaves': {error:?}"), + }); + } + // Return the leaves. + Ok(leaves) + } +} + +impl> SynthesisPuzzle { + /// Returns the epoch program for the given epoch hash. + pub fn get_epoch_program(&self, epoch_hash: N::BlockHash) -> Result> { + // If the epoch program is in the cache, return it. + if let Some(epoch_program) = self.epoch_program_cache.write().get(&epoch_hash) { + return Ok(epoch_program.clone()); + } + + // Initialize the epoch program. + let epoch_program = EpochProgram::new(epoch_hash)?; + // Insert the epoch program into the cache. + self.epoch_program_cache.write().put(epoch_hash, epoch_program.clone()); + // Return the epoch program. + Ok(epoch_program) + } +} + +/// Attention: This is *safe* because we do not instantiate `N` or `A` in this struct. +/// This implementation of `Send` and `Sync` cannot be applied to `A` directly for thread safety. +unsafe impl> Send for SynthesisPuzzle {} +unsafe impl> Sync for SynthesisPuzzle {} + +#[cfg(test)] +mod tests { + use super::*; + use rand::SeedableRng; + + type CurrentNetwork = console::network::MainnetV0; + type CurrentAleo = circuit::AleoV0; + + #[test] + fn test_get_epoch_program() { + // Initialize the epoch hash. + let epoch_hash = ::BlockHash::default(); + // Initialize the puzzle. + let puzzle = SynthesisPuzzle::::new(); + // Sample the epoch program, and ensure it succeeds. + let program_0 = puzzle.get_epoch_program(epoch_hash).unwrap(); + + // Fetch the epoch program again, and ensure it matches (from the cache). + let program_1 = puzzle.get_epoch_program(epoch_hash).unwrap(); + assert_eq!(program_0, program_1); + } + + #[test] + fn test_to_leaves() { + // Initialize the epoch hash. + let epoch_hash = ::BlockHash::default(); + // Initialize the puzzle. + let puzzle = SynthesisPuzzle::::new(); + + // Sample the epoch program. + let program = puzzle.get_epoch_program(epoch_hash).unwrap(); + // Directly construct the leaves. + let inputs = program.construct_inputs(&mut ChaChaRng::seed_from_u64(0)).unwrap(); + let leaves_0 = program.to_leaves::(inputs).unwrap(); + + // Sample the leaves. + let leaves_1 = puzzle.to_leaves(epoch_hash, &mut ChaChaRng::seed_from_u64(0)).unwrap(); + // Ensure the leaves match. + assert_eq!(leaves_0, leaves_1); + } + + #[test] + fn test_to_all_leaves() { + // Initialize the epoch hash. + let epoch_hash = ::BlockHash::default(); + // Initialize the puzzle. + let puzzle = SynthesisPuzzle::::new(); + + // Sample the leaves. + let leaves = + puzzle.to_all_leaves(epoch_hash, vec![ChaChaRng::seed_from_u64(0), ChaChaRng::seed_from_u64(1)]).unwrap(); + // Ensure the number of leaves is within the expected range. + assert_eq!(leaves.len(), 2); + + // Now, ensure it matches with the call to `to_leaves`. + let leaves_single = puzzle.to_leaves(epoch_hash, &mut ChaChaRng::seed_from_u64(0)).unwrap(); + assert_eq!(leaves_single, leaves[0]); + + let leaves_single = puzzle.to_leaves(epoch_hash, &mut ChaChaRng::seed_from_u64(1)).unwrap(); + assert_eq!(leaves_single, leaves[1]); + } +} diff --git a/ledger/puzzle/epoch/src/synthesis/program/construct_inputs.rs b/ledger/puzzle/epoch/src/synthesis/program/construct_inputs.rs new file mode 100644 index 0000000000..6b91504808 --- /dev/null +++ b/ledger/puzzle/epoch/src/synthesis/program/construct_inputs.rs @@ -0,0 +1,69 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl EpochProgram { + /// Construct the inputs for the given epoch program. + pub fn construct_inputs(&self, rng: &mut ChaChaRng) -> Result>> { + // Prepare the inputs. + let mut inputs = Vec::new(); + + // Iterate over the input registers. + for literal_type in self.register_table().input_register_types() { + // Initialize the literal. + let literal = match literal_type { + // If the literal type is a `boolean`, then generate a random `boolean` element. + LiteralType::Boolean => Literal::::Boolean(rng.gen()), + // If the literal type is a `field`, then generate a random non-zero `field` element. + LiteralType::Field => { + let field = Field::::rand(rng); + match field.is_zero() { + true => return Err(anyhow!("Invalid input, zero field element found")), + false => Literal::::Field(field), + } + } + // If the literal type is a `i8`, then generate a random `i8`. + LiteralType::I8 => Literal::::I8(rng.gen()), + // If the literal type is a `i16`, then generate a random `i16`. + LiteralType::I16 => Literal::::I16(rng.gen()), + // If the literal type is a `i32`, then generate a random `i32`. + LiteralType::I32 => Literal::::I32(rng.gen()), + // If the literal type is a `i64`, then generate a random `i64`. + LiteralType::I64 => Literal::::I64(rng.gen()), + // If the literal type is a `i128`, then generate a random `i128`. + LiteralType::I128 => Literal::::I128(rng.gen()), + // Unreachable. + LiteralType::Address + | LiteralType::Group + | LiteralType::U8 + | LiteralType::U16 + | LiteralType::U32 + | LiteralType::U64 + | LiteralType::U128 + | LiteralType::Scalar + | LiteralType::Signature + | LiteralType::String => { + unreachable!("Invalid input literal type, malformed program"); + } + }; + + // Store the input. + inputs.push(Value::from(literal)); + } + + Ok(inputs) + } +} diff --git a/ledger/puzzle/epoch/src/synthesis/program/mod.rs b/ledger/puzzle/epoch/src/synthesis/program/mod.rs new file mode 100644 index 0000000000..d1a1ac2298 --- /dev/null +++ b/ledger/puzzle/epoch/src/synthesis/program/mod.rs @@ -0,0 +1,183 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +mod construct_inputs; +mod to_leaves; +mod to_r1cs; + +use crate::synthesis::helpers::*; +use circuit::{Mode, environment::R1CS}; +use console::{ + account::PrivateKey, + network::Network, + prelude::{Itertools, ToBits as TBits, Uniform, Zero}, + program::{Field, Identifier, Literal, LiteralType, Value}, +}; +use snarkvm_synthesizer_process::{CallStack, Process, Registers, Stack, StackProgramTypes}; +use snarkvm_synthesizer_program::{Instruction, Program, RegistersStoreCircuit, StackProgram}; + +use aleo_std::prelude::{finish, lap, timer}; +use anyhow::{Result, anyhow, bail, ensure}; +use rand::Rng; +use rand_chacha::ChaChaRng; +use std::{ + fmt::{self, Debug, Formatter}, + ops::Deref, + str::FromStr, +}; + +/// The arity of the Merkle tree. +const ARITY: u8 = 8; + +#[derive(Clone)] +pub struct EpochProgram { + /// The program stack for the epoch. + stack: Stack, + /// The register table. + register_table: RegisterTable, + /// The epoch hash. + epoch_hash: N::BlockHash, +} + +impl Debug for EpochProgram { + /// Formats the epoch program for debugging. + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("EpochProgram") + .field("epoch_hash", &self.epoch_hash) + .field("program", self.stack.program()) + .finish() + } +} + +impl PartialEq for EpochProgram { + /// Returns `true` if the epoch programs are equal. + fn eq(&self, other: &Self) -> bool { + self.epoch_hash == other.epoch_hash && self.stack.program() == other.stack.program() + } +} + +impl Eq for EpochProgram {} + +impl EpochProgram { + /// Initializes a new epoch program, given an epoch. + /// + /// This method deterministically synthesizes a new program. + pub fn new(epoch_hash: N::BlockHash) -> Result { + // Initialize the register table. + let mut register_table = RegisterTable::new(); + + // Construct the program inputs, as a string. + let input_string = register_table.input_block().to_string(); + + // Sample the instructions from the given epoch. + let instructions = sample_instructions::(epoch_hash, &mut register_table)?; + debug_assert!(!instructions.is_empty()); + // Construct the program instructions, as a string. + let mut instruction_string = String::new(); + for instruction in &instructions { + instruction_string.push_str(&format!(" {instruction}\n")); + } + + // Construct the program string. + let program_string = format!( + r"program puzzle.aleo; + +function synthesize: +{input_string} +{instruction_string} +" + ); + + // Construct the program. + let program = Program::from_str(&program_string)?; + + // Initialize a new process. + let process = Process::::load()?; + // Initialize the stack with the synthesis challenge program. + let stack = Stack::new(&process, &program)?; + + Ok(Self { stack, register_table, epoch_hash }) + } +} + +impl EpochProgram { + /// Returns the program stack. + #[inline] + pub const fn stack(&self) -> &Stack { + &self.stack + } + + /// Returns the register table. + #[inline] + pub const fn register_table(&self) -> &RegisterTable { + &self.register_table + } + + /// Returns the epoch. + #[inline] + pub const fn epoch_hash(&self) -> N::BlockHash { + self.epoch_hash + } + + /// Returns the instructions for the program. + #[inline] + pub fn instructions(&self) -> Result<&[Instruction]> { + Ok(self.stack.program().get_function_ref(&Identifier::from_str("synthesize")?)?.instructions()) + } +} + +impl Deref for EpochProgram { + type Target = Program; + + fn deref(&self) -> &Self::Target { + self.stack.program() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use console::prelude::TestRng; + + type CurrentNetwork = console::network::MainnetV0; + + #[test] + fn test_new_is_deterministic() { + let mut rng = TestRng::default(); + + // Initialize a random epoch hash. + let epoch_hash = rng.gen(); + // Initialize a new epoch program. + let epoch_program_0 = EpochProgram::::new(epoch_hash).unwrap(); + // Initialize a new epoch program. + let epoch_program_1 = EpochProgram::::new(epoch_hash).unwrap(); + // Ensure the epoch program matches. + assert_eq!(epoch_program_0, epoch_program_1); + } + + #[test] + fn test_instructions_succeeds() { + let mut rng = TestRng::default(); + + // Initialize a random epoch hash. + let epoch_hash = rng.gen(); + // Initialize a new epoch program. + let epoch_program = EpochProgram::::new(epoch_hash).unwrap(); + // Retrieve the instructions. + let instructions = epoch_program.instructions().unwrap(); + // Ensure the instructions are not empty. + assert!(!instructions.is_empty()); + } +} diff --git a/ledger/puzzle/epoch/src/synthesis/program/to_leaves.rs b/ledger/puzzle/epoch/src/synthesis/program/to_leaves.rs new file mode 100644 index 0000000000..fc246d6930 --- /dev/null +++ b/ledger/puzzle/epoch/src/synthesis/program/to_leaves.rs @@ -0,0 +1,99 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl EpochProgram { + /// Returns the R1CS assignment of the epoch program on the given inputs as a vector of bit sequences. + pub fn to_leaves>(&self, console_inputs: Vec>) -> Result>> { + // Get the R1CS. + let r1cs = self.to_r1cs::(console_inputs)?; + // Retrieve the public variables. + let public_variables = r1cs.to_public_variables(); + // Retrieve the private variables. + let private_variables = r1cs.to_private_variables(); + + // Convert the public and private variables into leaves. + let mut leaves = Vec::with_capacity(public_variables.len() + private_variables.len()); + // Append the public variables. + for public_variable in public_variables { + leaves.push(public_variable.value().to_bits_le()); + } + // Append the private variables. + for private_variable in private_variables { + leaves.push(private_variable.value().to_bits_le()); + } + + // Pad the leaves to the next power of two. + let Some(num_padded_leaves) = checked_next_power_of_n(leaves.len(), ARITY as usize) else { + bail!("Integer overflow when computing the maximum number of leaves in the Merkle tree"); + }; + + // Pad the leaves up to the next power of two. + if leaves.len() < num_padded_leaves { + leaves.resize(num_padded_leaves, vec![false; 254]); + } + + Ok(leaves) + } +} + +/// Returns the next power of `n` that's greater than or equal to `base`. +/// Returns `None` for edge cases or in case of overflow. +fn checked_next_power_of_n(base: usize, n: usize) -> Option { + if n <= 1 { + return None; + } + + let mut value = 1; + while value < base { + value = value.checked_mul(n)?; + } + Some(value) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_next_power_of_n() { + // Test for regular input + assert_eq!(checked_next_power_of_n(10, 2), Some(16)); + assert_eq!(checked_next_power_of_n(1, 3), Some(1)); + assert_eq!(checked_next_power_of_n(25, 5), Some(25)); + assert_eq!(checked_next_power_of_n(26, 5), Some(125)); + + // Test for base being 0 + assert_eq!(checked_next_power_of_n(0, 2), Some(1)); + } + + #[test] + fn test_next_power_of_n_edge_cases() { + // n = 1 (should return None as it's an edge case) + assert_eq!(checked_next_power_of_n(10, 1), None); + + // n = 0 (should return None as it's less than the minimum valid n) + assert_eq!(checked_next_power_of_n(10, 0), None); + } + + #[test] + fn test_next_power_of_n_overflow() { + // Test for potential overflow cases + // Use a large base and n to test overflow, the exact values might need adjustments + // depending on the system's usize limits + assert_eq!(checked_next_power_of_n(usize::MAX, 2), None); + } +} diff --git a/ledger/puzzle/epoch/src/synthesis/program/to_r1cs.rs b/ledger/puzzle/epoch/src/synthesis/program/to_r1cs.rs new file mode 100644 index 0000000000..533f3fc982 --- /dev/null +++ b/ledger/puzzle/epoch/src/synthesis/program/to_r1cs.rs @@ -0,0 +1,125 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl EpochProgram { + /// Synthesizes the R1CS for a program function on the given inputs. + pub fn to_r1cs>(&self, console_inputs: Vec>) -> Result> { + let timer = timer!("synthesize_r1cs"); + + // Declare the function name. + let function_name = Identifier::from_str("synthesize")?; + // Retrieve the function from the program. + let function = self.stack.get_function(&function_name)?; + // Retrieve the number of function inputs. + let num_inputs = function.inputs().len(); + // Retrieve the register types for the function. + let register_types = self.stack.get_register_types(&function_name)?.clone(); + + // Ensure the inputs match their expected types. + ensure!(num_inputs == console_inputs.len(), "Expected {num_inputs} inputs, found {}", console_inputs.len()); + + // Initialize the registers. + let call_stack = CallStack::PackageRun(vec![], PrivateKey::new(&mut rand::thread_rng())?, Default::default()); + let mut registers = Registers::::new(call_stack, register_types); + lap!(timer, "Initialize the registers"); + + // Ensure the circuit environment is clean. + A::reset(); + + // Inject the circuit inputs. + let mut circuit_inputs = Vec::with_capacity(console_inputs.len()); + // Iterate over the console inputs. + for input in console_inputs { + // Inject the input as `Mode::Public`. + let input = as circuit::Inject>::new(Mode::Public, input); + // Store the input. + circuit_inputs.push(input); + } + lap!(timer, "Inject the inputs"); + + // Store the inputs into the registers. + function.inputs().iter().map(|i| i.register()).zip_eq(&circuit_inputs).try_for_each(|(register, input)| { + // Assign the circuit input to the register. + registers.store_circuit(&self.stack, register, input.clone()) + })?; + lap!(timer, "Store the inputs"); + + // Execute the instructions. + for instruction in function.instructions() { + // If the execution fails, bail and return the error. + if let Err(error) = instruction.execute(&self.stack, &mut registers) { + bail!("Failed to execute instruction ({instruction}): {error}"); + } + + #[cfg(debug_assertions)] + { + use circuit::Eject; + use snarkvm_synthesizer_program::RegistersLoadCircuit; + + use colored::Colorize; + + let is_satisfied = A::is_satisfied(); + println!( + "Executing instruction ({instruction}) ({})", + if is_satisfied { "✅".green() } else { "❌".red() } + ); + if !is_satisfied { + for operand in instruction.operands() { + let value = registers.load_circuit(&self.stack, operand)?; + println!(" {operand} = {}", value.eject_value()); + } + } + } + } + lap!(timer, "Execute the instructions"); + + #[cfg(debug_assertions)] + log_circuit::(function_name.to_string()); + + // If the circuit is empty or not satisfied, then throw an error. + ensure!( + A::num_constraints() > 0 && A::is_satisfied(), + "'{}/{function_name}' is not satisfied on the given inputs.", + self.stack.program_id(), + ); + lap!(timer, "Ensure the circuit is satisfied"); + + // Eject the R1CS and reset the circuit. + let r1cs = A::eject_r1cs_and_reset(); + finish!(timer, "Eject the circuit assignment and reset the circuit"); + + Ok(r1cs) + } +} + +/// Prints the current state of the circuit. +#[cfg(debug_assertions)] +pub(crate) fn log_circuit, S: Into>(scope: S) { + use colored::Colorize; + + // Determine if the circuit is satisfied. + let is_satisfied = if A::is_satisfied() { "✅".green() } else { "❌".red() }; + // Determine the count. + let (num_constant, num_public, num_private, num_constraints, num_nonzeros) = A::count(); + + // Print the log. + println!( + "{is_satisfied} {:width$} (Constant: {num_constant}, Public: {num_public}, Private: {num_private}, Constraints: {num_constraints}, NonZeros: {num_nonzeros:?})", + scope.into().bold(), + width = 20 + ); +} diff --git a/ledger/puzzle/src/lib.rs b/ledger/puzzle/src/lib.rs new file mode 100644 index 0000000000..b52eaae061 --- /dev/null +++ b/ledger/puzzle/src/lib.rs @@ -0,0 +1,711 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +#![forbid(unsafe_code)] +#![allow(clippy::too_many_arguments)] +#![warn(clippy::cast_possible_truncation)] + +mod partial_solution; +pub use partial_solution::*; + +mod solution; +pub use solution::*; + +mod solution_id; +pub use solution_id::*; + +mod solutions; +pub use solutions::*; + +use console::{ + account::Address, + algorithms::Sha3_256, + collections::kary_merkle_tree::KaryMerkleTree, + prelude::{ + FromBits, + Network, + Result, + anyhow, + bail, + cfg_into_iter, + cfg_iter, + cfg_keys, + cfg_values, + ensure, + has_duplicates, + }, + types::U64, +}; + +use aleo_std::prelude::*; +use core::num::NonZeroUsize; +use indexmap::IndexMap; +use lru::LruCache; +use parking_lot::RwLock; +use rand::SeedableRng; +use rand_chacha::ChaChaRng; +use std::sync::Arc; + +#[cfg(not(feature = "serial"))] +use rayon::prelude::*; + +/// The arity of the Merkle tree. +const ARITY: u8 = 8; +/// The size of the cache. +const CACHE_SIZE: usize = 1 << 10; + +/// The Merkle tree for the puzzle. +type MerkleTree = KaryMerkleTree; + +/// The puzzle trait. +pub trait PuzzleTrait: Send + Sync { + /// Initializes a new instance of the puzzle. + fn new() -> Self + where + Self: Sized; + + /// Returns the leaves for the puzzle, given the epoch hash and seeded RNG. + fn to_leaves(&self, epoch_hash: N::BlockHash, rng: &mut ChaChaRng) -> Result>>; + + /// Returns the batches of leaves for the puzzle, given the epoch hash and seeded RNGs. + fn to_all_leaves(&self, epoch_hash: N::BlockHash, rngs: Vec) -> Result>>>; +} + +#[derive(Clone)] +pub struct Puzzle { + /// The core puzzle. + inner: Arc>, + /// The LRU cache of solution IDs to proof targets. + proof_target_cache: Arc, u64>>>, +} + +impl Puzzle { + /// Initializes a new puzzle instance. + pub fn new + 'static>() -> Self { + Self { + inner: Arc::new(P::new()), + proof_target_cache: Arc::new(RwLock::new(LruCache::new(NonZeroUsize::new(CACHE_SIZE).unwrap()))), + } + } + + /// Returns the Merkle leaves for the puzzle, given the solution. + pub fn get_leaves(&self, solution: &PartialSolution) -> Result>> { + // Initialize a seeded random number generator. + let mut rng = ChaChaRng::seed_from_u64(*solution.id()); + // Output the leaves. + self.inner.to_leaves(solution.epoch_hash(), &mut rng) + } + + /// Returns each of the Merkle leaves for the puzzle, given the solutions. + pub fn get_all_leaves(&self, solutions: &PuzzleSolutions) -> Result>>> { + // Ensure all of the solutions are for the same epoch. + ensure!( + cfg_values!(solutions).all(|solution| solution.epoch_hash() == solutions[0].epoch_hash()), + "The solutions are for different epochs" + ); + // Construct the RNGs. + let rngs = cfg_keys!(solutions).map(|solution_id| ChaChaRng::seed_from_u64(**solution_id)).collect::>(); + // Output the leaves. + self.inner.to_all_leaves(solutions[0].epoch_hash(), rngs) + } + + /// Returns the proof target given the solution. + pub fn get_proof_target(&self, solution: &Solution) -> Result { + // Calculate the proof target. + let proof_target = self.get_proof_target_unchecked(solution)?; + // Ensure the proof target matches the expected proof target. + ensure!(solution.target() == proof_target, "The proof target does not match the expected proof target"); + // Return the proof target. + Ok(proof_target) + } + + /// Returns the proof target given the solution. + /// + /// Note: This method does **not** check the proof target against the expected proof target. + pub fn get_proof_target_unchecked(&self, solution: &Solution) -> Result { + // Calculate the proof target. + self.get_proof_target_from_partial_solution(solution.partial_solution()) + } + + /// Returns the proof target given the partial solution. + pub fn get_proof_target_from_partial_solution(&self, partial_solution: &PartialSolution) -> Result { + // If the proof target is in the cache, then return it. + if let Some(proof_target) = self.proof_target_cache.write().get(&partial_solution.id()) { + return Ok(*proof_target); + } + + // Construct the leaves of the Merkle tree. + let leaves = self.get_leaves(partial_solution)?; + // Get the proof target. + let proof_target = Self::leaves_to_proof_target(&leaves)?; + + // Insert the proof target into the cache. + self.proof_target_cache.write().put(partial_solution.id(), proof_target); + // Return the proof target. + Ok(proof_target) + } + + /// Returns the proof targets given the solutions. + pub fn get_proof_targets(&self, solutions: &PuzzleSolutions) -> Result> { + // Initialize the list of proof targets. + let mut targets = vec![0u64; solutions.len()]; + + // Initialize a list of solutions that need to be computed for the proof target. + let mut to_compute = Vec::new(); + // Iterate over the solutions. + for (i, (id, solution)) in solutions.iter().enumerate() { + // Check if the proof target is in the cache. + match self.proof_target_cache.write().get(id) { + // If the proof target is in the cache, then store it. + Some(proof_target) => { + // Ensure that the proof target matches the expected proof target. + ensure!( + solution.target() == *proof_target, + "The proof target does not match the cached proof target" + ); + targets[i] = *proof_target + } + // Otherwise, add it to the list of solutions that need to be computed. + None => to_compute.push((i, id, *solution)), + } + } + + if !to_compute.is_empty() { + // Construct the solutions object for those that need to be computed. + let solutions_subset = PuzzleSolutions::new(to_compute.iter().map(|(_, _, solution)| *solution).collect())?; + // Construct the leaves of the Merkle tree. + let leaves = self.get_all_leaves(&solutions_subset)?; + // Construct the Merkle roots and truncate them to a u64. + let targets_subset = cfg_iter!(leaves) + .zip(cfg_iter!(solutions_subset)) + .map(|(leaves, (solution_id, solution))| { + // Get the proof target. + let proof_target = Self::leaves_to_proof_target(leaves)?; + // Ensure that the proof target matches the expected proof target. + ensure!( + solution.target() == proof_target, + "The proof target does not match the computed proof target" + ); + // Insert the proof target into the cache. + self.proof_target_cache.write().put(*solution_id, proof_target); + // Return the proof target. + Ok((solution_id, proof_target)) + }) + .collect::>>()?; + + // Recombine the proof targets. + for (i, id, _) in &to_compute { + targets[*i] = targets_subset[id]; + } + } + + // Return the proof targets. + Ok(targets) + } + + /// Returns the combined proof target of the solutions. + pub fn get_combined_proof_target(&self, solutions: &PuzzleSolutions) -> Result { + self.get_proof_targets(solutions)?.into_iter().try_fold(0u128, |combined, proof_target| { + combined.checked_add(proof_target as u128).ok_or_else(|| anyhow!("Combined proof target overflowed")) + }) + } + + /// Returns a solution to the puzzle. + pub fn prove( + &self, + epoch_hash: N::BlockHash, + address: Address, + counter: u64, + minimum_proof_target: Option, + ) -> Result> { + // Construct the partial solution. + let partial_solution = PartialSolution::new(epoch_hash, address, counter)?; + // Compute the proof target. + let proof_target = self.get_proof_target_from_partial_solution(&partial_solution)?; + // Check that the minimum proof target is met. + if let Some(minimum_proof_target) = minimum_proof_target { + if proof_target < minimum_proof_target { + bail!("Solution was below the minimum proof target ({proof_target} < {minimum_proof_target})") + } + } + + // Construct the solution. + Ok(Solution::new(partial_solution, proof_target)) + } + + /// Returns `Ok(())` if the solution is valid. + pub fn check_solution( + &self, + solution: &Solution, + expected_epoch_hash: N::BlockHash, + expected_proof_target: u64, + ) -> Result<()> { + // Ensure the epoch hash matches. + if solution.epoch_hash() != expected_epoch_hash { + bail!( + "Solution does not match the expected epoch hash (found '{}', expected '{expected_epoch_hash}')", + solution.epoch_hash() + ) + } + // Ensure the solution is greater than or equal to the expected proof target. + let proof_target = self.get_proof_target(solution)?; + if proof_target < expected_proof_target { + bail!("Solution does not meet the proof target requirement ({proof_target} < {expected_proof_target})") + } + Ok(()) + } + + /// ATTENTION: This function will update the target if the solution target is different from the calculated one. + /// Returns `Ok(())` if the solution is valid. + pub fn check_solution_mut( + &self, + solution: &mut Solution, + expected_epoch_hash: N::BlockHash, + expected_proof_target: u64, + ) -> Result<()> { + // Ensure the epoch hash matches. + if solution.epoch_hash() != expected_epoch_hash { + bail!( + "Solution does not match the expected epoch hash (found '{}', expected '{expected_epoch_hash}')", + solution.epoch_hash() + ) + } + // Calculate the proof target of the solution. + let proof_target = self.get_proof_target_unchecked(solution)?; + + // Set the target with the newly calculated proof target value. + solution.target = proof_target; + + // Ensure the solution is greater than or equal to the expected proof target. + if proof_target < expected_proof_target { + bail!("Solution does not meet the proof target requirement ({proof_target} < {expected_proof_target})") + } + Ok(()) + } + + /// Returns `Ok(())` if the solutions are valid. + pub fn check_solutions( + &self, + solutions: &PuzzleSolutions, + expected_epoch_hash: N::BlockHash, + expected_proof_target: u64, + ) -> Result<()> { + let timer = timer!("Puzzle::verify"); + + // Ensure the solutions are not empty. + ensure!(!solutions.is_empty(), "The solutions are empty"); + // Ensure the number of solutions does not exceed `MAX_SOLUTIONS`. + if solutions.len() > N::MAX_SOLUTIONS { + bail!("Exceed the maximum number of solutions ({} > {})", solutions.len(), N::MAX_SOLUTIONS) + } + // Ensure the solution IDs are unique. + if has_duplicates(solutions.solution_ids()) { + bail!("The solutions contain duplicate solution IDs"); + } + lap!(timer, "Perform initial checks"); + + // Ensure the epoch hash matches. + cfg_iter!(solutions).try_for_each(|(solution_id, solution)| { + if solution.epoch_hash() != expected_epoch_hash { + bail!("Solution '{solution_id}' did not match the expected epoch hash (found '{}', expected '{expected_epoch_hash}')", solution.epoch_hash()) + } + Ok(()) + })?; + lap!(timer, "Verify each epoch hash matches"); + + // Ensure the solutions meet the proof target requirement. + cfg_into_iter!(self.get_proof_targets(solutions)?).enumerate().try_for_each(|(i, proof_target)| { + if proof_target < expected_proof_target { + bail!( + "Solution '{:?}' did not meet the proof target requirement ({proof_target} < {expected_proof_target})", + solutions.get_index(i).map(|(id, _)| id) + ) + } + Ok(()) + })?; + finish!(timer, "Verify each solution"); + Ok(()) + } + + /// A helper function that takes leaves of a Merkle tree and returns the proof target. + fn leaves_to_proof_target(leaves: &[Vec]) -> Result { + // Construct the Merkle tree. + let merkle_tree = MerkleTree::new(&Sha3_256::default(), &Sha3_256::default(), leaves)?; + // Retrieve the Merkle tree root. + let root = merkle_tree.root(); + // Truncate to a u64. + match *U64::::from_bits_be(&root[0..64])? { + 0 => Ok(u64::MAX), + value => Ok(u64::MAX / value), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use console::{ + account::{Address, PrivateKey}, + network::Network, + prelude::{FromBytes, TestRng, ToBits as TBits, ToBytes, Uniform}, + types::Field, + }; + + use anyhow::Result; + use core::marker::PhantomData; + use rand::{CryptoRng, Rng, RngCore, SeedableRng}; + use rand_chacha::ChaChaRng; + + type CurrentNetwork = console::network::MainnetV0; + + const ITERATIONS: u64 = 100; + + pub struct SimplePuzzle(PhantomData); + + impl PuzzleTrait for SimplePuzzle { + /// Initializes a new instance of the puzzle. + fn new() -> Self { + Self(PhantomData) + } + + /// Returns the leaves for the puzzle, given the epoch hash and seeded RNG. + fn to_leaves(&self, epoch_hash: N::BlockHash, rng: &mut ChaChaRng) -> Result>> { + // Sample a random number of leaves. + let num_leaves = self.num_leaves(epoch_hash)?; + // Sample random field elements for each of the leaves, and convert them to bits. + let leaves = (0..num_leaves).map(|_| Field::::rand(rng).to_bits_le()).collect::>(); + // Return the leaves. + Ok(leaves) + } + + /// Returns the batches of leaves for the puzzle, given the epoch hash and seeded RNGs. + fn to_all_leaves(&self, epoch_hash: N::BlockHash, rngs: Vec) -> Result>>> { + // Sample a random number of leaves. + let num_leaves = self.num_leaves(epoch_hash)?; + // Initialize the list of leaves. + let mut leaves = Vec::with_capacity(rngs.len()); + // Construct the epoch inputs. + for mut rng in rngs { + // Sample random field elements for each of the leaves, and convert them to bits. + leaves.push((0..num_leaves).map(|_| Field::::rand(&mut rng).to_bits_le()).collect::>()); + } + // Return the leaves. + Ok(leaves) + } + } + + impl SimplePuzzle { + /// Returns the number of leaves given the epoch hash. + pub fn num_leaves(&self, epoch_hash: N::BlockHash) -> Result { + const MIN_NUMBER_OF_LEAVES: usize = 100; + const MAX_NUMBER_OF_LEAVES: usize = 200; + + // Prepare the seed. + let seed = u64::from_bytes_le(&epoch_hash.to_bytes_le()?[0..8])?; + // Seed a random number generator from the epoch hash. + let mut epoch_rng = ChaChaRng::seed_from_u64(seed); + // Sample a random number of leaves. + Ok(epoch_rng.gen_range(MIN_NUMBER_OF_LEAVES..MAX_NUMBER_OF_LEAVES)) + } + } + + /// Samples a new puzzle. + fn sample_puzzle() -> Puzzle { + Puzzle::::new::>() + } + + #[test] + fn test_puzzle() { + let mut rng = TestRng::default(); + + // Initialize a new puzzle. + let puzzle = sample_puzzle(); + + // Initialize an epoch hash. + let epoch_hash = rng.gen(); + + for batch_size in 1..=CurrentNetwork::MAX_SOLUTIONS { + // Initialize the solutions. + let solutions = (0..batch_size) + .map(|_| puzzle.prove(epoch_hash, rng.gen(), rng.gen(), None).unwrap()) + .collect::>(); + let solutions = PuzzleSolutions::new(solutions).unwrap(); + + // Ensure the solutions are valid. + assert!(puzzle.check_solutions(&solutions, epoch_hash, 0u64).is_ok()); + + // Ensure the solutions are invalid. + let bad_epoch_hash = rng.gen(); + assert!(puzzle.check_solutions(&solutions, bad_epoch_hash, 0u64).is_err()); + } + } + + #[test] + fn test_prove_with_minimum_proof_target() { + let mut rng = TestRng::default(); + + // Initialize a new puzzle. + let puzzle = sample_puzzle(); + + // Initialize an epoch hash. + let epoch_hash = rng.gen(); + + for _ in 0..ITERATIONS { + let private_key = PrivateKey::::new(&mut rng).unwrap(); + let address = Address::try_from(private_key).unwrap(); + let counter = u64::rand(&mut rng); + + let solution = puzzle.prove(epoch_hash, address, counter, None).unwrap(); + let proof_target = puzzle.get_proof_target(&solution).unwrap(); + + // Assert that the operation will pass if the minimum target is low enough. + assert!(puzzle.prove(epoch_hash, address, counter, Some(proof_target)).is_ok()); + + // Assert that the operation will fail if the minimum target is too high. + assert!(puzzle.prove(epoch_hash, address, counter, Some(proof_target.saturating_add(1))).is_err()); + + let solutions = PuzzleSolutions::new(vec![solution]).unwrap(); + + // Ensure the solution is valid. + assert!(puzzle.check_solutions(&solutions, epoch_hash, proof_target).is_ok()); + + // Ensure the solution is invalid. + assert!(puzzle.check_solutions(&solutions, epoch_hash, proof_target.saturating_add(1)).is_err()); + } + } + + #[test] + fn test_prove_with_no_minimum_proof_target() { + let mut rng = rand::thread_rng(); + + // Initialize a new puzzle. + let puzzle = sample_puzzle(); + + // Initialize an epoch hash. + let epoch_hash = rng.gen(); + + // Generate inputs. + let private_key = PrivateKey::::new(&mut rng).unwrap(); + let address = Address::try_from(private_key).unwrap(); + + // Generate a solution. + let solution = puzzle.prove(epoch_hash, address, rng.gen(), None).unwrap(); + assert!(puzzle.check_solution(&solution, epoch_hash, 0u64).is_ok()); + + let solutions = PuzzleSolutions::new(vec![solution]).unwrap(); + assert!(puzzle.check_solutions(&solutions, epoch_hash, 0u64).is_ok()); + } + + #[test] + fn test_check_solution_with_incorrect_target_fails() { + let mut rng = rand::thread_rng(); + + // Initialize a new puzzle. + let puzzle = sample_puzzle(); + + // Initialize an epoch hash. + let epoch_hash = rng.gen(); + + // Generate inputs. + let private_key = PrivateKey::::new(&mut rng).unwrap(); + let address = Address::try_from(private_key).unwrap(); + + // Generate a solution. + let solution = puzzle.prove(epoch_hash, address, rng.gen(), None).unwrap(); + + // Generate a solution with an incorrect target. + let incorrect_solution = Solution::new(*solution.partial_solution(), solution.target().saturating_add(1)); + + // Ensure the incorrect solution is invalid. + assert!(puzzle.check_solution(&incorrect_solution, epoch_hash, 0u64).is_err()); + + // Ensure the invalid solution is invalid on a fresh puzzle instance. + let new_puzzle = sample_puzzle(); + assert!(new_puzzle.check_solution(&incorrect_solution, epoch_hash, 0u64).is_err()); + + // Ensure the incorrect solutions are invalid. + let incorrect_solutions = PuzzleSolutions::new(vec![incorrect_solution]).unwrap(); + assert!(puzzle.check_solutions(&incorrect_solutions, epoch_hash, 0u64).is_err()); + + // Ensure the incorrect solutions are invalid on a fresh puzzle instance. + let new_puzzle = sample_puzzle(); + assert!(new_puzzle.check_solutions(&incorrect_solutions, epoch_hash, 0u64).is_err()); + } + + #[test] + fn test_check_solutions_with_incorrect_target_fails() { + let mut rng = TestRng::default(); + + // Initialize a new puzzle. + let puzzle = sample_puzzle(); + + // Initialize an epoch hash. + let epoch_hash = rng.gen(); + + for batch_size in 1..=CurrentNetwork::MAX_SOLUTIONS { + // Initialize the incorrect solutions. + let incorrect_solutions = (0..batch_size) + .map(|_| { + let solution = puzzle.prove(epoch_hash, rng.gen(), rng.gen(), None).unwrap(); + Solution::new(*solution.partial_solution(), solution.target().saturating_add(1)) + }) + .collect::>(); + let incorrect_solutions = PuzzleSolutions::new(incorrect_solutions).unwrap(); + + // Ensure the incorrect solutions are invalid. + assert!(puzzle.check_solutions(&incorrect_solutions, epoch_hash, 0u64).is_err()); + + // Ensure the incorrect solutions are invalid on a fresh puzzle instance. + let new_puzzle = sample_puzzle(); + assert!(new_puzzle.check_solutions(&incorrect_solutions, epoch_hash, 0u64).is_err()); + } + } + + #[test] + fn test_check_solutions_with_duplicate_nonces() { + let mut rng = TestRng::default(); + + // Initialize a new puzzle. + let puzzle = sample_puzzle(); + + // Initialize an epoch hash. + let epoch_hash = rng.gen(); + // Initialize an address. + let address = rng.gen(); + // Initialize a counter. + let counter = rng.gen(); + + for batch_size in 1..=CurrentNetwork::MAX_SOLUTIONS { + // Initialize the solutions. + let solutions = + (0..batch_size).map(|_| puzzle.prove(epoch_hash, address, counter, None).unwrap()).collect::>(); + // Ensure the solutions are invalid, if the batch size is greater than 1. + let solutions = match batch_size { + 1 => PuzzleSolutions::new(solutions).unwrap(), + _ => { + assert!(PuzzleSolutions::new(solutions).is_err()); + continue; + } + }; + match batch_size { + 1 => assert!(puzzle.check_solutions(&solutions, epoch_hash, 0u64).is_ok()), + _ => unreachable!("There are duplicates that should not reach this point in the test"), + } + } + } + + #[test] + fn test_get_proof_targets_without_cache() { + let mut rng = TestRng::default(); + + // Initialize an epoch hash. + let epoch_hash = rng.gen(); + + for batch_size in 1..=CurrentNetwork::MAX_SOLUTIONS { + // Initialize a new puzzle. + let puzzle = sample_puzzle(); + // Initialize the solutions. + let solutions = (0..batch_size) + .map(|_| puzzle.prove(epoch_hash, rng.gen(), rng.gen(), None).unwrap()) + .collect::>(); + let solutions = PuzzleSolutions::new(solutions).unwrap(); + + // Reinitialize the puzzle to *clear the cache*. + let puzzle = sample_puzzle(); + + // Compute the proof targets. + let proof_targets = puzzle.get_proof_targets(&solutions).unwrap(); + + // Ensure the proof targets are correct. + for ((_, solution), proof_target) in solutions.iter().zip(proof_targets) { + assert_eq!(puzzle.get_proof_target(solution).unwrap(), proof_target); + } + } + } + + #[test] + fn test_get_proof_targets_with_partial_cache() { + let mut rng = TestRng::default(); + + // Initialize an epoch hash. + let epoch_hash = rng.gen(); + + for batch_size in 1..=CurrentNetwork::MAX_SOLUTIONS { + // Initialize a new puzzle. + let puzzle = sample_puzzle(); + // Initialize the solutions. + let solutions = (0..batch_size) + .map(|_| puzzle.prove(epoch_hash, rng.gen(), rng.gen(), None).unwrap()) + .collect::>(); + let solutions = PuzzleSolutions::new(solutions).unwrap(); + + // Reinitialize the puzzle to *clear the cache*. + let puzzle = sample_puzzle(); + + // Partially fill the cache. + for solution in solutions.values() { + // Flip a coin. + if rng.gen::() { + // This operation will fill the cache. + puzzle.get_proof_target(solution).unwrap(); + } + } + + // Compute the proof targets. + let proof_targets = puzzle.get_proof_targets(&solutions).unwrap(); + + // Ensure the proof targets are correct. + for ((_, solution), proof_target) in solutions.iter().zip(proof_targets) { + assert_eq!(puzzle.get_proof_target(solution).unwrap(), proof_target); + } + } + } + + /// Use `cargo test profiler --features timer` to run this test. + #[ignore] + #[test] + fn test_profiler() -> Result<()> { + fn sample_address_and_counter(rng: &mut (impl CryptoRng + RngCore)) -> (Address, u64) { + let private_key = PrivateKey::new(rng).unwrap(); + let address = Address::try_from(private_key).unwrap(); + let counter = rng.next_u64(); + (address, counter) + } + + let mut rng = rand::thread_rng(); + + // Initialize a new puzzle. + let puzzle = sample_puzzle(); + + // Initialize an epoch hash. + let epoch_hash = rng.gen(); + + for batch_size in [1, 2, ::MAX_SOLUTIONS] { + // Generate the solutions. + let solutions = (0..batch_size) + .map(|_| { + let (address, counter) = sample_address_and_counter(&mut rng); + puzzle.prove(epoch_hash, address, counter, None).unwrap() + }) + .collect::>(); + // Construct the solutions. + let solutions = PuzzleSolutions::new(solutions).unwrap(); + // Verify the solutions. + puzzle.check_solutions(&solutions, epoch_hash, 0u64).unwrap(); + } + + bail!("\n\nRemember to #[ignore] this test!\n\n") + } +} diff --git a/ledger/coinbase/src/helpers/partial_solution/bytes.rs b/ledger/puzzle/src/partial_solution/bytes.rs similarity index 74% rename from ledger/coinbase/src/helpers/partial_solution/bytes.rs rename to ledger/puzzle/src/partial_solution/bytes.rs index 7b919d93d5..b2eece6c5b 100644 --- a/ledger/coinbase/src/helpers/partial_solution/bytes.rs +++ b/ledger/puzzle/src/partial_solution/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -17,29 +18,29 @@ use super::*; impl FromBytes for PartialSolution { /// Reads the partial solution from the buffer. fn read_le(mut reader: R) -> IoResult { - let address: Address = FromBytes::read_le(&mut reader)?; - let nonce = u64::read_le(&mut reader)?; - let commitment = KZGCommitment::read_le(&mut reader)?; + let epoch_hash = N::BlockHash::read_le(&mut reader)?; + let address = Address::::read_le(&mut reader)?; + let counter = u64::read_le(&mut reader)?; - Ok(Self::new(address, nonce, commitment)) + Self::new(epoch_hash, address, counter).map_err(error) } } impl ToBytes for PartialSolution { /// Writes the partial solution to the buffer. fn write_le(&self, mut writer: W) -> IoResult<()> { + self.epoch_hash.write_le(&mut writer)?; self.address.write_le(&mut writer)?; - self.nonce.write_le(&mut writer)?; - self.commitment.write_le(&mut writer) + self.counter.write_le(&mut writer) } } #[cfg(test)] mod tests { use super::*; - use console::{account::PrivateKey, network::Testnet3}; + use console::{account::PrivateKey, network::MainnetV0}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { @@ -48,7 +49,7 @@ mod tests { let address = Address::try_from(private_key)?; // Sample a new partial solution. - let expected = PartialSolution::new(address, u64::rand(&mut rng), KZGCommitment(rng.gen())); + let expected = PartialSolution::new(rng.gen(), address, u64::rand(&mut rng)).unwrap(); // Check the byte representation. let expected_bytes = expected.to_bytes_le()?; diff --git a/ledger/puzzle/src/partial_solution/mod.rs b/ledger/puzzle/src/partial_solution/mod.rs new file mode 100644 index 0000000000..dbd77d8b53 --- /dev/null +++ b/ledger/puzzle/src/partial_solution/mod.rs @@ -0,0 +1,64 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +mod bytes; +mod serialize; +mod string; + +use crate::SolutionID; +use console::{account::Address, network::prelude::*, prelude::DeserializeExt}; + +/// The partial solution for the puzzle from a prover. +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +pub struct PartialSolution { + /// The solution ID. + solution_id: SolutionID, + /// The epoch hash. + epoch_hash: N::BlockHash, + /// The address of the prover. + address: Address, + /// The counter for the solution. + counter: u64, +} + +impl PartialSolution { + /// Initializes a new instance of the partial solution. + pub fn new(epoch_hash: N::BlockHash, address: Address, counter: u64) -> Result { + // Compute the solution ID. + let solution_id = SolutionID::new(epoch_hash, address, counter)?; + // Return the partial solution. + Ok(Self { solution_id, epoch_hash, address, counter }) + } + + /// Returns the solution ID. + pub const fn id(&self) -> SolutionID { + self.solution_id + } + + /// Returns the epoch hash of the solution. + pub const fn epoch_hash(&self) -> N::BlockHash { + self.epoch_hash + } + + /// Returns the address of the prover. + pub const fn address(&self) -> Address { + self.address + } + + /// Returns the counter for the solution. + pub const fn counter(&self) -> u64 { + self.counter + } +} diff --git a/ledger/coinbase/src/helpers/partial_solution/serialize.rs b/ledger/puzzle/src/partial_solution/serialize.rs similarity index 63% rename from ledger/coinbase/src/helpers/partial_solution/serialize.rs rename to ledger/puzzle/src/partial_solution/serialize.rs index 322b0b155a..e982e73d01 100644 --- a/ledger/coinbase/src/helpers/partial_solution/serialize.rs +++ b/ledger/puzzle/src/partial_solution/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,18 +15,17 @@ use super::*; -use snarkvm_utilities::DeserializeExt; - impl Serialize for PartialSolution { /// Serializes the partial solution to a JSON-string or buffer. fn serialize(&self, serializer: S) -> Result { match serializer.is_human_readable() { true => { - let mut partial_prover_solution = serializer.serialize_struct("PartialSolution", 3)?; - partial_prover_solution.serialize_field("address", &self.address)?; - partial_prover_solution.serialize_field("nonce", &self.nonce)?; - partial_prover_solution.serialize_field("commitment", &self.commitment)?; - partial_prover_solution.end() + let mut partial_solution = serializer.serialize_struct("PartialSolution", 4)?; + partial_solution.serialize_field("solution_id", &self.solution_id)?; + partial_solution.serialize_field("epoch_hash", &self.epoch_hash)?; + partial_solution.serialize_field("address", &self.address)?; + partial_solution.serialize_field("counter", &self.counter)?; + partial_solution.end() } false => ToBytesSerializer::serialize_with_size_encoding(self, serializer), } @@ -37,14 +37,25 @@ impl<'de, N: Network> Deserialize<'de> for PartialSolution { fn deserialize>(deserializer: D) -> Result { match deserializer.is_human_readable() { true => { - let mut partial_prover_solution = serde_json::Value::deserialize(deserializer)?; - Ok(Self::new( - DeserializeExt::take_from_value::(&mut partial_prover_solution, "address")?, - DeserializeExt::take_from_value::(&mut partial_prover_solution, "nonce")?, - >::take_from_value::(&mut partial_prover_solution, "commitment")?, - )) + let mut partial_solution = serde_json::Value::deserialize(deserializer)?; + let solution_id: SolutionID = + DeserializeExt::take_from_value::(&mut partial_solution, "solution_id")?; + + // Recover the partial solution. + let partial_solution = Self::new( + DeserializeExt::take_from_value::(&mut partial_solution, "epoch_hash")?, + DeserializeExt::take_from_value::(&mut partial_solution, "address")?, + DeserializeExt::take_from_value::(&mut partial_solution, "counter")?, + ) + .map_err(de::Error::custom)?; + + // Ensure the solution ID matches. + match solution_id == partial_solution.id() { + true => Ok(partial_solution), + false => Err(de::Error::custom(error("Mismatching solution ID, possible data corruption"))), + } } - false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "partial solution"), + false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "solution"), } } } @@ -52,9 +63,9 @@ impl<'de, N: Network> Deserialize<'de> for PartialSolution { #[cfg(test)] mod tests { use super::*; - use console::{account::PrivateKey, network::Testnet3}; + use console::{account::PrivateKey, network::MainnetV0}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_serde_json() -> Result<()> { @@ -63,7 +74,7 @@ mod tests { let address = Address::try_from(private_key)?; // Sample a new partial solution. - let expected = PartialSolution::new(address, u64::rand(&mut rng), KZGCommitment(rng.gen())); + let expected = PartialSolution::new(rng.gen(), address, u64::rand(&mut rng)).unwrap(); // Serialize let expected_string = &expected.to_string(); @@ -84,7 +95,7 @@ mod tests { let address = Address::try_from(private_key)?; // Sample a new partial solution. - let expected = PartialSolution::new(address, u64::rand(&mut rng), KZGCommitment(rng.gen())); + let expected = PartialSolution::new(rng.gen(), address, u64::rand(&mut rng)).unwrap(); // Serialize let expected_bytes = expected.to_bytes_le()?; diff --git a/ledger/coinbase/src/helpers/partial_solution/string.rs b/ledger/puzzle/src/partial_solution/string.rs similarity index 79% rename from ledger/coinbase/src/helpers/partial_solution/string.rs rename to ledger/puzzle/src/partial_solution/string.rs index 4b21975538..0486609ecf 100644 --- a/ledger/coinbase/src/helpers/partial_solution/string.rs +++ b/ledger/puzzle/src/partial_solution/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,8 +19,8 @@ impl FromStr for PartialSolution { type Err = Error; /// Initializes the partial solution from a JSON-string. - fn from_str(partial_prover_solution: &str) -> Result { - Ok(serde_json::from_str(partial_prover_solution)?) + fn from_str(solution: &str) -> Result { + Ok(serde_json::from_str(solution)?) } } @@ -40,9 +41,9 @@ impl Display for PartialSolution { #[cfg(test)] mod tests { use super::*; - use console::{account::PrivateKey, network::Testnet3}; + use console::{account::PrivateKey, network::MainnetV0}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_string() -> Result<()> { @@ -51,10 +52,10 @@ mod tests { let address = Address::try_from(private_key)?; // Sample a new partial solution. - let expected = PartialSolution::new(address, u64::rand(&mut rng), KZGCommitment(rng.gen())); + let expected = PartialSolution::new(rng.gen(), address, u64::rand(&mut rng)).unwrap(); // Check the string representation. - let candidate = format!("{expected}"); + let candidate = expected.to_string(); assert_eq!(expected, PartialSolution::from_str(&candidate)?); Ok(()) diff --git a/ledger/coinbase/src/helpers/prover_solution/bytes.rs b/ledger/puzzle/src/solution/bytes.rs similarity index 54% rename from ledger/coinbase/src/helpers/prover_solution/bytes.rs rename to ledger/puzzle/src/solution/bytes.rs index f5c5bdacf8..064a43cb53 100644 --- a/ledger/coinbase/src/helpers/prover_solution/bytes.rs +++ b/ledger/puzzle/src/solution/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,30 +15,30 @@ use super::*; -impl FromBytes for ProverSolution { - /// Reads the prover solution from the buffer. +impl FromBytes for Solution { + /// Reads the solution from the buffer. fn read_le(mut reader: R) -> IoResult { - let partial_solution: PartialSolution = FromBytes::read_le(&mut reader)?; - let proof = KZGProof::read_le(&mut reader)?; + let partial_solution = PartialSolution::read_le(&mut reader)?; + let target = u64::read_le(&mut reader)?; - Ok(Self::new(partial_solution, proof)) + Ok(Self::new(partial_solution, target)) } } -impl ToBytes for ProverSolution { - /// Writes the prover solution to the buffer. +impl ToBytes for Solution { + /// Writes the solution to the buffer. fn write_le(&self, mut writer: W) -> IoResult<()> { self.partial_solution.write_le(&mut writer)?; - self.proof.write_le(&mut writer) + self.target.write_le(&mut writer) } } #[cfg(test)] mod tests { use super::*; - use console::{account::PrivateKey, network::Testnet3}; + use console::{account::PrivateKey, network::MainnetV0}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { @@ -45,14 +46,15 @@ mod tests { let private_key = PrivateKey::::new(&mut rng)?; let address = Address::try_from(private_key)?; - // Sample a new prover solution. - let partial_solution = PartialSolution::new(address, u64::rand(&mut rng), KZGCommitment(rng.gen())); - let expected = ProverSolution::new(partial_solution, KZGProof { w: rng.gen(), random_v: None }); + // Sample a new solution. + let partial_solution = PartialSolution::new(rng.gen(), address, u64::rand(&mut rng)).unwrap(); + let target = u64::rand(&mut rng); + let expected = Solution::new(partial_solution, target); // Check the byte representation. let expected_bytes = expected.to_bytes_le()?; - assert_eq!(expected, ProverSolution::read_le(&expected_bytes[..])?); - assert!(ProverSolution::::read_le(&expected_bytes[1..]).is_err()); + assert_eq!(expected, Solution::read_le(&expected_bytes[..])?); + assert!(Solution::::read_le(&expected_bytes[1..]).is_err()); Ok(()) } diff --git a/ledger/puzzle/src/solution/mod.rs b/ledger/puzzle/src/solution/mod.rs new file mode 100644 index 0000000000..c3fd5e238c --- /dev/null +++ b/ledger/puzzle/src/solution/mod.rs @@ -0,0 +1,67 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +mod bytes; +mod serialize; +mod string; + +use crate::{PartialSolution, SolutionID}; +use console::{account::Address, network::prelude::*, prelude::DeserializeExt}; + +/// A helper struct around a puzzle solution. +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +pub struct Solution { + /// The partial solution. + partial_solution: PartialSolution, + /// The solution target. + pub(super) target: u64, +} + +impl Solution { + /// Initializes a new instance of the solution. + pub fn new(partial_solution: PartialSolution, target: u64) -> Self { + Self { partial_solution, target } + } + + /// Returns the partial solution.. + pub const fn partial_solution(&self) -> &PartialSolution { + &self.partial_solution + } + + /// Returns the solution ID. + pub const fn id(&self) -> SolutionID { + self.partial_solution.id() + } + + /// Returns the epoch hash of the solution. + pub const fn epoch_hash(&self) -> N::BlockHash { + self.partial_solution.epoch_hash() + } + + /// Returns the address of the prover. + pub const fn address(&self) -> Address { + self.partial_solution.address() + } + + /// Returns the counter for the solution. + pub const fn counter(&self) -> u64 { + self.partial_solution.counter() + } + + /// Returns the target for the solution. + pub const fn target(&self) -> u64 { + self.target + } +} diff --git a/ledger/coinbase/src/helpers/prover_solution/serialize.rs b/ledger/puzzle/src/solution/serialize.rs similarity index 51% rename from ledger/coinbase/src/helpers/prover_solution/serialize.rs rename to ledger/puzzle/src/solution/serialize.rs index 564cba8bed..33b6ec74f6 100644 --- a/ledger/coinbase/src/helpers/prover_solution/serialize.rs +++ b/ledger/puzzle/src/solution/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,45 +15,34 @@ use super::*; -use snarkvm_utilities::DeserializeExt; - -impl Serialize for ProverSolution { - /// Serializes the prover solution to a JSON-string or buffer. +impl Serialize for Solution { + /// Serializes the solution to a JSON-string or buffer. fn serialize(&self, serializer: S) -> Result { match serializer.is_human_readable() { true => { - let mut prover_solution = - serializer.serialize_struct("ProverSolution", 2 + self.proof.random_v.is_some() as usize)?; - prover_solution.serialize_field("partial_solution", &self.partial_solution)?; - prover_solution.serialize_field("proof.w", &self.proof.w)?; - if let Some(random_v) = &self.proof.random_v { - prover_solution.serialize_field("proof.random_v", &random_v)?; - } - prover_solution.end() + let mut solution = serializer.serialize_struct("Solution", 2)?; + solution.serialize_field("partial_solution", &self.partial_solution)?; + solution.serialize_field("target", &self.target)?; + solution.end() } false => ToBytesSerializer::serialize_with_size_encoding(self, serializer), } } } -impl<'de, N: Network> Deserialize<'de> for ProverSolution { - /// Deserializes the prover solution from a JSON-string or buffer. +impl<'de, N: Network> Deserialize<'de> for Solution { + /// Deserializes the solution from a JSON-string or buffer. fn deserialize>(deserializer: D) -> Result { match deserializer.is_human_readable() { true => { - let mut prover_solution = serde_json::Value::deserialize(deserializer)?; + let mut solution = serde_json::Value::deserialize(deserializer)?; + Ok(Self::new( - DeserializeExt::take_from_value::(&mut prover_solution, "partial_solution")?, - KZGProof { - w: DeserializeExt::take_from_value::(&mut prover_solution, "proof.w")?, - random_v: serde_json::from_value( - prover_solution.get_mut("proof.random_v").unwrap_or(&mut serde_json::Value::Null).take(), - ) - .map_err(de::Error::custom)?, - }, + DeserializeExt::take_from_value::(&mut solution, "partial_solution")?, + DeserializeExt::take_from_value::(&mut solution, "target")?, )) } - false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "prover solution"), + false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "solution"), } } } @@ -60,9 +50,9 @@ impl<'de, N: Network> Deserialize<'de> for ProverSolution { #[cfg(test)] mod tests { use super::*; - use console::{account::PrivateKey, network::Testnet3}; + use console::{account::PrivateKey, network::MainnetV0}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_serde_json() -> Result<()> { @@ -70,9 +60,10 @@ mod tests { let private_key = PrivateKey::::new(&mut rng)?; let address = Address::try_from(private_key)?; - // Sample a new prover puzzle solution. - let partial_solution = PartialSolution::new(address, u64::rand(&mut rng), KZGCommitment(rng.gen())); - let expected = ProverSolution::new(partial_solution, KZGProof { w: rng.gen(), random_v: None }); + // Sample a new solution. + let partial_solution = PartialSolution::new(rng.gen(), address, u64::rand(&mut rng)).unwrap(); + let target = u64::rand(&mut rng); + let expected = Solution::new(partial_solution, target); // Serialize let expected_string = &expected.to_string(); @@ -80,7 +71,7 @@ mod tests { assert_eq!(expected, serde_json::from_str(&candidate_string)?); // Deserialize - assert_eq!(expected, ProverSolution::from_str(expected_string)?); + assert_eq!(expected, Solution::from_str(expected_string)?); assert_eq!(expected, serde_json::from_str(&candidate_string)?); Ok(()) @@ -92,9 +83,10 @@ mod tests { let private_key = PrivateKey::::new(&mut rng)?; let address = Address::try_from(private_key)?; - // Sample a new prover puzzle solution. - let partial_solution = PartialSolution::new(address, u64::rand(&mut rng), KZGCommitment(rng.gen())); - let expected = ProverSolution::new(partial_solution, KZGProof { w: rng.gen(), random_v: None }); + // Sample a new solution. + let partial_solution = PartialSolution::new(rng.gen(), address, u64::rand(&mut rng)).unwrap(); + let target = u64::rand(&mut rng); + let expected = Solution::new(partial_solution, target); // Serialize let expected_bytes = expected.to_bytes_le()?; @@ -102,7 +94,7 @@ mod tests { assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]); // Deserialize - assert_eq!(expected, ProverSolution::read_le(&expected_bytes[..])?); + assert_eq!(expected, Solution::read_le(&expected_bytes[..])?); assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..])?); Ok(()) diff --git a/ledger/coinbase/src/helpers/prover_solution/string.rs b/ledger/puzzle/src/solution/string.rs similarity index 58% rename from ledger/coinbase/src/helpers/prover_solution/string.rs rename to ledger/puzzle/src/solution/string.rs index 66f6a79275..15fcff05c6 100644 --- a/ledger/coinbase/src/helpers/prover_solution/string.rs +++ b/ledger/puzzle/src/solution/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,24 +15,24 @@ use super::*; -impl FromStr for ProverSolution { +impl FromStr for Solution { type Err = Error; - /// Initializes the prover solution from a JSON-string. - fn from_str(partial_prover_solution: &str) -> Result { - Ok(serde_json::from_str(partial_prover_solution)?) + /// Initializes the solution from a JSON-string. + fn from_str(solution: &str) -> Result { + Ok(serde_json::from_str(solution)?) } } -impl Debug for ProverSolution { - /// Prints the prover solution as a JSON-string. +impl Debug for Solution { + /// Prints the solution as a JSON-string. fn fmt(&self, f: &mut Formatter) -> fmt::Result { Display::fmt(self, f) } } -impl Display for ProverSolution { - /// Displays the prover solution as a JSON-string. +impl Display for Solution { + /// Displays the solution as a JSON-string. fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{}", serde_json::to_string(self).map_err::(ser::Error::custom)?) } @@ -40,9 +41,9 @@ impl Display for ProverSolution { #[cfg(test)] mod tests { use super::*; - use console::{account::PrivateKey, network::Testnet3}; + use console::{account::PrivateKey, network::MainnetV0}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_string() -> Result<()> { @@ -50,13 +51,14 @@ mod tests { let private_key = PrivateKey::::new(&mut rng)?; let address = Address::try_from(private_key)?; - // Sample a new prover puzzle solution. - let partial_solution = PartialSolution::new(address, u64::rand(&mut rng), KZGCommitment(rng.gen())); - let expected = ProverSolution::new(partial_solution, KZGProof { w: rng.gen(), random_v: None }); + // Sample a new solution. + let partial_solution = PartialSolution::new(rng.gen(), address, u64::rand(&mut rng)).unwrap(); + let target = u64::rand(&mut rng); + let expected = Solution::new(partial_solution, target); // Check the string representation. let candidate = expected.to_string(); - assert_eq!(expected, ProverSolution::from_str(&candidate)?); + assert_eq!(expected, Solution::from_str(&candidate)?); Ok(()) } diff --git a/ledger/coinbase/src/helpers/puzzle_commitment/bytes.rs b/ledger/puzzle/src/solution_id/bytes.rs similarity index 55% rename from ledger/coinbase/src/helpers/puzzle_commitment/bytes.rs rename to ledger/puzzle/src/solution_id/bytes.rs index 1f83beb97d..06badeebac 100644 --- a/ledger/coinbase/src/helpers/puzzle_commitment/bytes.rs +++ b/ledger/puzzle/src/solution_id/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,40 +15,40 @@ use super::*; -impl FromBytes for PuzzleCommitment { - /// Reads the puzzle commitment from the buffer. +impl FromBytes for SolutionID { + /// Reads the solution ID from the buffer. fn read_le(mut reader: R) -> IoResult { - let commitment = KZGCommitment::read_le(&mut reader)?; + let nonce = u64::read_le(&mut reader)?; - Ok(Self::new(commitment)) + Ok(Self::from(nonce)) } } -impl ToBytes for PuzzleCommitment { - /// Writes the puzzle commitment to the buffer. +impl ToBytes for SolutionID { + /// Writes the solution ID to the buffer. fn write_le(&self, mut writer: W) -> IoResult<()> { - self.commitment.write_le(&mut writer) + self.0.write_le(&mut writer) } } #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { let mut rng = TestRng::default(); - // Sample a new puzzle commitment. - let expected = PuzzleCommitment::::new(KZGCommitment(rng.gen())); + // Sample a new solution ID. + let expected = SolutionID::::from(rng.gen::()); // Check the byte representation. let expected_bytes = expected.to_bytes_le()?; - assert_eq!(expected_bytes.len(), 48); - assert_eq!(expected, PuzzleCommitment::read_le(&expected_bytes[..])?); - assert!(PuzzleCommitment::::read_le(&expected_bytes[1..]).is_err()); + assert_eq!(expected_bytes.len(), 8); + assert_eq!(expected, SolutionID::read_le(&expected_bytes[..])?); + assert!(SolutionID::::read_le(&expected_bytes[1..]).is_err()); Ok(()) } diff --git a/ledger/puzzle/src/solution_id/mod.rs b/ledger/puzzle/src/solution_id/mod.rs new file mode 100644 index 0000000000..f5d50fc55e --- /dev/null +++ b/ledger/puzzle/src/solution_id/mod.rs @@ -0,0 +1,57 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +mod bytes; +mod serialize; +mod string; + +pub use string::SOLUTION_ID_PREFIX; + +use console::{account::Address, network::prelude::*}; +use snarkvm_algorithms::crypto_hash::sha256d_to_u64; + +use core::marker::PhantomData; + +/// The solution ID. +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +pub struct SolutionID(u64, PhantomData); + +impl From for SolutionID { + /// Initializes a new instance of the solution ID. + fn from(nonce: u64) -> Self { + Self(nonce, PhantomData) + } +} + +impl SolutionID { + /// Initializes the solution ID from the given epoch hash, address, and counter. + pub fn new(epoch_hash: N::BlockHash, address: Address, counter: u64) -> Result { + // Construct the nonce as sha256d(epoch_hash_bytes_le[0..8] || address || counter). + let mut bytes_le = Vec::new(); + let lower_bytes = &epoch_hash.to_bytes_le()?[0..8]; + bytes_le.extend_from_slice(lower_bytes); + bytes_le.extend_from_slice(&address.to_bytes_le()?); + bytes_le.extend_from_slice(&counter.to_bytes_le()?); + Ok(Self::from(sha256d_to_u64(&bytes_le))) + } +} + +impl Deref for SolutionID { + type Target = u64; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/ledger/coinbase/src/helpers/puzzle_commitment/serialize.rs b/ledger/puzzle/src/solution_id/serialize.rs similarity index 71% rename from ledger/coinbase/src/helpers/puzzle_commitment/serialize.rs rename to ledger/puzzle/src/solution_id/serialize.rs index 3f753fc143..204a0a7a90 100644 --- a/ledger/coinbase/src/helpers/puzzle_commitment/serialize.rs +++ b/ledger/puzzle/src/solution_id/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,8 +15,8 @@ use super::*; -impl Serialize for PuzzleCommitment { - /// Serializes the puzzle commitment to a string or buffer. +impl Serialize for SolutionID { + /// Serializes the solution ID to a string or buffer. fn serialize(&self, serializer: S) -> Result { match serializer.is_human_readable() { true => serializer.collect_str(self), @@ -24,12 +25,12 @@ impl Serialize for PuzzleCommitment { } } -impl<'de, N: Network> Deserialize<'de> for PuzzleCommitment { - /// Deserializes the puzzle commitment from a string or buffer. +impl<'de, N: Network> Deserialize<'de> for SolutionID { + /// Deserializes the solution ID from a string or buffer. fn deserialize>(deserializer: D) -> Result { match deserializer.is_human_readable() { true => FromStr::from_str(&String::deserialize(deserializer)?).map_err(de::Error::custom), - false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "puzzle commitment"), + false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "solution ID"), } } } @@ -37,16 +38,16 @@ impl<'de, N: Network> Deserialize<'de> for PuzzleCommitment { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_serde_json() -> Result<()> { let mut rng = TestRng::default(); - // Sample a new puzzle commitment. - let expected = PuzzleCommitment::::new(KZGCommitment(rng.gen())); + // Sample a new solution ID. + let expected = SolutionID::::from(rng.gen::()); // Serialize let expected_string = &expected.to_string(); @@ -54,7 +55,7 @@ mod tests { assert_eq!(expected, serde_json::from_str(&candidate_string)?); // Deserialize - assert_eq!(expected, PuzzleCommitment::from_str(expected_string)?); + assert_eq!(expected, SolutionID::from_str(expected_string)?); assert_eq!(expected, serde_json::from_str(&candidate_string)?); Ok(()) @@ -64,8 +65,8 @@ mod tests { fn test_bincode() -> Result<()> { let mut rng = TestRng::default(); - // Sample a new puzzle commitment. - let expected = PuzzleCommitment::::new(KZGCommitment(rng.gen())); + // Sample a new solution ID. + let expected = SolutionID::::from(rng.gen::()); // Serialize let expected_bytes = expected.to_bytes_le()?; @@ -73,7 +74,7 @@ mod tests { assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]); // Deserialize - assert_eq!(expected, PuzzleCommitment::read_le(&expected_bytes[..])?); + assert_eq!(expected, SolutionID::read_le(&expected_bytes[..])?); assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..])?); Ok(()) diff --git a/ledger/puzzle/src/solution_id/string.rs b/ledger/puzzle/src/solution_id/string.rs new file mode 100644 index 0000000000..42d04f5961 --- /dev/null +++ b/ledger/puzzle/src/solution_id/string.rs @@ -0,0 +1,104 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +pub static SOLUTION_ID_PREFIX: &str = "solution"; + +impl FromStr for SolutionID { + type Err = Error; + + /// Reads in the solution ID string. + fn from_str(solution_id: &str) -> Result { + // Decode the solution ID string from bech32m. + let (hrp, data, variant) = bech32::decode(solution_id)?; + if hrp != SOLUTION_ID_PREFIX { + bail!("Failed to decode solution ID: '{hrp}' is an invalid prefix") + } else if data.is_empty() { + bail!("Failed to decode solution ID: data field is empty") + } else if variant != bech32::Variant::Bech32m { + bail!("Found a solution ID that is not bech32m encoded: {solution_id}"); + } + // Decode the solution ID data from u5 to u8, and into the solution ID. + Ok(Self::read_le(&Vec::from_base32(&data)?[..])?) + } +} + +impl Debug for SolutionID { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(self, f) + } +} + +impl Display for SolutionID { + /// Writes the solution ID as a bech32m string. + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + // Convert the solution ID to bytes. + let bytes = self.to_bytes_le().map_err(|_| fmt::Error)?; + // Encode the bytes into bech32m. + let string = + bech32::encode(SOLUTION_ID_PREFIX, bytes.to_base32(), bech32::Variant::Bech32m).map_err(|_| fmt::Error)?; + // Output the string. + Display::fmt(&string, f) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use console::network::MainnetV0; + + type CurrentNetwork = MainnetV0; + + const ITERATIONS: u64 = 1_000; + + #[test] + fn test_string() -> Result<()> { + // Ensure type and empty value fails. + assert!(SolutionID::::from_str(&format!("{SOLUTION_ID_PREFIX}1")).is_err()); + assert!(SolutionID::::from_str("").is_err()); + + let mut rng = TestRng::default(); + + for _ in 0..ITERATIONS { + // Sample a new solution ID. + let expected = SolutionID::::from(rng.gen::()); + + // Check the string representation. + let candidate = format!("{expected}"); + assert_eq!(expected, SolutionID::from_str(&candidate)?); + assert_eq!(SOLUTION_ID_PREFIX, candidate.split('1').next().unwrap()); + } + Ok(()) + } + + #[test] + fn test_display() -> Result<()> { + let mut rng = TestRng::default(); + + for _ in 0..ITERATIONS { + // Sample a new solution ID. + let expected = SolutionID::::from(rng.gen::()); + + let candidate = expected.to_string(); + assert_eq!(format!("{expected}"), candidate); + assert_eq!(SOLUTION_ID_PREFIX, candidate.split('1').next().unwrap()); + + let candidate_recovered = SolutionID::::from_str(&candidate.to_string())?; + assert_eq!(expected, candidate_recovered); + } + Ok(()) + } +} diff --git a/ledger/coinbase/src/helpers/coinbase_solution/bytes.rs b/ledger/puzzle/src/solutions/bytes.rs similarity index 67% rename from ledger/coinbase/src/helpers/coinbase_solution/bytes.rs rename to ledger/puzzle/src/solutions/bytes.rs index 66d541a3fb..78339477f6 100644 --- a/ledger/coinbase/src/helpers/coinbase_solution/bytes.rs +++ b/ledger/puzzle/src/solutions/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,26 +15,26 @@ use super::*; -impl FromBytes for CoinbaseSolution { +impl FromBytes for PuzzleSolutions { /// Reads the solutions from the buffer. fn read_le(mut reader: R) -> IoResult { // Read the number of solutions. - let num_solutions: u16 = FromBytes::read_le(&mut reader)?; + let num_solutions: u8 = FromBytes::read_le(&mut reader)?; // Read the solutions. - let mut prover_solutions = Vec::with_capacity(num_solutions as usize); + let mut solutions = Vec::with_capacity(num_solutions as usize); for _ in 0..num_solutions { - prover_solutions.push(ProverSolution::read_le(&mut reader)?); + solutions.push(Solution::read_le(&mut reader)?); } // Return the solutions. - Self::new(prover_solutions).map_err(error) + Self::new(solutions).map_err(error) } } -impl ToBytes for CoinbaseSolution { +impl ToBytes for PuzzleSolutions { /// Writes the solutions to the buffer. fn write_le(&self, mut writer: W) -> IoResult<()> { // Write the number of solutions. - (u16::try_from(self.solutions.len()).map_err(|e| error(e.to_string()))?).write_le(&mut writer)?; + (u8::try_from(self.solutions.len()).map_err(error)?).write_le(&mut writer)?; // Write the solutions. for solution in self.solutions.values() { solution.write_le(&mut writer)?; @@ -51,11 +52,11 @@ mod tests { let mut rng = TestRng::default(); // Sample random solutions. - let expected = crate::helpers::coinbase_solution::serialize::tests::sample_solutions(&mut rng); + let expected = crate::solutions::serialize::tests::sample_solutions(&mut rng); // Check the byte representation. let expected_bytes = expected.to_bytes_le()?; - assert_eq!(expected, CoinbaseSolution::read_le(&expected_bytes[..])?); + assert_eq!(expected, PuzzleSolutions::read_le(&expected_bytes[..])?); Ok(()) } } diff --git a/ledger/puzzle/src/solutions/mod.rs b/ledger/puzzle/src/solutions/mod.rs new file mode 100644 index 0000000000..2a305a3f6a --- /dev/null +++ b/ledger/puzzle/src/solutions/mod.rs @@ -0,0 +1,189 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +mod bytes; +mod serialize; +mod string; + +use crate::{Solution, SolutionID}; +use console::{network::prelude::*, prelude::DeserializeExt, types::Field}; +use indexmap::IndexMap; + +/// The individual solutions. +#[derive(Clone, Eq, PartialEq)] +pub struct PuzzleSolutions { + /// The solutions for the puzzle. + solutions: IndexMap, Solution>, +} + +impl PuzzleSolutions { + /// Initializes a new instance of the solutions. + pub fn new(solutions: Vec>) -> Result { + // Ensure the solutions are not empty. + ensure!(!solutions.is_empty(), "There are no solutions to verify for the puzzle"); + // Ensure the number of solutions does not exceed `MAX_SOLUTIONS`. + if solutions.len() > N::MAX_SOLUTIONS { + bail!("Exceeded the maximum number of solutions ({} > {})", solutions.len(), N::MAX_SOLUTIONS); + } + // Ensure the solution IDs are unique. + if has_duplicates(solutions.iter().map(Solution::id)) { + bail!("The solutions contain duplicate solution IDs"); + } + // Return the solutions. + Ok(Self { solutions: solutions.into_iter().map(|solution| (solution.id(), solution)).collect() }) + } + + /// Returns the solution IDs. + pub fn solution_ids(&self) -> impl '_ + Iterator> { + self.solutions.keys() + } + + /// Returns the number of solutions. + pub fn len(&self) -> usize { + self.solutions.len() + } + + /// Returns `true` if there are no solutions. + pub fn is_empty(&self) -> bool { + self.solutions.is_empty() + } + + /// Returns the solution for the given solution ID. + pub fn get_solution(&self, solution_id: &SolutionID) -> Option<&Solution> { + self.solutions.get(solution_id) + } + + /// Returns the accumulator challenge point. + pub fn to_accumulator_point(&self) -> Result> { + // Encode the solution IDs as field elements. + let mut preimage = self.solution_ids().map(|id| Field::from_u64(**id)).collect::>(); + // Pad the preimage to the required length. + preimage.resize(N::MAX_SOLUTIONS, Field::zero()); + // Hash the preimage to obtain the accumulator point. + N::hash_psd8(&preimage) + } +} + +impl Deref for PuzzleSolutions { + type Target = IndexMap, Solution>; + + fn deref(&self) -> &Self::Target { + &self.solutions + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::PartialSolution; + use console::account::{Address, PrivateKey}; + + use std::collections::HashSet; + + type CurrentNetwork = console::network::MainnetV0; + + /// Returns the solutions for the given number of solutions. + pub(crate) fn sample_solutions_with_count( + num_solutions: usize, + rng: &mut TestRng, + ) -> PuzzleSolutions { + // Sample a new solutions. + let mut solutions = vec![]; + for _ in 0..num_solutions { + let private_key = PrivateKey::::new(rng).unwrap(); + let address = Address::try_from(private_key).unwrap(); + + let partial_solution = PartialSolution::new(rng.gen(), address, u64::rand(rng)).unwrap(); + let solution = Solution::new(partial_solution, u64::rand(rng)); + solutions.push(solution); + } + PuzzleSolutions::new(solutions).unwrap() + } + + #[test] + fn test_new_is_not_empty() { + // Ensure the solutions are not empty. + assert!(PuzzleSolutions::::new(vec![]).is_err()); + } + + #[test] + fn test_len() { + let mut rng = TestRng::default(); + + for num_solutions in 1..::MAX_SOLUTIONS { + // Sample random solutions. + let solutions = sample_solutions_with_count(num_solutions, &mut rng); + // Ensure the number of solutions is correct. + assert_eq!(num_solutions, solutions.len()); + } + } + + #[test] + fn test_is_empty() { + let mut rng = TestRng::default(); + + for num_solutions in 1..::MAX_SOLUTIONS { + // Sample random solutions. + let solutions = sample_solutions_with_count(num_solutions, &mut rng); + // Ensure the solutions are not empty. + assert!(!solutions.is_empty()); + } + } + + #[test] + fn test_solution_ids() { + let mut rng = TestRng::default(); + + for num_solutions in 1..::MAX_SOLUTIONS { + // Sample random solutions. + let solutions = sample_solutions_with_count(num_solutions, &mut rng); + // Ensure the solution IDs are unique. + assert_eq!(num_solutions, solutions.solution_ids().collect::>().len()); + } + } + + #[test] + fn test_get_solution() { + let mut rng = TestRng::default(); + + for num_solutions in 1..::MAX_SOLUTIONS { + // Sample random solutions. + let solutions = sample_solutions_with_count(num_solutions, &mut rng); + // Ensure the solutions are not empty. + for solution_id in solutions.solution_ids() { + assert_eq!(solutions.get_solution(solution_id).unwrap().id(), *solution_id); + } + } + } + + #[test] + fn test_to_accumulator_point() { + let mut rng = TestRng::default(); + + for num_solutions in 1..::MAX_SOLUTIONS { + // Sample random solutions. + let solutions = crate::solutions::tests::sample_solutions_with_count(num_solutions, &mut rng); + // Compute the candidate accumulator point. + let candidate = solutions.to_accumulator_point().unwrap(); + // Compute the expected accumulator point. + let mut preimage = vec![Field::zero(); ::MAX_SOLUTIONS]; + for (i, id) in solutions.keys().enumerate() { + preimage[i] = Field::from_u64(**id); + } + let expected = ::hash_psd8(&preimage).unwrap(); + assert_eq!(expected, candidate); + } + } +} diff --git a/ledger/coinbase/src/helpers/coinbase_solution/serialize.rs b/ledger/puzzle/src/solutions/serialize.rs similarity index 76% rename from ledger/coinbase/src/helpers/coinbase_solution/serialize.rs rename to ledger/puzzle/src/solutions/serialize.rs index ac973aee78..4127fab479 100644 --- a/ledger/coinbase/src/helpers/coinbase_solution/serialize.rs +++ b/ledger/puzzle/src/solutions/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,14 +15,12 @@ use super::*; -use snarkvm_utilities::DeserializeExt; - -impl Serialize for CoinbaseSolution { +impl Serialize for PuzzleSolutions { /// Serializes the solutions to a JSON-string or buffer. fn serialize(&self, serializer: S) -> Result { match serializer.is_human_readable() { true => { - let mut solutions = serializer.serialize_struct("CoinbaseSolution", 1)?; + let mut solutions = serializer.serialize_struct("PuzzleSolutions", 1)?; solutions.serialize_field("solutions", &self.solutions.values().collect::>())?; solutions.end() } @@ -30,7 +29,7 @@ impl Serialize for CoinbaseSolution { } } -impl<'de, N: Network> Deserialize<'de> for CoinbaseSolution { +impl<'de, N: Network> Deserialize<'de> for PuzzleSolutions { /// Deserializes the solutions from a JSON-string or buffer. fn deserialize>(deserializer: D) -> Result { match deserializer.is_human_readable() { @@ -46,21 +45,23 @@ impl<'de, N: Network> Deserialize<'de> for CoinbaseSolution { #[cfg(test)] pub(super) mod tests { use super::*; - use console::account::PrivateKey; + use crate::PartialSolution; + use console::account::{Address, PrivateKey}; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; - pub(crate) fn sample_solutions(rng: &mut TestRng) -> CoinbaseSolution { + pub(crate) fn sample_solutions(rng: &mut TestRng) -> PuzzleSolutions { // Sample a new solutions. - let mut prover_solutions = vec![]; - for _ in 0..rng.gen_range(1..10) { + let mut solutions = vec![]; + for _ in 0..rng.gen_range(1..CurrentNetwork::MAX_SOLUTIONS) { let private_key = PrivateKey::::new(rng).unwrap(); let address = Address::try_from(private_key).unwrap(); - let partial_solution = PartialSolution::new(address, u64::rand(rng), KZGCommitment(rng.gen())); - prover_solutions.push(ProverSolution::new(partial_solution, KZGProof { w: rng.gen(), random_v: None })); + let partial_solution = PartialSolution::new(rng.gen(), address, u64::rand(rng)).unwrap(); + let solution = Solution::new(partial_solution, u64::rand(rng)); + solutions.push(solution); } - CoinbaseSolution::new(prover_solutions).unwrap() + PuzzleSolutions::new(solutions).unwrap() } #[test] @@ -76,7 +77,7 @@ pub(super) mod tests { assert_eq!(expected, serde_json::from_str(&candidate_string)?); // Deserialize - assert_eq!(expected, CoinbaseSolution::from_str(expected_string)?); + assert_eq!(expected, PuzzleSolutions::from_str(expected_string)?); assert_eq!(expected, serde_json::from_str(&candidate_string)?); Ok(()) @@ -95,7 +96,7 @@ pub(super) mod tests { assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]); // Deserialize - assert_eq!(expected, CoinbaseSolution::read_le(&expected_bytes[..])?); + assert_eq!(expected, PuzzleSolutions::read_le(&expected_bytes[..])?); assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..])?); Ok(()) diff --git a/ledger/puzzle/src/solutions/string.rs b/ledger/puzzle/src/solutions/string.rs new file mode 100644 index 0000000000..b8bee3ca28 --- /dev/null +++ b/ledger/puzzle/src/solutions/string.rs @@ -0,0 +1,58 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl FromStr for PuzzleSolutions { + type Err = Error; + + /// Initializes the solutions from a JSON-string. + fn from_str(solutions: &str) -> Result { + Ok(serde_json::from_str(solutions)?) + } +} + +impl Debug for PuzzleSolutions { + /// Prints the solutions as a JSON-string. + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(self, f) + } +} + +impl Display for PuzzleSolutions { + /// Displays the solutions as a JSON-string. + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{}", serde_json::to_string(self).map_err::(ser::Error::custom)?) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_string() -> Result<()> { + let mut rng = TestRng::default(); + + // Sample random solutions. + let expected = crate::solutions::serialize::tests::sample_solutions(&mut rng); + + // Check the string representation. + let candidate = format!("{expected}"); + assert_eq!(expected, PuzzleSolutions::from_str(&candidate)?); + + Ok(()) + } +} diff --git a/ledger/query/Cargo.toml b/ledger/query/Cargo.toml index 979555c7e4..d4ff55f37a 100644 --- a/ledger/query/Cargo.toml +++ b/ledger/query/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-query" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A query for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -34,18 +34,18 @@ query = [ "ledger-store", "synthesizer-program", "ureq" ] [dependencies.console] package = "snarkvm-console" path = "../../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-store] package = "snarkvm-ledger-store" path = "../store" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.synthesizer-program] package = "snarkvm-synthesizer-program" path = "../../synthesizer/program" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.async-trait] diff --git a/ledger/query/src/lib.rs b/ledger/query/src/lib.rs index 652275a377..f9776ce657 100644 --- a/ledger/query/src/lib.rs +++ b/ledger/query/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/query/src/query.rs b/ledger/query/src/query.rs index e4fbfd29e3..50e81fef17 100644 --- a/ledger/query/src/query.rs +++ b/ledger/query/src/query.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -66,7 +67,15 @@ impl> QueryTrait for Query { match self { Self::VM(block_store) => Ok(block_store.current_state_root()), Self::REST(url) => match N::ID { - 3 => Ok(Self::get_request(&format!("{url}/testnet3/latest/stateRoot"))?.into_json()?), + console::network::MainnetV0::ID => { + Ok(Self::get_request(&format!("{url}/mainnet/stateRoot/latest"))?.into_json()?) + } + console::network::TestnetV0::ID => { + Ok(Self::get_request(&format!("{url}/testnet/stateRoot/latest"))?.into_json()?) + } + console::network::CanaryV0::ID => { + Ok(Self::get_request(&format!("{url}/canary/stateRoot/latest"))?.into_json()?) + } _ => bail!("Unsupported network ID in inclusion query"), }, } @@ -78,7 +87,15 @@ impl> QueryTrait for Query { match self { Self::VM(block_store) => Ok(block_store.current_state_root()), Self::REST(url) => match N::ID { - 3 => Ok(Self::get_request_async(&format!("{url}/testnet3/latest/stateRoot")).await?.json().await?), + console::network::MainnetV0::ID => { + Ok(Self::get_request_async(&format!("{url}/mainnet/stateRoot/latest")).await?.json().await?) + } + console::network::TestnetV0::ID => { + Ok(Self::get_request_async(&format!("{url}/testnet/stateRoot/latest")).await?.json().await?) + } + console::network::CanaryV0::ID => { + Ok(Self::get_request_async(&format!("{url}/canary/stateRoot/latest")).await?.json().await?) + } _ => bail!("Unsupported network ID in inclusion query"), }, } @@ -89,7 +106,15 @@ impl> QueryTrait for Query { match self { Self::VM(block_store) => block_store.get_state_path_for_commitment(commitment), Self::REST(url) => match N::ID { - 3 => Ok(Self::get_request(&format!("{url}/testnet3/statePath/{commitment}"))?.into_json()?), + console::network::MainnetV0::ID => { + Ok(Self::get_request(&format!("{url}/mainnet/statePath/{commitment}"))?.into_json()?) + } + console::network::TestnetV0::ID => { + Ok(Self::get_request(&format!("{url}/testnet/statePath/{commitment}"))?.into_json()?) + } + console::network::CanaryV0::ID => { + Ok(Self::get_request(&format!("{url}/canary/statePath/{commitment}"))?.into_json()?) + } _ => bail!("Unsupported network ID in inclusion query"), }, } @@ -101,8 +126,53 @@ impl> QueryTrait for Query { match self { Self::VM(block_store) => block_store.get_state_path_for_commitment(commitment), Self::REST(url) => match N::ID { - 3 => { - Ok(Self::get_request_async(&format!("{url}/testnet3/statePath/{commitment}")).await?.json().await?) + console::network::MainnetV0::ID => { + Ok(Self::get_request_async(&format!("{url}/mainnet/statePath/{commitment}")).await?.json().await?) + } + console::network::TestnetV0::ID => { + Ok(Self::get_request_async(&format!("{url}/testnet/statePath/{commitment}")).await?.json().await?) + } + console::network::CanaryV0::ID => { + Ok(Self::get_request_async(&format!("{url}/canary/statePath/{commitment}")).await?.json().await?) + } + _ => bail!("Unsupported network ID in inclusion query"), + }, + } + } + + /// Returns a state path for the given `commitment`. + fn current_block_height(&self) -> Result { + match self { + Self::VM(block_store) => Ok(block_store.max_height().unwrap_or_default()), + Self::REST(url) => match N::ID { + console::network::MainnetV0::ID => { + Ok(Self::get_request(&format!("{url}/mainnet/block/height/latest"))?.into_json()?) + } + console::network::TestnetV0::ID => { + Ok(Self::get_request(&format!("{url}/testnet/block/height/latest"))?.into_json()?) + } + console::network::CanaryV0::ID => { + Ok(Self::get_request(&format!("{url}/canary/block/height/latest"))?.into_json()?) + } + _ => bail!("Unsupported network ID in inclusion query"), + }, + } + } + + /// Returns a state path for the given `commitment`. + #[cfg(feature = "async")] + async fn current_block_height_async(&self) -> Result { + match self { + Self::VM(block_store) => Ok(block_store.max_height().unwrap_or_default()), + Self::REST(url) => match N::ID { + console::network::MainnetV0::ID => { + Ok(Self::get_request_async(&format!("{url}/mainnet/block/height/latest")).await?.json().await?) + } + console::network::TestnetV0::ID => { + Ok(Self::get_request_async(&format!("{url}/testnet/block/height/latest")).await?.json().await?) + } + console::network::CanaryV0::ID => { + Ok(Self::get_request_async(&format!("{url}/canary/block/height/latest")).await?.json().await?) } _ => bail!("Unsupported network ID in inclusion query"), }, @@ -118,7 +188,15 @@ impl> Query { block_store.get_program(program_id)?.ok_or_else(|| anyhow!("Program {program_id} not found in storage")) } Self::REST(url) => match N::ID { - 3 => Ok(Self::get_request(&format!("{url}/testnet3/program/{program_id}"))?.into_json()?), + console::network::MainnetV0::ID => { + Ok(Self::get_request(&format!("{url}/mainnet/program/{program_id}"))?.into_json()?) + } + console::network::TestnetV0::ID => { + Ok(Self::get_request(&format!("{url}/testnet/program/{program_id}"))?.into_json()?) + } + console::network::CanaryV0::ID => { + Ok(Self::get_request(&format!("{url}/canary/program/{program_id}"))?.into_json()?) + } _ => bail!("Unsupported network ID in inclusion query"), }, } @@ -132,7 +210,15 @@ impl> Query { block_store.get_program(program_id)?.ok_or_else(|| anyhow!("Program {program_id} not found in storage")) } Self::REST(url) => match N::ID { - 3 => Ok(Self::get_request_async(&format!("{url}/testnet3/program/{program_id}")).await?.json().await?), + console::network::MainnetV0::ID => { + Ok(Self::get_request_async(&format!("{url}/mainnet/program/{program_id}")).await?.json().await?) + } + console::network::TestnetV0::ID => { + Ok(Self::get_request_async(&format!("{url}/testnet/program/{program_id}")).await?.json().await?) + } + console::network::CanaryV0::ID => { + Ok(Self::get_request_async(&format!("{url}/canary/program/{program_id}")).await?.json().await?) + } _ => bail!("Unsupported network ID in inclusion query"), }, } diff --git a/ledger/query/src/traits.rs b/ledger/query/src/traits.rs index cdef8937b7..4a5573ad23 100644 --- a/ledger/query/src/traits.rs +++ b/ledger/query/src/traits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -29,4 +30,11 @@ pub trait QueryTrait { /// Returns a state path for the given `commitment`. #[cfg(feature = "async")] async fn get_state_path_for_commitment_async(&self, commitment: &Field) -> Result>; + + /// Returns the current block height + fn current_block_height(&self) -> Result; + + /// Returns the current block height + #[cfg(feature = "async")] + async fn current_block_height_async(&self) -> Result; } diff --git a/ledger/src/advance.rs b/ledger/src/advance.rs index 30d7576b70..0a51fb567f 100644 --- a/ledger/src/advance.rs +++ b/ledger/src/advance.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,10 +17,11 @@ use super::*; impl> Ledger { /// Returns a candidate for the next block in the ledger, using a committed subdag and its transmissions. - pub fn prepare_advance_to_next_quorum_block( + pub fn prepare_advance_to_next_quorum_block( &self, subdag: Subdag, transmissions: IndexMap, Transmission>, + rng: &mut R, ) -> Result> { // Retrieve the latest block as the previous block (for the next block). let previous_block = self.latest_block(); @@ -29,8 +31,8 @@ impl> Ledger { // Currently, we do not support ratifications from the memory pool. ensure!(ratifications.is_empty(), "Ratifications are currently unsupported from the memory pool"); // Construct the block template. - let (header, ratifications, solutions, transactions, aborted_transaction_ids) = - self.construct_block_template(&previous_block, Some(&subdag), ratifications, solutions, transactions)?; + let (header, ratifications, solutions, aborted_solution_ids, transactions, aborted_transaction_ids) = + self.construct_block_template(&previous_block, Some(&subdag), ratifications, solutions, transactions, rng)?; // Construct the new quorum block. Block::new_quorum( @@ -39,6 +41,7 @@ impl> Ledger { subdag, ratifications, solutions, + aborted_solution_ids, transactions, aborted_transaction_ids, ) @@ -49,7 +52,7 @@ impl> Ledger { &self, private_key: &PrivateKey, candidate_ratifications: Vec>, - candidate_solutions: Vec>, + candidate_solutions: Vec>, candidate_transactions: Vec>, rng: &mut R, ) -> Result> { @@ -60,13 +63,15 @@ impl> Ledger { let previous_block = self.latest_block(); // Construct the block template. - let (header, ratifications, solutions, transactions, aborted_transaction_ids) = self.construct_block_template( - &previous_block, - None, - candidate_ratifications, - candidate_solutions, - candidate_transactions, - )?; + let (header, ratifications, solutions, aborted_solution_ids, transactions, aborted_transaction_ids) = self + .construct_block_template( + &previous_block, + None, + candidate_ratifications, + candidate_solutions, + candidate_transactions, + rng, + )?; // Construct the new beacon block. Block::new_beacon( @@ -75,6 +80,7 @@ impl> Ledger { header, ratifications, solutions, + aborted_solution_ids, transactions, aborted_transaction_ids, rng, @@ -97,10 +103,18 @@ impl> Ledger { *self.current_committee.write() = Some(current_committee); } - // If the block is the start of a new epoch, or the epoch challenge has not been set, update the current epoch challenge. - if block.height() % N::NUM_BLOCKS_PER_EPOCH == 0 || self.current_epoch_challenge.read().is_none() { - // Update the current epoch challenge. - self.current_epoch_challenge.write().clone_from(&self.get_epoch_challenge(block.height()).ok()); + // If the block is the start of a new epoch, or the epoch hash has not been set, update the current epoch hash. + if block.height() % N::NUM_BLOCKS_PER_EPOCH == 0 || self.current_epoch_hash.read().is_none() { + // Update and log the current epoch hash. + match self.get_epoch_hash(block.height()).ok() { + Some(epoch_hash) => { + trace!("Updating the current epoch hash at block {} to '{epoch_hash}'", block.height()); + *self.current_epoch_hash.write() = Some(epoch_hash); + } + None => { + error!("Failed to update the current epoch hash at block {}", block.height()); + } + } } Ok(()) @@ -114,8 +128,8 @@ pub fn split_candidate_solutions( verification_fn: F, ) -> (Vec, Vec) where - T: Sized + Send, - F: Fn(&T) -> bool + Send + Sync, + T: Sized + Copy, + F: Fn(&mut T) -> bool, { // Separate the candidate solutions into valid and aborted solutions. let mut valid_candidate_solutions = Vec::with_capacity(max_solutions); @@ -134,79 +148,87 @@ where } // Split off a chunk of the candidate solutions. - let candidates_chunk = if candidate_solutions.len() > chunk_size { + let mut candidates_chunk = if candidate_solutions.len() > chunk_size { candidate_solutions.split_off(candidate_solutions.len() - chunk_size) } else { std::mem::take(&mut candidate_solutions) }; // Verify the solutions in the chunk. - let verification_results: Vec<_> = cfg_into_iter!(candidates_chunk) - .rev() - .map(|solution| { - let verified = verification_fn(&solution); - (solution, verified) - }) - .collect(); + let verification_results = candidates_chunk.iter_mut().rev().map(|solution| { + let verified = verification_fn(solution); + (solution, verified) + }); // Process the results of the verification. for (solution, is_valid) in verification_results.into_iter() { if is_valid && valid_candidate_solutions.len() < max_solutions { - valid_candidate_solutions.push(solution); + valid_candidate_solutions.push(*solution); } else { - aborted_candidate_solutions.push(solution); + aborted_candidate_solutions.push(*solution); } } } + // The `aborted_candidate_solutions` can contain both verified and unverified solutions. + // When `check_solution_mut` is used as `verification_fn`, these aborted solutions + // may include both mutated and un-mutated variants. This occurs because the verification + // check is skipped once the `max_solutions` limit is reached. + // + // This approach is SAFE because currently, only the `solutionID` of aborted solutions is stored. + // However, if full aborted solutions need to be stored in the future, this logic will need to be revisited. (valid_candidate_solutions, aborted_candidate_solutions) } impl> Ledger { /// Constructs a block template for the next block in the ledger. #[allow(clippy::type_complexity)] - fn construct_block_template( + fn construct_block_template( &self, previous_block: &Block, subdag: Option<&Subdag>, candidate_ratifications: Vec>, - candidate_solutions: Vec>, + candidate_solutions: Vec>, candidate_transactions: Vec>, - ) -> Result<(Header, Ratifications, Option>, Transactions, Vec)> + rng: &mut R, + ) -> Result<(Header, Ratifications, Solutions, Vec>, Transactions, Vec)> { // Construct the solutions. - let (solutions, solutions_root, combined_proof_target) = match candidate_solutions.is_empty() { - true => (None, Field::::zero(), 0u128), + let (solutions, aborted_solutions, solutions_root, combined_proof_target) = match candidate_solutions.is_empty() + { + true => (None, vec![], Field::::zero(), 0u128), false => { - // Retrieve the coinbase verifying key. - let coinbase_verifying_key = self.coinbase_puzzle.coinbase_verifying_key(); - // Retrieve the latest epoch challenge. - let latest_epoch_challenge = self.latest_epoch_challenge()?; - // TODO: For mainnet - Add `aborted_solution_ids` to the block. + // Retrieve the latest epoch hash. + let latest_epoch_hash = self.latest_epoch_hash()?; + // Retrieve the latest proof target. + let latest_proof_target = self.latest_proof_target(); // Separate the candidate solutions into valid and aborted solutions. - let (valid_candidate_solutions, _aborted_candidate_solutions) = + let (valid_candidate_solutions, aborted_candidate_solutions) = split_candidate_solutions(candidate_solutions, N::MAX_SOLUTIONS, |solution| { - solution - .verify(coinbase_verifying_key, &latest_epoch_challenge, self.latest_proof_target()) - .unwrap_or(false) + self.puzzle().check_solution_mut(solution, latest_epoch_hash, latest_proof_target).is_ok() }); // Check if there are any valid solutions. match valid_candidate_solutions.is_empty() { - true => (None, Field::::zero(), 0u128), + true => (None, aborted_candidate_solutions, Field::::zero(), 0u128), false => { // Construct the solutions. - let solutions = CoinbaseSolution::new(valid_candidate_solutions)?; + let solutions = PuzzleSolutions::new(valid_candidate_solutions)?; // Compute the solutions root. let solutions_root = solutions.to_accumulator_point()?; // Compute the combined proof target. - let combined_proof_target = solutions.to_combined_proof_target()?; + let combined_proof_target = self.puzzle().get_combined_proof_target(&solutions)?; // Output the solutions, solutions root, and combined proof target. - (Some(solutions), solutions_root, combined_proof_target) + (Some(solutions), aborted_candidate_solutions, solutions_root, combined_proof_target) } } } }; + // Prepare the solutions. + let solutions = Solutions::from(solutions); + + // Construct the aborted solution IDs. + let aborted_solution_ids = aborted_solutions.iter().map(Solution::id).collect::>(); // Retrieve the latest state root. let latest_state_root = self.latest_state_root(); @@ -214,6 +236,12 @@ impl> Ledger { let latest_cumulative_proof_target = previous_block.cumulative_proof_target(); // Retrieve the latest coinbase target. let latest_coinbase_target = previous_block.coinbase_target(); + // Retrieve the latest cumulative weight. + let latest_cumulative_weight = previous_block.cumulative_weight(); + // Retrieve the last coinbase target. + let last_coinbase_target = previous_block.last_coinbase_target(); + // Retrieve the last coinbase timestamp. + let last_coinbase_timestamp = previous_block.last_coinbase_timestamp(); // Compute the next round number. let next_round = match subdag { @@ -224,42 +252,55 @@ impl> Ledger { let next_height = previous_block.height().saturating_add(1); // Determine the timestamp for the next block. let next_timestamp = match subdag { - Some(subdag) => subdag.timestamp(), + Some(subdag) => { + // Retrieve the previous committee lookback. + let previous_committee_lookback = { + // Calculate the penultimate round, which is the round before the anchor round. + let penultimate_round = subdag.anchor_round().saturating_sub(1); + // Get the round number for the previous committee. Note, we subtract 2 from odd rounds, + // because committees are updated in even rounds. + let previous_penultimate_round = match penultimate_round % 2 == 0 { + true => penultimate_round.saturating_sub(1), + false => penultimate_round.saturating_sub(2), + }; + // Get the previous committee lookback round. + let penultimate_committee_lookback_round = + previous_penultimate_round.saturating_sub(Committee::::COMMITTEE_LOOKBACK_RANGE); + // Output the previous committee lookback. + self.get_committee_for_round(penultimate_committee_lookback_round)? + .ok_or(anyhow!("Failed to fetch committee for round {penultimate_committee_lookback_round}"))? + }; + // Return the timestamp for the given committee lookback. + subdag.timestamp(&previous_committee_lookback) + } None => OffsetDateTime::now_utc().unix_timestamp(), }; - // Compute the next cumulative weight. - let next_cumulative_weight = previous_block.cumulative_weight().saturating_add(combined_proof_target); - // Compute the next cumulative proof target. - let next_cumulative_proof_target = latest_cumulative_proof_target.saturating_add(combined_proof_target); - // Determine if the coinbase target is reached. - let is_coinbase_target_reached = next_cumulative_proof_target >= latest_coinbase_target as u128; - // Update the next cumulative proof target, if necessary. - let next_cumulative_proof_target = match is_coinbase_target_reached { - true => 0, - false => next_cumulative_proof_target, - }; - // Construct the next coinbase target. - let next_coinbase_target = coinbase_target( - previous_block.last_coinbase_target(), - previous_block.last_coinbase_timestamp(), + + // Calculate the next coinbase targets and timestamps. + let ( + next_coinbase_target, + next_proof_target, + next_cumulative_proof_target, + next_cumulative_weight, + next_last_coinbase_target, + next_last_coinbase_timestamp, + ) = to_next_targets::( + latest_cumulative_proof_target, + combined_proof_target, + latest_coinbase_target, + latest_cumulative_weight, + last_coinbase_target, + last_coinbase_timestamp, next_timestamp, - N::ANCHOR_TIME, - N::NUM_BLOCKS_PER_EPOCH, - N::GENESIS_COINBASE_TARGET, )?; - // Construct the next proof target. - let next_proof_target = proof_target(next_coinbase_target, N::GENESIS_PROOF_TARGET); - - // Construct the next last coinbase target and next last coinbase timestamp. - let (next_last_coinbase_target, next_last_coinbase_timestamp) = match is_coinbase_target_reached { - true => (next_coinbase_target, next_timestamp), - false => (previous_block.last_coinbase_target(), previous_block.last_coinbase_timestamp()), - }; // Calculate the coinbase reward. - let coinbase_reward = coinbase_reward( + let coinbase_reward = coinbase_reward::( next_height, + next_timestamp, + N::GENESIS_TIMESTAMP, N::STARTING_SUPPLY, + N::ANCHOR_TIME, N::ANCHOR_HEIGHT, N::BLOCK_TIME, combined_proof_target, @@ -278,10 +319,12 @@ impl> Ledger { // Speculate over the ratifications, solutions, and transactions. let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = self.vm.speculate( state, + next_timestamp.saturating_sub(previous_block.timestamp()), Some(coinbase_reward), candidate_ratifications, - solutions.as_ref(), + &solutions, candidate_transactions.iter(), + rng, )?; // Compute the ratifications root. @@ -319,6 +362,6 @@ impl> Ledger { )?; // Return the block template. - Ok((header, ratifications, solutions, transactions, aborted_transaction_ids)) + Ok((header, ratifications, solutions, aborted_solution_ids, transactions, aborted_transaction_ids)) } } diff --git a/ledger/src/check_next_block.rs b/ledger/src/check_next_block.rs index 4ac3ed0355..ac27f8a1e7 100644 --- a/ledger/src/check_next_block.rs +++ b/ledger/src/check_next_block.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,8 +15,6 @@ use super::*; -use rand::{rngs::StdRng, SeedableRng}; - impl> Ledger { /// Checks the given block is valid next block. pub fn check_next_block(&self, block: &Block, rng: &mut R) -> Result<()> { @@ -32,22 +31,12 @@ impl> Ledger { } // Ensure the solutions do not already exist. - if let Some(solutions) = block.solutions() { - for puzzle_commitment in solutions.puzzle_commitments() { - if self.contains_puzzle_commitment(puzzle_commitment)? { - bail!("Puzzle commitment {puzzle_commitment} already exists in the ledger"); - } + for solution_id in block.solutions().solution_ids() { + if self.contains_solution_id(solution_id)? { + bail!("Solution ID {solution_id} already exists in the ledger"); } } - // Ensure each transaction is well-formed and unique. - let transactions = block.transactions(); - let rngs = (0..transactions.len()).map(|_| StdRng::from_seed(rng.gen())).collect::>(); - cfg_iter!(transactions).zip(rngs).try_for_each(|(transaction, mut rng)| { - self.check_transaction_basic(transaction, transaction.to_rejected_id()?, &mut rng) - .map_err(|e| anyhow!("Invalid transaction found in the transactions list: {e}")) - })?; - // TODO (howardwu): Remove this after moving the total supply into credits.aleo. { // // Retrieve the latest total supply. @@ -80,22 +69,73 @@ impl> Ledger { block.previous_hash(), )?; - // Ensure speculation over the unconfirmed transactions is correct. - let ratified_finalize_operations = - self.vm.check_speculate(state, block.ratifications(), block.solutions(), block.transactions())?; + // Ensure speculation over the unconfirmed transactions is correct and ensure each transaction is well-formed and unique. + let time_since_last_block = block.timestamp().saturating_sub(self.latest_timestamp()); + let ratified_finalize_operations = self.vm.check_speculate( + state, + time_since_last_block, + block.ratifications(), + block.solutions(), + block.transactions(), + rng, + )?; + + // Retrieve the committee lookback. + let committee_lookback = { + // Determine the round number for the previous committee. Note, we subtract 2 from odd rounds, + // because committees are updated in even rounds. + let previous_round = match block.round() % 2 == 0 { + true => block.round().saturating_sub(1), + false => block.round().saturating_sub(2), + }; + // Determine the committee lookback round. + let committee_lookback_round = previous_round.saturating_sub(Committee::::COMMITTEE_LOOKBACK_RANGE); + // Output the committee lookback. + self.get_committee_for_round(committee_lookback_round)? + .ok_or(anyhow!("Failed to fetch committee for round {committee_lookback_round}"))? + }; + + // Retrieve the previous committee lookback. + let previous_committee_lookback = { + // Calculate the penultimate round, which is the round before the anchor round. + let penultimate_round = block.round().saturating_sub(1); + // Determine the round number for the previous committee. Note, we subtract 2 from odd rounds, + // because committees are updated in even rounds. + let previous_penultimate_round = match penultimate_round % 2 == 0 { + true => penultimate_round.saturating_sub(1), + false => penultimate_round.saturating_sub(2), + }; + // Determine the previous committee lookback round. + let penultimate_committee_lookback_round = + previous_penultimate_round.saturating_sub(Committee::::COMMITTEE_LOOKBACK_RANGE); + // Output the previous committee lookback. + self.get_committee_for_round(penultimate_committee_lookback_round)? + .ok_or(anyhow!("Failed to fetch committee for round {penultimate_committee_lookback_round}"))? + }; // Ensure the block is correct. - let expected_existing_transaction_ids = block.verify( + let (expected_existing_solution_ids, expected_existing_transaction_ids) = block.verify( &self.latest_block(), self.latest_state_root(), - &self.latest_committee()?, - self.coinbase_puzzle(), - &self.latest_epoch_challenge()?, + &previous_committee_lookback, + &committee_lookback, + self.puzzle(), + self.latest_epoch_hash()?, OffsetDateTime::now_utc().unix_timestamp(), ratified_finalize_operations, )?; - // Ensure that each existing transaction id from the block exists in the ledger. + // Determine if the block subdag is correctly constructed and is not a combination of multiple subdags. + self.check_block_subdag_atomicity(block)?; + + // Ensure that each existing solution ID from the block exists in the ledger. + for existing_solution_id in expected_existing_solution_ids { + if !self.contains_solution_id(&existing_solution_id)? { + bail!("Solution ID '{existing_solution_id}' does not exist in the ledger"); + } + } + + // Ensure that each existing transaction ID from the block exists in the ledger. for existing_transaction_id in expected_existing_transaction_ids { if !self.contains_transaction_id(&existing_transaction_id)? { bail!("Transaction ID '{existing_transaction_id}' does not exist in the ledger"); @@ -104,4 +144,66 @@ impl> Ledger { Ok(()) } + + /// Checks that the block subdag can not be split into multiple valid subdags. + fn check_block_subdag_atomicity(&self, block: &Block) -> Result<()> { + // Returns `true` if there is a path from the previous certificate to the current certificate. + fn is_linked( + subdag: &Subdag, + previous_certificate: &BatchCertificate, + current_certificate: &BatchCertificate, + ) -> Result { + // Initialize the list containing the traversal. + let mut traversal = vec![current_certificate]; + // Iterate over the rounds from the current certificate to the previous certificate. + for round in (previous_certificate.round()..current_certificate.round()).rev() { + // Retrieve all of the certificates for this past round. + let certificates = subdag.get(&round).ok_or(anyhow!("No certificates found for round {round}"))?; + // Filter the certificates to only include those that are in the traversal. + traversal = certificates + .into_iter() + .filter(|p| traversal.iter().any(|c| c.previous_certificate_ids().contains(&p.id()))) + .collect(); + } + Ok(traversal.contains(&previous_certificate)) + } + + // Check if the block has a subdag. + let subdag = match block.authority() { + Authority::Quorum(subdag) => subdag, + _ => return Ok(()), + }; + + // Iterate over the rounds to find possible leader certificates. + for round in (self.latest_round().saturating_add(2)..=subdag.anchor_round().saturating_sub(2)).rev().step_by(2) + { + // Retrieve the previous committee lookback. + let previous_committee_lookback = self + .get_committee_lookback_for_round(round)? + .ok_or_else(|| anyhow!("No committee lookback found for round {round}"))?; + + // Compute the leader for the commit round. + let computed_leader = previous_committee_lookback + .get_leader(round) + .map_err(|e| anyhow!("Failed to compute leader for round {round}: {e}"))?; + + // Retrieve the previous leader certificates. + let previous_certificate = match subdag.get(&round).and_then(|certificates| { + certificates.iter().find(|certificate| certificate.author() == computed_leader) + }) { + Some(cert) => cert, + None => continue, + }; + + // Determine if there is a path between the previous certificate and the subdag's leader certificate. + if is_linked(subdag, previous_certificate, subdag.leader_certificate())? { + bail!( + "The previous certificate should not be linked to the current certificate in block {}", + block.height() + ); + } + } + + Ok(()) + } } diff --git a/ledger/src/check_transaction_basic.rs b/ledger/src/check_transaction_basic.rs index cfdb6b7a76..d578a6704f 100644 --- a/ledger/src/check_transaction_basic.rs +++ b/ledger/src/check_transaction_basic.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,4 +25,13 @@ impl> Ledger { ) -> Result<()> { self.vm().check_transaction(transaction, rejected_id, rng) } + + /// Checks that the given list of transactions are well-formed and unique. + pub fn check_transactions_basic( + &self, + transactions: &[(&Transaction, Option>)], + rng: &mut R, + ) -> Result<()> { + self.vm().check_transactions(transactions, rng) + } } diff --git a/ledger/src/contains.rs b/ledger/src/contains.rs index 64a52bbda5..7f5243a46c 100644 --- a/ledger/src/contains.rs +++ b/ledger/src/contains.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -44,14 +45,14 @@ impl> Ledger { pub fn contains_transmission(&self, transmission_id: &TransmissionID) -> Result { match transmission_id { TransmissionID::Ratification => Ok(false), - TransmissionID::Solution(puzzle_commitment) => self.contains_puzzle_commitment(puzzle_commitment), - TransmissionID::Transaction(transaction_id) => self.contains_transaction_id(transaction_id), + TransmissionID::Solution(solution_id, _) => self.contains_solution_id(solution_id), + TransmissionID::Transaction(transaction_id, _) => self.contains_transaction_id(transaction_id), } } - /// Returns `true` if the given puzzle commitment exists. - pub fn contains_puzzle_commitment(&self, puzzle_commitment: &PuzzleCommitment) -> Result { - self.vm.block_store().contains_puzzle_commitment(puzzle_commitment) + /// Returns `true` if the given solution ID exists. + pub fn contains_solution_id(&self, solution_id: &SolutionID) -> Result { + self.vm.block_store().contains_solution_id(solution_id) } /* Transaction */ diff --git a/ledger/src/find.rs b/ledger/src/find.rs index 0e547d79d0..d24c0858e9 100644 --- a/ledger/src/find.rs +++ b/ledger/src/find.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -25,12 +26,9 @@ impl> Ledger { self.vm.block_store().find_block_hash(transaction_id) } - /// Returns the block height that contains the given `puzzle commitment`. - pub fn find_block_height_from_puzzle_commitment( - &self, - puzzle_commitment: &PuzzleCommitment, - ) -> Result> { - self.vm.block_store().find_block_height_from_puzzle_commitment(puzzle_commitment) + /// Returns the block height that contains the given `solution ID`. + pub fn find_block_height_from_solution_id(&self, solution_id: &SolutionID) -> Result> { + self.vm.block_store().find_block_height_from_solution_id(solution_id) } /// Returns the transaction ID that contains the given `program ID`. diff --git a/ledger/src/get.rs b/ledger/src/get.rs index 750b9f22f4..162dd2c247 100644 --- a/ledger/src/get.rs +++ b/ledger/src/get.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -25,6 +26,22 @@ impl> Ledger { self.vm.finalize_store().committee_store().get_committee_for_round(round) } + /// Returns the committee lookback for the given round. + pub fn get_committee_lookback_for_round(&self, round: u64) -> Result>> { + // Get the round number for the previous committee. Note, we subtract 2 from odd rounds, + // because committees are updated in even rounds. + let previous_round = match round % 2 == 0 { + true => round.saturating_sub(1), + false => round.saturating_sub(2), + }; + + // Get the committee lookback round. + let committee_lookback_round = previous_round.saturating_sub(Committee::::COMMITTEE_LOOKBACK_RANGE); + + // Retrieve the committee for the committee lookback round. + self.get_committee_for_round(committee_lookback_round) + } + /// Returns the state root that contains the given `block height`. pub fn get_state_root(&self, block_height: u32) -> Result> { self.vm.block_store().get_state_root(block_height) @@ -35,16 +52,16 @@ impl> Ledger { self.vm.block_store().get_state_path_for_commitment(commitment) } - /// Returns the epoch challenge for the given block height. - pub fn get_epoch_challenge(&self, block_height: u32) -> Result> { + /// Returns the epoch hash for the given block height. + pub fn get_epoch_hash(&self, block_height: u32) -> Result { // Compute the epoch number from the current block height. - let epoch_number = block_height / N::NUM_BLOCKS_PER_EPOCH; + let epoch_number = block_height.saturating_div(N::NUM_BLOCKS_PER_EPOCH); // Compute the epoch starting height (a multiple of `NUM_BLOCKS_PER_EPOCH`). - let epoch_starting_height = epoch_number * N::NUM_BLOCKS_PER_EPOCH; - // Retrieve the epoch block hash, defined as the 'previous block hash' from the epoch starting height. - let epoch_block_hash = self.get_previous_hash(epoch_starting_height)?; - // Construct the epoch challenge. - EpochChallenge::new(epoch_number, epoch_block_hash, N::COINBASE_PUZZLE_DEGREE) + let epoch_starting_height = epoch_number.saturating_mul(N::NUM_BLOCKS_PER_EPOCH); + // Retrieve the epoch hash, defined as the 'previous block hash' from the epoch starting height. + let epoch_hash = self.get_previous_hash(epoch_starting_height)?; + // Construct the epoch hash. + Ok(epoch_hash) } /// Returns the block for the given block height. @@ -200,10 +217,10 @@ impl> Ledger { } /// Returns the block solutions for the given block height. - pub fn get_solutions(&self, height: u32) -> Result>> { + pub fn get_solutions(&self, height: u32) -> Result> { // If the height is 0, return the genesis block solutions. if height == 0 { - return Ok(self.genesis_block.solutions().cloned()); + return Ok(self.genesis_block.solutions().clone()); } // Retrieve the block hash. let block_hash = match self.vm.block_store().get_block_hash(height)? { @@ -215,7 +232,7 @@ impl> Ledger { } /// Returns the solution for the given solution ID. - pub fn get_solution(&self, solution_id: &PuzzleCommitment) -> Result> { + pub fn get_solution(&self, solution_id: &SolutionID) -> Result> { self.vm.block_store().get_solution(solution_id) } @@ -241,15 +258,48 @@ impl> Ledger { pub fn get_batch_certificate(&self, certificate_id: &Field) -> Result>> { self.vm.block_store().get_batch_certificate(certificate_id) } + + /// Returns the delegators for the given validator. + pub fn get_delegators_for_validator(&self, validator: &Address) -> Result>> { + // Construct the credits.aleo program ID. + let credits_program_id = ProgramID::from_str("credits.aleo")?; + // Construct the bonded mapping name. + let bonded_mapping = Identifier::from_str("bonded")?; + // Construct the bonded mapping key name. + let bonded_mapping_key = Identifier::from_str("validator")?; + // Get the credits.aleo bonded mapping. + let bonded = self.vm.finalize_store().get_mapping_confirmed(credits_program_id, bonded_mapping)?; + // Select the delegators for the given validator. + cfg_into_iter!(bonded) + .filter_map(|(bonded_address, bond_state)| { + let Plaintext::Literal(Literal::Address(bonded_address), _) = bonded_address else { + return Some(Err(anyhow!("Invalid delegator in finalize storage."))); + }; + let Value::Plaintext(Plaintext::Struct(bond_state, _)) = bond_state else { + return Some(Err(anyhow!("Invalid bond_state in finalize storage."))); + }; + let Some(mapping_validator) = bond_state.get(&bonded_mapping_key) else { + return Some(Err(anyhow!("Invalid bond_state validator in finalize storage."))); + }; + let Plaintext::Literal(Literal::Address(mapping_validator), _) = mapping_validator else { + return Some(Err(anyhow!("Invalid validator in finalize storage."))); + }; + // Select bonded addresses which: + // 1. are bonded to the right validator. + // 2. are not themselves the validator. + (mapping_validator == validator && bonded_address != *validator).then_some(Ok(bonded_address)) + }) + .collect::>() + } } #[cfg(test)] mod tests { use super::*; use crate::test_helpers::CurrentLedger; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_get_block() { diff --git a/ledger/src/helpers/bft.rs b/ledger/src/helpers/bft.rs index 3b89c61509..29c73ca6fb 100644 --- a/ledger/src/helpers/bft.rs +++ b/ledger/src/helpers/bft.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,10 +17,10 @@ use console::network::Network; use ledger_block::{Ratify, Transaction}; -use ledger_coinbase::ProverSolution; use ledger_narwhal::{Transmission, TransmissionID}; +use ledger_puzzle::Solution; -use anyhow::{bail, ensure, Result}; +use anyhow::{Result, bail, ensure}; use std::collections::HashSet; /// Takes in an iterator of transmissions and returns a tuple of ratifications, solutions, and transactions. @@ -28,7 +29,7 @@ use std::collections::HashSet; /// This method guarantees that the output is 1) order-preserving, and 2) unique. pub fn decouple_transmissions( transmissions: impl Iterator, Transmission)>, -) -> Result<(Vec>, Vec>, Vec>)> { +) -> Result<(Vec>, Vec>, Vec>)> { // Initialize a list for the ratifications. let ratifications = Vec::new(); // Initialize a list for the solutions. @@ -46,15 +47,19 @@ pub fn decouple_transmissions( // Deserialize and store the transmission. match (transmission_id, transmission) { (TransmissionID::Ratification, Transmission::Ratification) => (), - (TransmissionID::Solution(commitment), Transmission::Solution(solution)) => { + (TransmissionID::Solution(commitment, checksum), Transmission::Solution(solution)) => { + // Ensure the transmission checksum corresponds to the solution. + ensure!(checksum == solution.to_checksum::()?, "Mismatching transmission checksum (solution)"); // Deserialize the solution. let solution = solution.deserialize_blocking()?; // Ensure the transmission ID corresponds to the solution. - ensure!(commitment == solution.commitment(), "Mismatching transmission ID (solution)"); + ensure!(commitment == solution.id(), "Mismatching transmission ID (solution)"); // Insert the solution into the list. solutions.push(solution); } - (TransmissionID::Transaction(transaction_id), Transmission::Transaction(transaction)) => { + (TransmissionID::Transaction(transaction_id, checksum), Transmission::Transaction(transaction)) => { + // Ensure the transmission checksum corresponds to the transaction. + ensure!(checksum == transaction.to_checksum::()?, "Mismatching transmission checksum (transaction)"); // Deserialize the transaction. let transaction = transaction.deserialize_blocking()?; // Ensure the transmission ID corresponds to the transaction. diff --git a/ledger/src/helpers/mod.rs b/ledger/src/helpers/mod.rs index 2b00c4b28c..98b4db6024 100644 --- a/ledger/src/helpers/mod.rs +++ b/ledger/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/src/helpers/supply.rs b/ledger/src/helpers/supply.rs index b534846805..6770bbb25b 100644 --- a/ledger/src/helpers/supply.rs +++ b/ledger/src/helpers/supply.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,7 +16,7 @@ use console::network::Network; use ledger_block::Transactions; -use anyhow::{anyhow, Result}; +use anyhow::{Result, anyhow}; /// Returns the next total supply in microcredits, given the starting total supply and newly-confirmed transactions. pub fn update_total_supply( diff --git a/ledger/src/iterators.rs b/ledger/src/iterators.rs index 976de7393a..fce64fb998 100644 --- a/ledger/src/iterators.rs +++ b/ledger/src/iterators.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,9 +21,9 @@ impl> Ledger { self.vm.block_store().state_roots() } - /// Returns an iterator over the puzzle commitments, for all blocks in `self`. - pub fn puzzle_commitments(&self) -> impl '_ + Iterator>> { - self.vm.block_store().puzzle_commitments() + /// Returns an iterator over the solution IDs, for all blocks in `self`. + pub fn solution_ids(&self) -> impl '_ + Iterator>> { + self.vm.block_store().solution_ids() } /* Transaction */ diff --git a/ledger/src/lib.rs b/ledger/src/lib.rs index c56fc67c69..4d7465c744 100644 --- a/ledger/src/lib.rs +++ b/ledger/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -20,9 +21,9 @@ extern crate tracing; pub use ledger_authority as authority; pub use ledger_block as block; -pub use ledger_coinbase as coinbase; pub use ledger_committee as committee; pub use ledger_narwhal as narwhal; +pub use ledger_puzzle as puzzle; pub use ledger_query as query; pub use ledger_store as store; @@ -52,9 +53,9 @@ use console::{ types::{Field, Group}, }; use ledger_authority::Authority; -use ledger_coinbase::{CoinbasePuzzle, CoinbaseSolution, EpochChallenge, ProverSolution, PuzzleCommitment}; use ledger_committee::Committee; use ledger_narwhal::{BatchCertificate, Subdag, Transmission, TransmissionID}; +use ledger_puzzle::{Puzzle, PuzzleSolutions, Solution, SolutionID}; use ledger_query::Query; use ledger_store::{ConsensusStorage, ConsensusStore}; use synthesizer::{ @@ -63,8 +64,8 @@ use synthesizer::{ }; use aleo_std::{ - prelude::{finish, lap, timer}, StorageMode, + prelude::{finish, lap, timer}, }; use anyhow::Result; use core::ops::Range; @@ -99,10 +100,8 @@ pub struct Ledger> { vm: VM, /// The genesis block. genesis_block: Block, - /// The coinbase puzzle. - coinbase_puzzle: CoinbasePuzzle, - /// The current epoch challenge. - current_epoch_challenge: Arc>>>, + /// The current epoch hash. + current_epoch_hash: Arc>>, /// The current committee. current_committee: Arc>>>, /// The current block. @@ -128,7 +127,7 @@ impl> Ledger { const NUM_BLOCKS: usize = 10; // Retrieve the latest height. let latest_height = ledger.current_block.read().height(); - debug_assert_eq!(latest_height, *ledger.vm.block_store().heights().max().unwrap(), "Mismatch in latest height"); + debug_assert_eq!(latest_height, ledger.vm.block_store().max_height().unwrap(), "Mismatch in latest height"); // Sample random block heights. let block_heights: Vec = (0..=latest_height).choose_multiple(&mut OsRng, (latest_height as usize).min(NUM_BLOCKS)); @@ -165,14 +164,13 @@ impl> Ledger { let mut ledger = Self { vm, genesis_block: genesis_block.clone(), - coinbase_puzzle: CoinbasePuzzle::::load()?, - current_epoch_challenge: Default::default(), + current_epoch_hash: Default::default(), current_committee: Arc::new(RwLock::new(current_committee)), current_block: Arc::new(RwLock::new(genesis_block.clone())), }; // If the block store is empty, initialize the genesis block. - if ledger.vm.block_store().heights().max().is_none() { + if ledger.vm.block_store().max_height().is_none() { // Add the genesis block. ledger.advance_to_next_block(&genesis_block)?; } @@ -180,7 +178,7 @@ impl> Ledger { // Retrieve the latest height. let latest_height = - *ledger.vm.block_store().heights().max().ok_or_else(|| anyhow!("Failed to load blocks from the ledger"))?; + ledger.vm.block_store().max_height().ok_or_else(|| anyhow!("Failed to load blocks from the ledger"))?; // Fetch the latest block. let block = ledger .get_block(latest_height) @@ -190,8 +188,8 @@ impl> Ledger { ledger.current_block = Arc::new(RwLock::new(block)); // Set the current committee (and ensures the latest committee exists). ledger.current_committee = Arc::new(RwLock::new(Some(ledger.latest_committee()?))); - // Set the current epoch challenge. - ledger.current_epoch_challenge = Arc::new(RwLock::new(Some(ledger.get_epoch_challenge(latest_height)?))); + // Set the current epoch hash. + ledger.current_epoch_hash = Arc::new(RwLock::new(Some(ledger.get_epoch_hash(latest_height)?))); finish!(timer, "Initialize ledger"); Ok(ledger) @@ -202,9 +200,9 @@ impl> Ledger { &self.vm } - /// Returns the coinbase puzzle. - pub const fn coinbase_puzzle(&self) -> &CoinbasePuzzle { - &self.coinbase_puzzle + /// Returns the puzzle. + pub const fn puzzle(&self) -> &Puzzle { + self.vm.puzzle() } /// Returns the latest committee. @@ -225,11 +223,11 @@ impl> Ledger { self.current_block.read().height() / N::NUM_BLOCKS_PER_EPOCH } - /// Returns the latest epoch challenge. - pub fn latest_epoch_challenge(&self) -> Result> { - match self.current_epoch_challenge.read().as_ref() { - Some(challenge) => Ok(challenge.clone()), - None => self.get_epoch_challenge(self.latest_height()), + /// Returns the latest epoch hash. + pub fn latest_epoch_hash(&self) -> Result { + match self.current_epoch_hash.read().as_ref() { + Some(epoch_hash) => Ok(*epoch_hash), + None => self.get_epoch_hash(self.latest_height()), } } @@ -389,14 +387,16 @@ pub(crate) mod test_helpers { use aleo_std::StorageMode; use console::{ account::{Address, PrivateKey, ViewKey}, - network::Testnet3, + network::MainnetV0, prelude::*, }; use ledger_block::Block; use ledger_store::ConsensusStore; + use snarkvm_circuit::network::AleoV0; use synthesizer::vm::VM; - pub(crate) type CurrentNetwork = Testnet3; + pub(crate) type CurrentNetwork = MainnetV0; + pub(crate) type CurrentAleo = AleoV0; #[cfg(not(feature = "rocks"))] pub(crate) type CurrentLedger = diff --git a/ledger/src/tests.rs b/ledger/src/tests.rs index bc60cfab8a..cc5989c0e5 100644 --- a/ledger/src/tests.rs +++ b/ledger/src/tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,19 +14,166 @@ // limitations under the License. use crate::{ - advance::split_candidate_solutions, - test_helpers::{CurrentLedger, CurrentNetwork}, + Ledger, RecordsFilter, + advance::split_candidate_solutions, + test_helpers::{CurrentAleo, CurrentLedger, CurrentNetwork}, }; use aleo_std::StorageMode; use console::{ account::{Address, PrivateKey}, - network::prelude::*, + network::{MainnetV0, prelude::*}, program::{Entry, Identifier, Literal, Plaintext, ProgramID, Value}, + types::U16, }; -use ledger_block::{ConfirmedTransaction, Rejected, Transaction}; -use ledger_store::{helpers::memory::ConsensusMemory, ConsensusStore}; -use synthesizer::{program::Program, vm::VM}; +use ledger_authority::Authority; +use ledger_block::{Block, ConfirmedTransaction, Execution, Ratify, Rejected, Transaction}; +use ledger_committee::{Committee, MIN_VALIDATOR_STAKE}; +use ledger_narwhal::{BatchCertificate, BatchHeader, Data, Subdag, Transmission, TransmissionID}; +use ledger_store::{ConsensusStore, helpers::memory::ConsensusMemory}; +use snarkvm_utilities::try_vm_runtime; +use synthesizer::{Stack, program::Program, vm::VM}; + +use indexmap::{IndexMap, IndexSet}; +use rand::seq::SliceRandom; +use std::collections::{BTreeMap, HashMap}; +use time::OffsetDateTime; + +/// Initializes a sample VM. +fn sample_vm() -> VM> { + VM::from(ConsensusStore::>::open(None).unwrap()).unwrap() +} + +/// Extract the transmissions from a block. +fn extract_transmissions( + block: &Block, +) -> IndexMap, Transmission> { + let mut transmissions = IndexMap::new(); + for tx in block.transactions().iter() { + let checksum = Data::Object(tx.transaction().clone()).to_checksum::().unwrap(); + transmissions.insert(TransmissionID::from((&tx.id(), &checksum)), tx.transaction().clone().into()); + } + if let Some(coinbase_solution) = block.solutions().as_ref() { + for (_, solution) in coinbase_solution.iter() { + let checksum = Data::Object(*solution).to_checksum::().unwrap(); + transmissions.insert(TransmissionID::from((solution.id(), checksum)), (*solution).into()); + } + } + transmissions +} + +/// Construct `num_blocks` quorum blocks given a set of validator private keys and the genesis block. +fn construct_quorum_blocks( + private_keys: Vec>, + genesis: Block, + num_blocks: u64, + rng: &mut TestRng, +) -> Vec> { + // Initialize the ledger with the genesis block. + let ledger = + Ledger::>::load(genesis.clone(), StorageMode::Production) + .unwrap(); + + // Initialize the round parameters. + assert!(num_blocks > 0); + assert!(num_blocks < 25); + let rounds_per_commit = 2; + let final_round = num_blocks.saturating_mul(rounds_per_commit); + + // Sample rounds of batch certificates starting at the genesis round from a static set of 4 authors. + let (round_to_certificates_map, committee) = { + let committee = ledger.latest_committee().unwrap(); + let mut round_to_certificates_map: HashMap>> = HashMap::new(); + let mut previous_certificates: IndexSet> = IndexSet::with_capacity(4); + + // Create certificates for each round. + for round in 1..=final_round { + let mut current_certificates = IndexSet::new(); + let previous_certificate_ids = + if round <= 1 { IndexSet::new() } else { previous_certificates.iter().map(|c| c.id()).collect() }; + + for (i, private_key_1) in private_keys.iter().enumerate() { + let batch_header = BatchHeader::new( + private_key_1, + round, + OffsetDateTime::now_utc().unix_timestamp(), + committee.id(), + Default::default(), + previous_certificate_ids.clone(), + rng, + ) + .unwrap(); + // Add signatures for the batch headers. This creates a fully connected DAG. + let signatures = private_keys + .iter() + .enumerate() + .filter(|&(j, _)| i != j) + .map(|(_, private_key_2)| private_key_2.sign(&[batch_header.batch_id()], rng).unwrap()) + .collect(); + current_certificates.insert(BatchCertificate::from(batch_header, signatures).unwrap()); + } + + round_to_certificates_map.insert(round, current_certificates.clone()); + previous_certificates = current_certificates; + } + (round_to_certificates_map, committee) + }; + + // Helper function to create a quorum block. + fn create_next_quorum_block( + ledger: &Ledger>, + round: u64, + leader_certificate: &BatchCertificate, + previous_leader_certificate: Option<&BatchCertificate>, + round_to_certificates_map: &HashMap>>, + rng: &mut TestRng, + ) -> Block { + // Construct the subdag for the block. + let mut subdag_map = BTreeMap::new(); + // Add the leader certificate. + subdag_map.insert(round, [leader_certificate.clone()].into()); + // Add the certificates of the previous round. + subdag_map.insert(round - 1, round_to_certificates_map.get(&(round - 1)).unwrap().clone()); + // Add the certificates from the previous leader round, excluding the previous leader certificate. + // This assumes the number of rounds per commit is 2. + if let Some(prev_leader_cert) = previous_leader_certificate { + let mut previous_leader_round_certificates = + round_to_certificates_map.get(&(round - 2)).cloned().unwrap_or_default(); + previous_leader_round_certificates.shift_remove(prev_leader_cert); + subdag_map.insert(round - 2, previous_leader_round_certificates); + } + // Construct the block. + let subdag = Subdag::from(subdag_map).unwrap(); + let block = ledger.prepare_advance_to_next_quorum_block(subdag, Default::default(), rng).unwrap(); + ledger.check_next_block(&block, rng).unwrap(); + block + } + + // Track the blocks that are created. + let mut blocks = Vec::new(); + let mut previous_leader_certificate: Option<&BatchCertificate> = None; + + // Construct the blocks. + for block_height in 1..=num_blocks { + let round = block_height.saturating_mul(rounds_per_commit); + let leader = committee.get_leader(round).unwrap(); + let leader_certificate = + round_to_certificates_map.get(&round).unwrap().iter().find(|c| c.author() == leader).unwrap(); + let block = create_next_quorum_block( + &ledger, + round, + leader_certificate, + previous_leader_certificate, + &round_to_certificates_map, + rng, + ); + ledger.advance_to_next_block(&block).unwrap(); + previous_leader_certificate = Some(leader_certificate); + blocks.push(block); + } + + blocks +} #[test] fn test_load() { @@ -200,6 +348,8 @@ fn test_insufficient_public_fees() { // Sample recipient. let recipient_private_key = PrivateKey::new(rng).unwrap(); let recipient_address = Address::try_from(&recipient_private_key).unwrap(); + let withdrawal_private_key = PrivateKey::::new(rng).unwrap(); + let withdrawal_address = Address::try_from(&withdrawal_private_key).unwrap(); // Fund the recipient with 1 million credits. { @@ -219,15 +369,16 @@ fn test_insufficient_public_fees() { ledger.advance_to_next_block(&block).unwrap(); } - println!("-----------"); - // Attempt to bond the node with insufficient public fees. { - let inputs = - [Value::from_str(&format!("{recipient_address}")).unwrap(), Value::from_str("1000000000000u64").unwrap()]; + let inputs = [ + Value::from_str(&format!("{withdrawal_address}")).unwrap(), + Value::from_str("1000000000000u64").unwrap(), + Value::from_str("10u8").unwrap(), + ]; let transaction = ledger .vm - .execute(&recipient_private_key, ("credits.aleo", "bond_public"), inputs.into_iter(), None, 0, None, rng) + .execute(&recipient_private_key, ("credits.aleo", "bond_validator"), inputs.into_iter(), None, 0, None, rng) .unwrap(); let block = @@ -492,20 +643,36 @@ fn test_bond_and_unbond_validator() { // Sample new account for the new committee member. let new_member_private_key = PrivateKey::::new(rng).unwrap(); let new_member_address = Address::try_from(&new_member_private_key).unwrap(); + let new_member_withdrawal_private_key = PrivateKey::::new(rng).unwrap(); + let new_member_withdrawal_address = Address::try_from(&new_member_withdrawal_private_key).unwrap(); - // Fund the new committee member. + // Fund the new committee member and their withdrawwal address. let inputs = [ Value::from_str(&format!("{new_member_address}")).unwrap(), - Value::from_str("10000000000000u64").unwrap(), // 10 million credits. + Value::from_str("20000000000000u64").unwrap(), // 20 million credits. ]; let transfer_transaction = ledger .vm .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) .unwrap(); + let inputs = [ + Value::from_str(&format!("{new_member_withdrawal_address}")).unwrap(), + Value::from_str("20000000u64").unwrap(), // 20 credits. + ]; + let transfer_to_withdrawal_transaction = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); // Construct the next block. let transfer_block = ledger - .prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transfer_transaction], rng) + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + vec![], + vec![transfer_transaction, transfer_to_withdrawal_transaction], + rng, + ) .unwrap(); // Check that the next block is valid. @@ -515,19 +682,21 @@ fn test_bond_and_unbond_validator() { ledger.advance_to_next_block(&transfer_block).unwrap(); // Construct the bond public - let bond_amount = 1000000000000u64; // 1 million credits. + let bond_amount = MIN_VALIDATOR_STAKE; + let commission = 10u8; let inputs = [ - Value::from_str(&format!("{new_member_address}")).unwrap(), + Value::from_str(&format!("{new_member_withdrawal_address}")).unwrap(), Value::from_str(&format!("{bond_amount}u64")).unwrap(), + Value::from_str(&format!("{commission}u8")).unwrap(), ]; - let bond_public_transaction = ledger + let bond_validator_transaction = ledger .vm - .execute(&new_member_private_key, ("credits.aleo", "bond_public"), inputs.iter(), None, 0, None, rng) + .execute(&new_member_private_key, ("credits.aleo", "bond_validator"), inputs.iter(), None, 0, None, rng) .unwrap(); // Construct the next block. - let bond_public_block = ledger - .prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![bond_public_transaction], rng) + let bond_validator_block = ledger + .prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![bond_validator_transaction], rng) .unwrap(); // Check that the committee does not include the new member. @@ -535,21 +704,49 @@ fn test_bond_and_unbond_validator() { assert!(!committee.is_committee_member(new_member_address)); // Check that the next block is valid. - ledger.check_next_block(&bond_public_block, rng).unwrap(); + ledger.check_next_block(&bond_validator_block, rng).unwrap(); // Add the bond public block to the ledger. - ledger.advance_to_next_block(&bond_public_block).unwrap(); + ledger.advance_to_next_block(&bond_validator_block).unwrap(); // Check that the committee is updated with the new member. let committee = ledger.latest_committee().unwrap(); assert!(committee.is_committee_member(new_member_address)); - // Construct the bond public - let unbond_amount = committee.get_stake(new_member_address); // 1 million credits. - let inputs = [Value::from_str(&format!("{unbond_amount}u64")).unwrap()]; + // Check that number of validators in the `metadata` mapping in `credtis.aleo` is updated. + let program_id = ProgramID::::from_str("credits.aleo").unwrap(); + let metadata_mapping_name = Identifier::from_str("metadata").unwrap(); + let key = Plaintext::::from_str("aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc") + .unwrap(); + let num_validators = match ledger + .vm() + .finalize_store() + .get_value_confirmed(program_id, metadata_mapping_name, &key) + .unwrap() + .unwrap() + { + Value::Plaintext(Plaintext::Literal(Literal::U32(num_validators), _)) => *num_validators as usize, + _ => panic!("Unexpected value type"), + }; + assert_eq!(num_validators, committee.num_members()); + + // Construct the unbond public + let unbond_amount = committee.get_stake(new_member_address); + let inputs = [ + Value::from_str(&format!("{new_member_address}")).unwrap(), + Value::from_str(&format!("{unbond_amount}u64")).unwrap(), + ]; let unbond_public_transaction = ledger .vm - .execute(&new_member_private_key, ("credits.aleo", "unbond_public"), inputs.iter(), None, 0, None, rng) + .execute( + &new_member_withdrawal_private_key, + ("credits.aleo", "unbond_public"), + inputs.iter(), + None, + 0, + None, + rng, + ) .unwrap(); // Construct the next block. @@ -566,6 +763,23 @@ fn test_bond_and_unbond_validator() { // Check that the committee does not include the new member. let committee = ledger.latest_committee().unwrap(); assert!(!committee.is_committee_member(new_member_address)); + + // Check that number of validators in the `metadata` mapping in `credtis.aleo` is updated. + let program_id = ProgramID::::from_str("credits.aleo").unwrap(); + let metadata_mapping_name = Identifier::from_str("metadata").unwrap(); + let key = Plaintext::::from_str("aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc") + .unwrap(); + let num_validators = match ledger + .vm() + .finalize_store() + .get_value_confirmed(program_id, metadata_mapping_name, &key) + .unwrap() + .unwrap() + { + Value::Plaintext(Plaintext::Literal(Literal::U32(num_validators), _)) => *num_validators as usize, + _ => panic!("Unexpected value type"), + }; + assert_eq!(num_validators, committee.num_members()); } #[test] @@ -637,6 +851,53 @@ fn test_aborted_transaction_indexing() { ledger.advance_to_next_block(&block).unwrap(); } +#[test] +fn test_aborted_solution_ids() { + let rng = &mut TestRng::default(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = crate::test_helpers::sample_test_env(rng); + + // Retrieve the puzzle parameters. + let puzzle = ledger.puzzle(); + let latest_epoch_hash = ledger.latest_epoch_hash().unwrap(); + let minimum_proof_target = ledger.latest_proof_target(); + + // Create a solution that is less than the minimum proof target. + let mut invalid_solution = puzzle.prove(latest_epoch_hash, address, rng.gen(), None).unwrap(); + while puzzle.get_proof_target(&invalid_solution).unwrap() >= minimum_proof_target { + invalid_solution = puzzle.prove(latest_epoch_hash, address, rng.gen(), None).unwrap(); + } + + // Create a valid transaction for the block. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("10u64").unwrap()]; + let transfer_transaction = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + + // Create a block. + let block = ledger + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + vec![invalid_solution], + vec![transfer_transaction], + rng, + ) + .unwrap(); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Add the deployment block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); + + // Enforce that the block solution was aborted properly. + assert!(block.solutions().is_empty()); + assert_eq!(block.aborted_solution_ids(), &vec![invalid_solution.id()]); +} + #[test] fn test_execute_duplicate_input_ids() { let rng = &mut TestRng::default(); @@ -660,56 +921,107 @@ fn test_execute_duplicate_input_ids() { // Fetch the unspent records. let records = find_records(); - let record_1 = records[0].clone(); + let record_execution = records[0].clone(); + let record_deployment = records[1].clone(); - // Prepare a transfer that spends the record. + // Prepare a transfer that spends a record. let inputs = [ - Value::Record(record_1.clone()), + Value::Record(record_execution.clone()), Value::from_str(&format!("{address}")).unwrap(), Value::from_str("100u64").unwrap(), ]; - let transfer_1 = ledger - .vm - .execute(&private_key, ("credits.aleo", "transfer_private"), inputs.into_iter(), None, 0, None, rng) - .unwrap(); - let transfer_1_id = transfer_1.id(); - // Prepare a transfer that attempts to spend the same record. - let inputs = [ - Value::Record(record_1.clone()), - Value::from_str(&format!("{address}")).unwrap(), - Value::from_str("1000u64").unwrap(), - ]; - let transfer_2 = ledger - .vm - .execute(&private_key, ("credits.aleo", "transfer_private"), inputs.into_iter(), None, 0, None, rng) + let num_duplicate_deployments = 3; + let mut executions = Vec::with_capacity(num_duplicate_deployments + 1); + let mut execution_ids = Vec::with_capacity(num_duplicate_deployments + 1); + let mut deployments = Vec::with_capacity(num_duplicate_deployments); + let mut deployment_ids = Vec::with_capacity(num_duplicate_deployments); + + // Create Executions and Deployments, spending the same record. + for i in 0..num_duplicate_deployments { + // Execute. + let execution = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_private"), inputs.clone().iter(), None, 0, None, rng) + .unwrap(); + execution_ids.push(execution.id()); + executions.push(execution); + // Deploy. + let program_id = ProgramID::::from_str(&format!("dummy_program_{i}.aleo")).unwrap(); + let program = Program::::from_str(&format!( + " +program {program_id}; +function foo: + input r0 as u8.private; + async foo r0 into r1; + output r1 as {program_id}/foo.future; +finalize foo: + input r0 as u8.public; + add r0 r0 into r1;", + )) .unwrap(); - let transfer_2_id = transfer_2.id(); + let deployment = + ledger.vm.deploy(&private_key, &program, Some(record_deployment.clone()), 0, None, rng).unwrap(); + deployment_ids.push(deployment.id()); + deployments.push(deployment); + } - // Prepare a transfer that attempts to spend the same record in the fee. + // Create one more execution which spends the record as a fee. let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("100u64").unwrap()]; - let transfer_3 = ledger + let execution = ledger .vm .execute( &private_key, ("credits.aleo", "transfer_public"), - inputs.into_iter(), - Some(record_1.clone()), + inputs.clone().iter(), + Some(record_execution.clone()), 0, None, rng, ) .unwrap(); - let transfer_3_id = transfer_3.id(); - - // Prepare a transfer that attempts to spend the same record for the subsequent block. - let inputs = - [Value::Record(record_1), Value::from_str(&format!("{address}")).unwrap(), Value::from_str("1000u64").unwrap()]; - let transfer_4 = ledger + execution_ids.push(execution.id()); + executions.push(execution); + + // Select a transaction to mutate by a malicious validator. + let transaction_to_mutate = executions.last().unwrap().clone(); + + // Create a mutated execution which adds one transition, resulting in a different transaction id. + // This simulates a malicious validator re-using execution content. + let execution_to_mutate = transaction_to_mutate.execution().unwrap(); + // Sample a transition. + let sample = ledger_test_helpers::sample_transition(rng); + // Extend the transitions. + let mutated_transitions = std::iter::once(sample).chain(execution_to_mutate.transitions().cloned()); + // Create a mutated execution. + let mutated_execution = Execution::from( + mutated_transitions, + execution_to_mutate.global_state_root(), + execution_to_mutate.proof().cloned(), + ) + .unwrap(); + // Create a new fee for the execution. + let fee_authorization = ledger .vm - .execute(&private_key, ("credits.aleo", "transfer_private"), inputs.into_iter(), None, 0, None, rng) + .authorize_fee_public( + &private_key, + *executions.last().unwrap().fee_amount().unwrap(), + 0, + mutated_execution.to_execution_id().unwrap(), + rng, + ) .unwrap(); - let transfer_4_id = transfer_4.id(); + let fee = ledger.vm.execute_fee_authorization(fee_authorization, None, rng).unwrap(); + // Create a mutated transaction. + let mutated_transaction = Transaction::from_execution(mutated_execution, Some(fee)).unwrap(); + execution_ids.push(mutated_transaction.id()); + executions.push(mutated_transaction); + + // Create a mutated execution which just takes the fee transition, resulting in a different transaction id. + // This simulates a malicious validator transforming a transaction to a fee transaction. + let mutated_transaction = Transaction::from_fee(transaction_to_mutate.fee_transition().unwrap()).unwrap(); + execution_ids.push(mutated_transaction.id()); + executions.push(mutated_transaction); // Create a block. let block = ledger @@ -717,7 +1029,15 @@ fn test_execute_duplicate_input_ids() { &private_key, vec![], vec![], - vec![transfer_1, transfer_2, transfer_3], + vec![ + executions.pop().unwrap(), + executions.pop().unwrap(), + executions.pop().unwrap(), + executions.pop().unwrap(), + executions.pop().unwrap(), + deployments.pop().unwrap(), + deployments.pop().unwrap(), + ], rng, ) .unwrap(); @@ -729,21 +1049,45 @@ fn test_execute_duplicate_input_ids() { ledger.advance_to_next_block(&block).unwrap(); // Enforce that the block transactions were correct. - assert_eq!(block.transactions().num_accepted(), 1); - assert_eq!(block.transactions().transaction_ids().collect::>(), vec![&transfer_1_id]); - assert_eq!(block.aborted_transaction_ids(), &vec![transfer_2_id, transfer_3_id]); + assert_eq!(block.transactions().num_accepted(), 2); + println!("execution_ids: {:?}", execution_ids); + assert_eq!(block.transactions().transaction_ids().collect::>(), vec![&execution_ids[2], &deployment_ids[2]]); + assert_eq!(block.aborted_transaction_ids(), &vec![ + execution_ids[5], + execution_ids[4], + execution_ids[3], + execution_ids[1], + deployment_ids[1] + ]); + + // Ensure that verification was not run on aborted deployments. + let partially_verified_transaction = ledger.vm().partially_verified_transactions().read().clone(); + + assert!(partially_verified_transaction.contains(&execution_ids[2])); + assert!(partially_verified_transaction.contains(&deployment_ids[2])); + assert!(!partially_verified_transaction.contains(&execution_ids[1])); + assert!(!partially_verified_transaction.contains(&deployment_ids[1])); + assert!(!partially_verified_transaction.contains(&execution_ids[3])); + assert!(!partially_verified_transaction.contains(&execution_ids[4])); // Verification was run, but the execution was invalid. + assert!(!partially_verified_transaction.contains(&execution_ids[5])); // Prepare a transfer that will succeed for the subsequent block. let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("1000u64").unwrap()]; - let transfer_5 = ledger + let transfer = ledger .vm .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.into_iter(), None, 0, None, rng) .unwrap(); - let transfer_5_id = transfer_5.id(); + let transfer_id = transfer.id(); // Create a block. let block = ledger - .prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transfer_4, transfer_5], rng) + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + vec![], + vec![executions.pop().unwrap(), deployments.pop().unwrap(), transfer], + rng, + ) .unwrap(); // Check that the next block is valid. @@ -754,8 +1098,14 @@ fn test_execute_duplicate_input_ids() { // Enforce that the block transactions were correct. assert_eq!(block.transactions().num_accepted(), 1); - assert_eq!(block.transactions().transaction_ids().collect::>(), vec![&transfer_5_id]); - assert_eq!(block.aborted_transaction_ids(), &vec![transfer_4_id]); + assert_eq!(block.transactions().transaction_ids().collect::>(), vec![&transfer_id]); + assert_eq!(block.aborted_transaction_ids(), &vec![execution_ids[0], deployment_ids[0]]); + + // Ensure that verification was not run on transactions aborted in a previous block. + let partially_verified_transaction = ledger.vm().partially_verified_transactions().read().clone(); + assert!(partially_verified_transaction.contains(&transfer_id)); + assert!(!partially_verified_transaction.contains(&execution_ids[0])); + assert!(!partially_verified_transaction.contains(&deployment_ids[0])); } #[test] @@ -763,7 +1113,8 @@ fn test_execute_duplicate_output_ids() { let rng = &mut TestRng::default(); // Initialize the test environment. - let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = crate::test_helpers::sample_test_env(rng); + let crate::test_helpers::TestEnv { ledger, private_key, view_key, address, .. } = + crate::test_helpers::sample_test_env(rng); // Deploy a test program to the ledger. let program = Program::::from_str( @@ -796,8 +1147,25 @@ function create_duplicate_record: // Add the block to the ledger. ledger.advance_to_next_block(&block).unwrap(); - // Create a transaction with different transition ids, but with a fixed output record (output ID). - let mut create_transaction_with_duplicate_output_id = |x: u64| -> Transaction { + // A helper function to find records. + let find_records = || { + let microcredits = Identifier::from_str("microcredits").unwrap(); + ledger + .find_records(&view_key, RecordsFilter::SlowUnspent(private_key)) + .unwrap() + .filter(|(_, record)| match record.data().get(µcredits) { + Some(Entry::Private(Plaintext::Literal(Literal::U64(amount), _))) => !amount.is_zero(), + _ => false, + }) + .collect::>() + }; + + // Fetch the unspent records. + let records = find_records(); + let record_1 = records[0].clone(); + + // Create an execution with different transition ids, but with a fixed output record (output ID). + let mut create_execution_with_duplicate_output_id = |x: u64| -> Transaction { // Use a fixed seed RNG. let fixed_rng = &mut TestRng::from_seed(1); @@ -834,16 +1202,61 @@ function create_duplicate_record: Transaction::from_execution(execution, Some(fee)).unwrap() }; + // Create an deployment with different transition ids, but with a fixed output record (output ID). + let create_deployment_with_duplicate_output_id = |x: u64| -> Transaction { + // Use a fixed seed RNG. + let fixed_rng = &mut TestRng::from_seed(1); + + // Deploy a test program to the ledger. + let program = Program::::from_str(&format!( + " +program dummy_program_{x}.aleo; + +record dummy_program: + owner as address.private; + rand_var as u64.private; + +function create_duplicate_record: + input r0 as u64.private; + cast self.caller 1u64 into r1 as dummy_program.record; + output r1 as dummy_program.record;" + )) + .unwrap(); + + // Create a transaction with a fixed rng. + let transaction = ledger.vm.deploy(&private_key, &program, None, 0, None, fixed_rng).unwrap(); + + // Extract the deployment and owner. + let deployment = transaction.deployment().unwrap().clone(); + let owner = *transaction.owner().unwrap(); + + // Create a new fee for the execution. + let fee_authorization = ledger + .vm + .authorize_fee_private( + &private_key, + record_1.clone(), + *transaction.fee_amount().unwrap(), + 0, + deployment.to_deployment_id().unwrap(), + fixed_rng, + ) + .unwrap(); + let fee = ledger.vm.execute_fee_authorization(fee_authorization, None, fixed_rng).unwrap(); + + Transaction::from_deployment(owner, deployment, fee).unwrap() + }; + // Create the first transfer. - let transfer_1 = create_transaction_with_duplicate_output_id(1); + let transfer_1 = create_execution_with_duplicate_output_id(1); let transfer_1_id = transfer_1.id(); // Create a second transfer with the same output id. - let transfer_2 = create_transaction_with_duplicate_output_id(2); + let transfer_2 = create_execution_with_duplicate_output_id(2); let transfer_2_id = transfer_2.id(); // Create a third transfer with the same output id. - let transfer_3 = create_transaction_with_duplicate_output_id(3); + let transfer_3 = create_execution_with_duplicate_output_id(3); let transfer_3_id = transfer_3.id(); // Ensure that each transaction has a duplicate output id. @@ -853,9 +1266,34 @@ function create_duplicate_record: assert_eq!(tx_1_output_id, tx_2_output_id); assert_eq!(tx_1_output_id, tx_3_output_id); + // Create the first deployment. + let deployment_1 = create_deployment_with_duplicate_output_id(1); + let deployment_1_id = deployment_1.id(); + + // Create a second deployment with the same output id. + let deployment_2 = create_deployment_with_duplicate_output_id(2); + let deployment_2_id = deployment_2.id(); + + // Create a third deployment with the same output id. + let deployment_3 = create_deployment_with_duplicate_output_id(3); + let deployment_3_id = deployment_3.id(); + + // Ensure that each transaction has a duplicate output id. + let deployment_1_output_id = deployment_1.output_ids().next().unwrap(); + let deployment_2_output_id = deployment_2.output_ids().next().unwrap(); + let deployment_3_output_id = deployment_3.output_ids().next().unwrap(); + assert_eq!(deployment_1_output_id, deployment_2_output_id); + assert_eq!(deployment_1_output_id, deployment_3_output_id); + // Create a block. let block = ledger - .prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transfer_1, transfer_2], rng) + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + vec![], + vec![transfer_1, transfer_2, deployment_1, deployment_2], + rng, + ) .unwrap(); // Check that the next block is valid. @@ -865,9 +1303,16 @@ function create_duplicate_record: ledger.advance_to_next_block(&block).unwrap(); // Enforce that the block transactions were correct. - assert_eq!(block.transactions().num_accepted(), 1); - assert_eq!(block.transactions().transaction_ids().collect::>(), vec![&transfer_1_id]); - assert_eq!(block.aborted_transaction_ids(), &vec![transfer_2_id]); + assert_eq!(block.transactions().num_accepted(), 2); + assert_eq!(block.transactions().transaction_ids().collect::>(), vec![&transfer_1_id, &deployment_1_id]); + assert_eq!(block.aborted_transaction_ids(), &vec![transfer_2_id, deployment_2_id]); + + // Ensure that verification was not run on aborted deployments. + let partially_verified_transaction = ledger.vm().partially_verified_transactions().read().clone(); + assert!(partially_verified_transaction.contains(&transfer_1_id)); + assert!(partially_verified_transaction.contains(&deployment_1_id)); + assert!(!partially_verified_transaction.contains(&transfer_2_id)); + assert!(!partially_verified_transaction.contains(&deployment_2_id)); // Prepare a transfer that will succeed for the subsequent block. let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("1000u64").unwrap()]; @@ -879,7 +1324,13 @@ function create_duplicate_record: // Create a block. let block = ledger - .prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transfer_3, transfer_4], rng) + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + vec![], + vec![transfer_3, transfer_4, deployment_3], + rng, + ) .unwrap(); // Check that the next block is valid. @@ -891,7 +1342,13 @@ function create_duplicate_record: // Enforce that the block transactions were correct. assert_eq!(block.transactions().num_accepted(), 1); assert_eq!(block.transactions().transaction_ids().collect::>(), vec![&transfer_4_id]); - assert_eq!(block.aborted_transaction_ids(), &vec![transfer_3_id]); + assert_eq!(block.aborted_transaction_ids(), &vec![transfer_3_id, deployment_3_id]); + + // Ensure that verification was not run on transactions aborted in a previous block. + let partially_verified_transaction = ledger.vm().partially_verified_transactions().read().clone(); + assert!(partially_verified_transaction.contains(&transfer_4_id)); + assert!(!partially_verified_transaction.contains(&transfer_3_id)); + assert!(!partially_verified_transaction.contains(&deployment_3_id)); } #[test] @@ -926,7 +1383,10 @@ function empty_function: // Add the block to the ledger. ledger.advance_to_next_block(&block).unwrap(); - // Create a transaction with different transaction ids, but with a fixed transition id. + // Create a transaction with different transaction IDs, but with a fixed transition ID. + // NOTE: there's no use creating deployments with duplicate (fee) transition ids, + // as this is only possible if they have duplicate programs, duplicate transaction_ids, + // which will not abort but fail on check_next_block. let mut create_transaction_with_duplicate_transition_id = || -> Transaction { // Use a fixed seed RNG. let fixed_rng = &mut TestRng::from_seed(1); @@ -999,6 +1459,11 @@ function empty_function: assert_eq!(block.transactions().transaction_ids().collect::>(), vec![&transaction_1_id]); assert_eq!(block.aborted_transaction_ids(), &vec![transaction_2_id]); + // Ensure that verification was not run on aborted transactions. + let partially_verified_transaction = ledger.vm().partially_verified_transactions().read().clone(); + assert!(partially_verified_transaction.contains(&transaction_1_id)); + assert!(!partially_verified_transaction.contains(&transaction_2_id)); + // Prepare a transfer that will succeed for the subsequent block. let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("1000u64").unwrap()]; let transfer_transaction = ledger @@ -1028,6 +1493,11 @@ function empty_function: assert_eq!(block.transactions().num_accepted(), 1); assert_eq!(block.transactions().transaction_ids().collect::>(), vec![&transfer_transaction_id]); assert_eq!(block.aborted_transaction_ids(), &vec![transaction_3_id]); + + // Ensure that verification was not run on transactions aborted in a previous block. + let partially_verified_transaction = ledger.vm().partially_verified_transactions().read().clone(); + assert!(partially_verified_transaction.contains(&transfer_transaction_id)); + assert!(!partially_verified_transaction.contains(&transaction_3_id)); } #[test] @@ -1065,7 +1535,10 @@ function simple_output: // Add the block to the ledger. ledger.advance_to_next_block(&block).unwrap(); - // Create a transaction with different transaction ids, but with a TPK. + // Create a transaction with different transaction ids, but with a duplicate TPK. + // NOTE: there's no use creating deployments with duplicate (fee) TPKs, + // as this is only possible if they have duplicate programs, duplicate transaction_ids, + // which will not abort but fail on check_next_block. let mut create_transaction_with_duplicate_tpk = |function: &str| -> Transaction { // Use a fixed seed RNG. let fixed_rng = &mut TestRng::from_seed(1); @@ -1136,6 +1609,11 @@ function simple_output: assert_eq!(block.transactions().transaction_ids().collect::>(), vec![&transaction_1_id]); assert_eq!(block.aborted_transaction_ids(), &vec![transaction_2_id]); + // Ensure that verification was not run on aborted transactions. + let partially_verified_transaction = ledger.vm().partially_verified_transactions().read().clone(); + assert!(partially_verified_transaction.contains(&transaction_1_id)); + assert!(!partially_verified_transaction.contains(&transaction_2_id)); + // Prepare a transfer that will succeed for the subsequent block. let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("1000u64").unwrap()]; let transfer_transaction = ledger @@ -1165,57 +1643,46 @@ function simple_output: assert_eq!(block.transactions().num_accepted(), 1); assert_eq!(block.transactions().transaction_ids().collect::>(), vec![&transfer_transaction_id]); assert_eq!(block.aborted_transaction_ids(), &vec![transaction_3_id]); + + // Ensure that verification was not run on transactions aborted in a previous block. + let partially_verified_transaction = ledger.vm().partially_verified_transactions().read().clone(); + assert!(partially_verified_transaction.contains(&transfer_transaction_id)); + assert!(!partially_verified_transaction.contains(&transaction_3_id)); } #[test] -fn test_deployment_duplicate_program_id() { +fn test_abort_multiple_deployments_with_same_payer() { let rng = &mut TestRng::default(); // Initialize the test environment. let crate::test_helpers::TestEnv { ledger, private_key, .. } = crate::test_helpers::sample_test_env(rng); - // Create two programs with a duplicate program ID but different mappings + // Create two distinct programs let program_1 = Program::::from_str( - r" -program dummy_program.aleo; -mapping abcd1: - key as address.public; - value as u64.public; -function foo: - input r0 as u8.private; - async foo r0 into r1; - output r1 as dummy_program.aleo/foo.future; -finalize foo: - input r0 as u8.public; - add r0 r0 into r1;", + " +program dummy_program_1.aleo; + +function empty_function: + ", ) .unwrap(); let program_2 = Program::::from_str( - r" -program dummy_program.aleo; -mapping abcd2: - key as address.public; - value as u64.public; -function foo2: - input r0 as u8.private; - async foo2 r0 into r1; - output r1 as dummy_program.aleo/foo2.future; -finalize foo2: - input r0 as u8.public; - add r0 r0 into r1;", + " +program dummy_program_2.aleo; + +function empty_function: + ", ) .unwrap(); - // Create a deployment transaction for the first program. + // Create a deployment transaction for the first program with the same public payer. let deployment_1 = ledger.vm.deploy(&private_key, &program_1, None, 0, None, rng).unwrap(); let deployment_1_id = deployment_1.id(); - assert!(ledger.check_transaction_basic(&deployment_1, None, rng).is_ok()); - // Create a deployment transaction for the second program. + // Create a deployment transaction for the second program with the same public payer. let deployment_2 = ledger.vm.deploy(&private_key, &program_2, None, 0, None, rng).unwrap(); let deployment_2_id = deployment_2.id(); - assert!(ledger.check_transaction_basic(&deployment_2, None, rng).is_ok()); // Create a block. let block = ledger @@ -1230,27 +1697,1448 @@ finalize foo2: // Enforce that the block transactions were correct. assert_eq!(block.transactions().num_accepted(), 1); - assert_eq!(block.transactions().num_rejected(), 1); + assert_eq!(block.aborted_transaction_ids(), &vec![deployment_2_id]); - // Enforce that the first program was deployed and the second was rejected. + // Enforce that the first program was deployed and the second was aborted. assert_eq!(ledger.get_program(*program_1.id()).unwrap(), program_1); assert!(ledger.vm.transaction_store().contains_transaction_id(&deployment_1_id).unwrap()); assert!(ledger.vm.block_store().contains_rejected_or_aborted_transaction_id(&deployment_2_id).unwrap()); + + // Ensure that verification was not run on aborted transactions. + let partially_verified_transaction = ledger.vm().partially_verified_transactions().read().clone(); + assert!(partially_verified_transaction.contains(&deployment_1_id)); + assert!(!partially_verified_transaction.contains(&deployment_2_id)); } #[test] -fn test_split_candidate_solutions() { +fn test_abort_fee_transaction() { let rng = &mut TestRng::default(); - let max_solutions = CurrentNetwork::MAX_SOLUTIONS; - - const ITERATIONS: usize = 1_000; + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = crate::test_helpers::sample_test_env(rng); + + // Construct valid transaction for the ledger. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("1000u64").unwrap()]; + let transaction = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.clone().into_iter(), None, 0, None, rng) + .unwrap(); + let transaction_id = transaction.id(); + + // Convert a fee transaction. + let transaction_to_convert_to_fee = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.into_iter(), None, 0, None, rng) + .unwrap(); + let fee_transaction = Transaction::from_fee(transaction_to_convert_to_fee.fee_transition().unwrap()).unwrap(); + let fee_transaction_id = fee_transaction.id(); + + // Create a block using a fee transaction. + let block = ledger + .prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![fee_transaction, transaction], rng) + .unwrap(); + + // Check that the block aborts the invalid transaction. + assert_eq!(block.aborted_transaction_ids(), &vec![fee_transaction_id]); + assert_eq!(block.transaction_ids().collect::>(), vec![&transaction_id]); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Add the block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); +} + +#[test] +fn test_abort_invalid_transaction() { + let rng = &mut TestRng::default(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = crate::test_helpers::sample_test_env(rng); + + // Initialize a new VM. + let vm = sample_vm(); + + // Construct a custom genesis block. + let custom_genesis = vm.genesis_beacon(&private_key, rng).unwrap(); + + // Update the VM. + vm.add_next_block(&custom_genesis).unwrap(); + + // Generate a transaction that will be invalid on another network. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("1000u64").unwrap()]; + let invalid_transaction = vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.clone().into_iter(), None, 0, None, rng) + .unwrap(); + let invalid_transaction_id = invalid_transaction.id(); + + // Check that the ledger deems this transaction invalid. + assert!(ledger.check_transaction_basic(&invalid_transaction, None, rng).is_err()); + + // Construct valid transactions for the ledger. + let valid_transaction_1 = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.clone().into_iter(), None, 0, None, rng) + .unwrap(); + let valid_transaction_2 = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.into_iter(), None, 0, None, rng) + .unwrap(); + let valid_transaction_id_1 = valid_transaction_1.id(); + let valid_transaction_id_2 = valid_transaction_2.id(); + + // Create a block. + let block = ledger + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + vec![], + vec![valid_transaction_1, invalid_transaction, valid_transaction_2], + rng, + ) + .unwrap(); + + // Check that the block aborts the invalid transaction. + assert_eq!(block.aborted_transaction_ids(), &vec![invalid_transaction_id]); + assert_eq!(block.transaction_ids().collect::>(), vec![&valid_transaction_id_1, &valid_transaction_id_2]); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Add the block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); +} + +#[test] +fn test_deployment_duplicate_program_id() { + let rng = &mut TestRng::default(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, view_key, .. } = crate::test_helpers::sample_test_env(rng); + + // A helper function to find records. + let find_records = || { + let microcredits = Identifier::from_str("microcredits").unwrap(); + ledger + .find_records(&view_key, RecordsFilter::SlowUnspent(private_key)) + .unwrap() + .filter(|(_, record)| match record.data().get(µcredits) { + Some(Entry::Private(Plaintext::Literal(Literal::U64(amount), _))) => !amount.is_zero(), + _ => false, + }) + .collect::>() + }; + + // Fetch the unspent records. + let records = find_records(); + let record_1 = records[0].clone(); + let record_2 = records[1].clone(); + + // Create two programs with a duplicate program ID but different mappings + let program_1 = Program::::from_str( + r" +program dummy_program.aleo; +mapping abcd1: + key as address.public; + value as u64.public; +function foo: + input r0 as u8.private; + async foo r0 into r1; + output r1 as dummy_program.aleo/foo.future; +finalize foo: + input r0 as u8.public; + add r0 r0 into r1;", + ) + .unwrap(); + + let program_2 = Program::::from_str( + r" +program dummy_program.aleo; +mapping abcd2: + key as address.public; + value as u64.public; +function foo2: + input r0 as u8.private; + async foo2 r0 into r1; + output r1 as dummy_program.aleo/foo2.future; +finalize foo2: + input r0 as u8.public; + add r0 r0 into r1;", + ) + .unwrap(); + + // Create a deployment transaction for the first program. + let deployment_1 = ledger.vm.deploy(&private_key, &program_1, Some(record_1), 0, None, rng).unwrap(); + let deployment_1_id = deployment_1.id(); + assert!(ledger.check_transaction_basic(&deployment_1, None, rng).is_ok()); + + // Create a deployment transaction for the second program. + let deployment_2 = ledger.vm.deploy(&private_key, &program_2, Some(record_2), 0, None, rng).unwrap(); + let deployment_2_id = deployment_2.id(); + assert!(ledger.check_transaction_basic(&deployment_2, None, rng).is_ok()); + + // Create a block. + let block = ledger + .prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![deployment_1, deployment_2], rng) + .unwrap(); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Add the block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); + + // Enforce that the block transactions were correct. + assert_eq!(block.transactions().num_accepted(), 1); + assert_eq!(block.transactions().num_rejected(), 1); + + // Enforce that the first program was deployed and the second was rejected. + assert_eq!(ledger.get_program(*program_1.id()).unwrap(), program_1); + assert!(ledger.vm.transaction_store().contains_transaction_id(&deployment_1_id).unwrap()); + assert!(ledger.vm.block_store().contains_rejected_or_aborted_transaction_id(&deployment_2_id).unwrap()); +} + +#[test] +fn test_split_candidate_solutions() { + let rng = &mut TestRng::default(); + + let max_solutions = CurrentNetwork::MAX_SOLUTIONS; + + const ITERATIONS: usize = 1_000; for _ in 0..ITERATIONS { let num_candidates = rng.gen_range(0..max_solutions * 2); let candidate_solutions: Vec = rng.sample_iter(Standard).take(num_candidates).collect(); let (_accepted, _aborted) = - split_candidate_solutions(candidate_solutions, max_solutions, |candidate| candidate % 2 == 0); + split_candidate_solutions(candidate_solutions, max_solutions, |candidate| *candidate % 2 == 0); + } +} + +#[test] +fn test_max_committee_limit_with_bonds() { + // Initialize an RNG. + let rng = &mut TestRng::default(); + + // Initialize the VM. + let vm = sample_vm(); + + // Construct the validators, one less than the maximum committee size. + let validators = (0..Committee::::MAX_COMMITTEE_SIZE - 1) + .map(|_| { + let private_key = PrivateKey::::new(rng).unwrap(); + let amount = MIN_VALIDATOR_STAKE; + let is_open = true; + (private_key, (amount, is_open)) + }) + .collect::>(); + + // Track the allocated amount. + let mut allocated_amount = 0; + + // Construct the committee. + let mut committee_map = IndexMap::new(); + for (private_key, (amount, _)) in &validators { + let address = Address::try_from(private_key).unwrap(); + committee_map.insert(address, (*amount, true, 0)); + allocated_amount += *amount; + } + + // Initialize two new validators. + let first_private_key = PrivateKey::::new(rng).unwrap(); + let first_address = Address::try_from(&first_private_key).unwrap(); + let first_withdrawal_private_key = PrivateKey::::new(rng).unwrap(); + let first_withdrawal_address = Address::try_from(&first_withdrawal_private_key).unwrap(); + let second_private_key = PrivateKey::::new(rng).unwrap(); + let second_address = Address::try_from(&second_private_key).unwrap(); + let second_withdrawal_private_key = PrivateKey::::new(rng).unwrap(); + let second_withdrawal_address = Address::try_from(&second_withdrawal_private_key).unwrap(); + + // Construct the public balances, allocating the remaining supply to the first validator and two new validators. + // The remaining validators will have a balance of 0. + let mut public_balances = IndexMap::new(); + for (private_key, _) in &validators { + public_balances.insert(Address::try_from(private_key).unwrap(), 0); + } + let remaining_supply = ::STARTING_SUPPLY - allocated_amount; + let amount = remaining_supply / 5; + public_balances.insert(Address::try_from(validators.keys().next().unwrap()).unwrap(), amount); + public_balances.insert(first_address, amount); + public_balances.insert(first_withdrawal_address, amount); + public_balances.insert(second_address, amount); + public_balances.insert(second_withdrawal_address, remaining_supply - 4 * amount); + + // Construct the bonded balances. + let bonded_balances = validators + .iter() + .map(|(private_key, (amount, _))| { + let address = Address::try_from(private_key).unwrap(); + (address, (address, address, *amount)) + }) + .collect(); + + // Construct the genesis block, which should pass. + let genesis_block = vm + .genesis_quorum( + validators.keys().next().unwrap(), + Committee::new_genesis(committee_map).unwrap(), + public_balances, + bonded_balances, + rng, + ) + .unwrap(); + + // Initialize a Ledger from the genesis block. + let ledger = + Ledger::>::load(genesis_block, StorageMode::Production) + .unwrap(); + + // Bond the first validator. + let bond_first_transaction = ledger + .vm() + .execute( + &first_private_key, + ("credits.aleo", "bond_validator"), + vec![ + Value::::from_str(&first_withdrawal_address.to_string()).unwrap(), + Value::::from_str(&format!("{MIN_VALIDATOR_STAKE}u64")).unwrap(), + Value::::from_str("10u8").unwrap(), + ] + .iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Create a block. + let block = ledger + .prepare_advance_to_next_beacon_block( + validators.keys().next().unwrap(), + vec![], + vec![], + vec![bond_first_transaction], + rng, + ) + .unwrap(); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Check that the first validator is not in the committee. + let committee = ledger.latest_committee().unwrap(); + assert!(!committee.is_committee_member(first_address)); + + // Add the block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); + + // Check that the first validator was added to the committee. + let committee = ledger.latest_committee().unwrap(); + assert!(committee.is_committee_member(first_address)); + + // Attempt to bond the second validator. + let bond_second_transaction = ledger + .vm() + .execute( + &second_private_key, + ("credits.aleo", "bond_validator"), + vec![ + Value::::from_str(&second_withdrawal_address.to_string()).unwrap(), + Value::::from_str(&format!("{MIN_VALIDATOR_STAKE}u64")).unwrap(), + Value::::from_str("10u8").unwrap(), + ] + .iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Create a block. + let block = ledger + .prepare_advance_to_next_beacon_block( + validators.keys().next().unwrap(), + vec![], + vec![], + vec![bond_second_transaction], + rng, + ) + .unwrap(); + + // Ensure that the `bond_second_transaction` is rejected. + assert_eq!(block.transactions().num_rejected(), 1); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Check that the second validator is not in the committee. + let committee = ledger.latest_committee().unwrap(); + assert!(!committee.is_committee_member(second_address)); + + // Add the block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); + + // Check that the second validator was not added to the committee. + let committee = ledger.latest_committee().unwrap(); + assert!(!committee.is_committee_member(second_address)); + + // Check that unbonding a validator first allows the second validator to bond in. + + let unbond_first_validator = ledger + .vm() + .execute( + &first_withdrawal_private_key, + ("credits.aleo", "unbond_public"), + vec![ + Value::::from_str(&first_address.to_string()).unwrap(), + Value::::from_str(&format!("{MIN_VALIDATOR_STAKE}u64")).unwrap(), + ] + .iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Attempt to bond the second validator. + let bond_second_validator = ledger + .vm() + .execute( + &second_private_key, + ("credits.aleo", "bond_validator"), + vec![ + Value::::from_str(&second_withdrawal_address.to_string()).unwrap(), + Value::::from_str(&format!("{MIN_VALIDATOR_STAKE}u64")).unwrap(), + Value::::from_str("10u8").unwrap(), + ] + .iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Create a block. + let block = ledger + .prepare_advance_to_next_beacon_block( + validators.keys().next().unwrap(), + vec![], + vec![], + vec![unbond_first_validator, bond_second_validator], + rng, + ) + .unwrap(); + + // Ensure that no transactions are rejected. + assert_eq!(block.transactions().num_rejected(), 0); + assert_eq!(block.transactions().num_accepted(), 2); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Check that the first validator is in the committee and the second validator is not. + let committee = ledger.latest_committee().unwrap(); + assert!(!committee.is_committee_member(second_address)); + assert!(committee.is_committee_member(first_address)); + + // Add the block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); + + // Check that the first validator was removed and the second validator was added to the committee. + let committee = ledger.latest_committee().unwrap(); + assert!(committee.is_committee_member(second_address)); + assert!(!committee.is_committee_member(first_address)); +} + +#[test] +fn test_deployment_exceeding_max_transaction_spend() { + let rng = &mut TestRng::default(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, .. } = crate::test_helpers::sample_test_env(rng); + + // Construct two programs, one that is allowed and one that exceeds the maximum transaction spend. + let mut allowed_program = None; + let mut exceeding_program = None; + + for i in 0..::MAX_COMMANDS.ilog2() { + // Construct the finalize body. + let finalize_body = + (0..2.pow(i)).map(|i| format!("hash.bhp256 0field into r{i} as field;")).collect::>().join("\n"); + + // Construct the program. + let program = Program::from_str(&format!( + r"program test_max_spend_limit_{i}.aleo; + function foo: + async foo into r0; + output r0 as test_max_spend_limit_{i}.aleo/foo.future; + + finalize foo:{finalize_body}", + )) + .unwrap(); + + // Attempt to initialize a `Stack` for the program. + // If this fails, then by `Stack::initialize` the finalize cost exceeds the `TRANSACTION_SPEND_LIMIT`. + if Stack::::new(&ledger.vm().process().read(), &program).is_err() { + exceeding_program = Some(program); + break; + } else { + allowed_program = Some(program); + } + } + + // Ensure that the allowed and exceeding programs are not None. + assert!(allowed_program.is_some()); + assert!(exceeding_program.is_some()); + + let allowed_program = allowed_program.unwrap(); + let exceeding_program = exceeding_program.unwrap(); + + // Deploy the allowed program. + let deployment = ledger.vm().deploy(&private_key, &allowed_program, None, 0, None, rng).unwrap(); + + // Verify the deployment transaction. + assert!(ledger.vm().check_transaction(&deployment, None, rng).is_ok()); + + // Construct the next block. + let block = + ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![deployment], rng).unwrap(); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Add the block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); + + // Check that the program exists in the VM. + assert!(ledger.vm().contains_program(allowed_program.id())); + + // Attempt to deploy the exceeding program. + let result = ledger.vm().deploy(&private_key, &exceeding_program, None, 0, None, rng); + + // Check that the deployment failed. + assert!(result.is_err()); +} + +#[test] +fn test_transaction_ordering() { + let rng = &mut TestRng::default(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = crate::test_helpers::sample_test_env(rng); + + // Get the public balance of the address. + let mut public_balance = match ledger.genesis_block.ratifications().iter().next().unwrap() { + Ratify::Genesis(_, public_balance, _) => *public_balance.get(&address).unwrap(), + _ => panic!("Expected a genesis ratification"), + }; + + // Sample multiple private keys and addresses. + let private_key_2 = PrivateKey::::new(rng).unwrap(); + let address_2 = Address::try_from(&private_key_2).unwrap(); + let private_key_3 = PrivateKey::::new(rng).unwrap(); + let address_3 = Address::try_from(&private_key_3).unwrap(); + + // Fund a new address. + let amount_1 = 100000000u64; + let inputs = + [Value::from_str(&format!("{address_2}")).unwrap(), Value::from_str(&format!("{amount_1}u64")).unwrap()]; + let transfer_1 = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + + let amount_2 = 100000000u64; + let inputs = + [Value::from_str(&format!("{address_3}")).unwrap(), Value::from_str(&format!("{amount_2}u64")).unwrap()]; + let transfer_2 = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + + // Update the public balance. + public_balance -= *transfer_1.fee_amount().unwrap(); + public_balance -= *transfer_2.fee_amount().unwrap(); + + // Create a block. + let block = ledger + .prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transfer_1, transfer_2], rng) + .unwrap(); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Add the block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); + + // Create multiple dummy programs. + let program_1 = Program::::from_str( + r" +program dummy_program.aleo; +function foo: + input r0 as u8.private; + async foo r0 into r1; + output r1 as dummy_program.aleo/foo.future; +finalize foo: + input r0 as u8.public; + add r0 r0 into r1;", + ) + .unwrap(); + + let program_2 = Program::::from_str( + r" +program dummy_program_2.aleo; +function foo: + input r0 as u8.private; + async foo r0 into r1; + output r1 as dummy_program_2.aleo/foo.future; +finalize foo: + input r0 as u8.public; + add r0 r0 into r1;", + ) + .unwrap(); + + let program_3 = Program::::from_str( + r" +program dummy_program_3.aleo; +function foo: + input r0 as u8.private; + async foo r0 into r1; + output r1 as dummy_program_3.aleo/foo.future; +finalize foo: + input r0 as u8.public; + add r0 r0 into r1;", + ) + .unwrap(); + + // Create a transfer transaction. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("1000000u64").unwrap()]; + let initial_transfer = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + let initial_transfer_id = initial_transfer.id(); + + // Create a deployment transaction. + let deployment_transaction = ledger.vm.deploy(&private_key_2, &program_1, None, 0, None, rng).unwrap(); + + // Create a deployment transaction. + let deployment_transaction_2 = ledger.vm.deploy(&private_key_3, &program_2, None, 0, None, rng).unwrap(); + + // Create a transfer transaction. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("1000000u64").unwrap()]; + let transfer_transaction = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + + // Create a rejected transfer transaction. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("1000000000000000u64").unwrap()]; + let rejected_transfer = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + + // Create an aborted transfer transaction. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("10u64").unwrap()]; + let aborted_transfer = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, public_balance - 10, None, rng) + .unwrap(); + + // Create an aborted deployment transaction. + let aborted_deployment = ledger.vm.deploy(&private_key, &program_3, None, public_balance - 10, None, rng).unwrap(); + + const ITERATIONS: usize = 100; + for _ in 0..ITERATIONS { + // Create a random order for the transactions. + let mut transactions = vec![ + deployment_transaction.clone(), + deployment_transaction_2.clone(), + transfer_transaction.clone(), + rejected_transfer.clone(), + ]; + transactions.shuffle(rng); + + // Get the confirmed transaction IDs. + let mut confirmed_transaction_ids = transactions.iter().map(Transaction::id).collect::>(); + + // Randomly insert the aborted transactions. + let mut aborted_transactions = vec![aborted_transfer.clone(), aborted_deployment.clone()]; + aborted_transactions.shuffle(rng); + + // Randomly insert the aborted transactions. + let start_position = rng.gen_range(0..=transactions.len()); + for (index, element) in aborted_transactions.iter().enumerate() { + transactions.insert(start_position + index, element.clone()); + } + + // Get the aborted transaction IDs. + let aborted_transaction_ids = aborted_transactions.iter().map(Transaction::id).collect::>(); + + // Add the initial transfer to the list of transactions. + transactions.insert(0, initial_transfer.clone()); + confirmed_transaction_ids.insert(0, initial_transfer_id); + + // Create a block. + let block = + ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], transactions, rng).unwrap(); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Enforce that the block transactions were correct. + assert_eq!(block.transactions().num_accepted(), 4); + assert_eq!(block.transactions().num_rejected(), 1); + + // Enforce that the ordering of the transactions is correct. + let block_confirmed_transactions_ids: Vec<_> = block + .transactions() + .iter() + .map(|transaction| transaction.to_unconfirmed_transaction_id().unwrap()) + .collect(); + assert_eq!(block_confirmed_transactions_ids, confirmed_transaction_ids); + + // Enforce that the aborted transactions is correct. + assert_eq!(block.aborted_transaction_ids(), &aborted_transaction_ids); + } +} + +#[test] +fn test_metadata() { + let rng = &mut TestRng::default(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, .. } = crate::test_helpers::sample_test_env(rng); + + // Deploy a test program to the ledger. + let program_id = ProgramID::::from_str("metadata.aleo").unwrap(); + let program = Program::::from_str(&format!( + " +program {program_id}; +function is_block: + input r0 as u32.public; + async is_block r0 into r1; + output r1 as {program_id}/is_block.future; + +finalize is_block: + input r0 as u32.public; + assert.eq r0 block.height; + +function is_id: + input r0 as u16.public; + async is_id r0 into r1; + output r1 as {program_id}/is_id.future; + +finalize is_id: + input r0 as u16.public; + assert.eq r0 network.id; + ", + )) + .unwrap(); + + // Deploy. + let transaction = ledger.vm.deploy(&private_key, &program, None, 0, None, rng).unwrap(); + // Verify. + ledger.vm().check_transaction(&transaction, None, rng).unwrap(); + + // Construct the next block. + let block = + ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transaction], rng).unwrap(); + // Advance to the next block. + ledger.advance_to_next_block(&block).unwrap(); + assert_eq!(ledger.latest_height(), 1); + assert_eq!(ledger.latest_hash(), block.hash()); + assert_eq!(program, ledger.get_program(program_id).unwrap()); + + // Execute functions `is_block` and `is_id` to assert that the on-chain state is as expected. + let inputs_block: [Value; 1] = [Value::from_str("2u32").unwrap()]; + let tx_block = + ledger.vm.execute(&private_key, (&program_id, "is_block"), inputs_block.iter(), None, 0, None, rng).unwrap(); + let inputs_id: [Value; 1] = [Value::from(Literal::U16(U16::new(CurrentNetwork::ID)))]; + let tx_id = ledger.vm.execute(&private_key, (&program_id, "is_id"), inputs_id.iter(), None, 0, None, rng).unwrap(); + + // Construct the next block. + let block_2 = + ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![tx_id, tx_block], rng).unwrap(); + // Advance to the next block. + ledger.advance_to_next_block(&block_2).unwrap(); + + // Execute the program. + let inputs_block_2: [Value; 1] = [Value::from_str("3u32").unwrap()]; + let tx_block_2 = + ledger.vm.execute(&private_key, (&program_id, "is_block"), inputs_block_2.iter(), None, 0, None, rng).unwrap(); + let tx_id_2 = + ledger.vm.execute(&private_key, (&program_id, "is_id"), inputs_id.iter(), None, 0, None, rng).unwrap(); + + // Construct the next block. + let block_3 = ledger + .prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![tx_block_2, tx_id_2], rng) + .unwrap(); + // Advance to the next block. + ledger.advance_to_next_block(&block_3).unwrap(); +} + +#[test] +fn test_deployment_with_cast_from_field_to_scalar() { + // Initialize an RNG. + let rng = &mut TestRng::default(); + + const ITERATIONS: usize = 10; + + // Construct a program that casts a field to a scalar. + let program = Program::::from_str( + r" +program test_cast_field_to_scalar.aleo; +function foo: + input r0 as field.public; + cast r0 into r1 as scalar;", + ) + .unwrap(); + + // Constructs a program that has a struct with a field that is cast to a scalar. + let program_2 = Program::::from_str( + r" +program test_cast_f_to_s_struct.aleo; + +struct message: + first as scalar; + +function foo: + input r0 as field.public; + cast r0 into r1 as scalar; + cast r1 into r2 as message;", + ) + .unwrap(); + + // Constructs a program that has an array of scalars cast from fields. + let program_3 = Program::::from_str( + r" +program test_cast_f_to_s_array.aleo; + +function foo: + input r0 as field.public; + cast r0 into r1 as scalar; + cast r1 r1 r1 r1 into r2 as [scalar; 4u32];", + ) + .unwrap(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, .. } = crate::test_helpers::sample_test_env(rng); + + // Create a helper method to deploy the programs. + let deploy_program = |program: &Program, rng: &mut TestRng| { + let mut attempts = 0; + loop { + if attempts >= ITERATIONS { + panic!("Failed to craft deployment after {ITERATIONS} attempts"); + } + match try_vm_runtime!(|| ledger.vm().deploy(&private_key, program, None, 0, None, rng)) { + Ok(result) => break result.unwrap(), + Err(_) => attempts += 1, + } + } + }; + + // Deploy the programs. Keep attempting to create a deployment until it is successful. + let deployment_tx = deploy_program(&program, rng); + let deployment_tx_2 = deploy_program(&program_2, rng); + let deployment_tx_3 = deploy_program(&program_3, rng); + + // Verify the deployment under different RNGs to ensure the deployment is valid. + for _ in 0..ITERATIONS { + let process = ledger.vm().process().clone(); + // Create a helper method to verify the deployments. + let verify_deployment = |deployment_tx: &Transaction, rng: &mut TestRng| { + let expected_result = match try_vm_runtime!(|| ledger.vm().check_transaction(deployment_tx, None, rng)) { + Ok(result) => result.is_ok(), + Err(_) => false, + }; + let deployment = deployment_tx.deployment().unwrap().clone(); + for _ in 0..ITERATIONS { + let result = + match try_vm_runtime!(|| process.read().verify_deployment::(&deployment, rng)) { + Ok(result) => result.is_ok(), + Err(_) => false, + }; + assert_eq!(result, expected_result); + } + }; + + // Verify the deployments. + verify_deployment(&deployment_tx, rng); + verify_deployment(&deployment_tx_2, rng); + verify_deployment(&deployment_tx_3, rng); + } +} + +// These tests require the proof targets to be low enough to be able to generate **valid** solutions. +// This requires the 'test' feature to be enabled for the `console` dependency. +#[cfg(feature = "test")] +mod valid_solutions { + use super::*; + use ledger_puzzle::Solution; + use rand::prelude::SliceRandom; + use std::collections::HashSet; + + #[test] + fn test_duplicate_solution_ids() { + // Initialize an RNG. + let rng = &mut TestRng::default(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = + crate::test_helpers::sample_test_env(rng); + + // Retrieve the puzzle parameters. + let puzzle = ledger.puzzle(); + let latest_epoch_hash = ledger.latest_epoch_hash().unwrap(); + let minimum_proof_target = ledger.latest_proof_target(); + + // Create a solution that is greater than the minimum proof target. + let mut valid_solution = puzzle.prove(latest_epoch_hash, address, rng.gen(), None).unwrap(); + while puzzle.get_proof_target(&valid_solution).unwrap() < minimum_proof_target { + println!( + "Solution is invalid: {} < {}", + puzzle.get_proof_target(&valid_solution).unwrap(), + minimum_proof_target + ); + valid_solution = puzzle.prove(latest_epoch_hash, address, rng.gen(), None).unwrap(); + } + + // Create a valid transaction for the block. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("10u64").unwrap()]; + let transfer_transaction = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + + // Check that block creation fails when duplicate solution IDs are provided. + let result = ledger.prepare_advance_to_next_beacon_block( + &private_key, + vec![], + vec![valid_solution, valid_solution], + vec![transfer_transaction.clone()], + rng, + ); + assert!(result.is_err()); + + // Create a block. + let block = ledger + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + vec![valid_solution], + vec![transfer_transaction], + rng, + ) + .unwrap(); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Add the deployment block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); + + // Enforce that the block solution was accepted properly. + assert_eq!(block.solutions().len(), 1); + assert_eq!(block.aborted_solution_ids().len(), 0) + } + + #[test] + fn test_cumulative_proof_target_correctness() { + // The number of blocks to test. + const NUM_BLOCKS: u32 = 25; + + // Initialize an RNG. + let rng = &mut TestRng::default(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = + crate::test_helpers::sample_test_env(rng); + + // Retrieve the puzzle parameters. + let puzzle = ledger.puzzle(); + + // Initialize block height. + let mut block_height = ledger.latest_height(); + + // Start a local counter of proof targets. + let mut combined_targets = 0; + + // Run through 25 blocks of target adjustment. + while block_height < NUM_BLOCKS { + // Get coinbase puzzle data from the latest block. + let block = ledger.latest_block(); + let coinbase_target = block.coinbase_target(); + let coinbase_threshold = coinbase_target.saturating_div(2); + let latest_epoch_hash = ledger.latest_epoch_hash().unwrap(); + let latest_proof_target = ledger.latest_proof_target(); + + // Sample the number of solutions to generate. + let num_solutions = rng.gen_range(1..=CurrentNetwork::MAX_SOLUTIONS); + + // Initialize a vector for valid solutions for this block. + let mut solutions = Vec::with_capacity(num_solutions); + + // Loop through proofs until two that meet the threshold are found. + loop { + if let Ok(solution) = puzzle.prove(latest_epoch_hash, address, rng.gen(), Some(latest_proof_target)) { + // Get the proof target. + let proof_target = puzzle.get_proof_target(&solution).unwrap(); + + // Update the local combined target counter and store the solution. + combined_targets += proof_target; + solutions.push(solution); + + // If two have been found, exit the solver loop. + if solutions.len() >= num_solutions { + break; + } + } + } + + // If the combined target exceeds the coinbase threshold reset it. + if combined_targets >= coinbase_threshold { + combined_targets = 0; + } + + // Get a transfer transaction to ensure solutions can be included in the block. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("10u64").unwrap()]; + let transfer_transaction = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + + // Generate the next prospective block. + let next_block = ledger + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + solutions, + vec![transfer_transaction.clone()], + rng, + ) + .unwrap(); + + // Ensure the combined target matches the expected value. + assert_eq!(combined_targets as u128, next_block.cumulative_proof_target()); + + // Ensure the next block is correct. + ledger.check_next_block(&next_block, rng).unwrap(); + + // Advanced to the next block. + ledger.advance_to_next_block(&next_block).unwrap(); + + // Set the latest block height. + block_height = ledger.latest_height(); + } + } + + #[test] + fn test_excess_invalid_solution_ids() { + // Note that the sum of `NUM_INVALID_SOLUTIONS` and `NUM_VALID_SOLUTIONS` should exceed the maximum number of solutions. + const NUM_INVALID_SOLUTIONS: usize = CurrentNetwork::MAX_SOLUTIONS; + const NUM_VALID_SOLUTIONS: usize = CurrentNetwork::MAX_SOLUTIONS; + + // Initialize an RNG. + let rng = &mut TestRng::default(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = + crate::test_helpers::sample_test_env(rng); + + // Retrieve the puzzle parameters. + let puzzle = ledger.puzzle(); + let latest_epoch_hash = ledger.latest_epoch_hash().unwrap(); + let minimum_proof_target = ledger.latest_proof_target(); + + // Initialize storage for the valid and invalid solutions + let mut valid_solutions = Vec::with_capacity(NUM_VALID_SOLUTIONS); + let mut invalid_solutions = Vec::with_capacity(NUM_INVALID_SOLUTIONS); + + // Create solutions that are greater than the minimum proof target. + while valid_solutions.len() < NUM_VALID_SOLUTIONS { + let solution = puzzle.prove(latest_epoch_hash, address, rng.gen(), None).unwrap(); + if puzzle.get_proof_target(&solution).unwrap() < minimum_proof_target { + if invalid_solutions.len() < NUM_INVALID_SOLUTIONS { + invalid_solutions.push(solution); + } + } else { + valid_solutions.push(solution); + } + } + // Create the remaining solutions that are less than the minimum proof target. + while invalid_solutions.len() < NUM_INVALID_SOLUTIONS { + let solution = puzzle.prove(latest_epoch_hash, address, rng.gen(), None).unwrap(); + if puzzle.get_proof_target(&solution).unwrap() < minimum_proof_target { + invalid_solutions.push(solution); + } + } + + // Check the length of the valid and invalid solutions. + assert_eq!(valid_solutions.len(), NUM_VALID_SOLUTIONS); + assert_eq!(invalid_solutions.len(), NUM_INVALID_SOLUTIONS); + + // Concatenate and shuffle the solutions. + let mut candidate_solutions = valid_solutions.clone(); + candidate_solutions.extend(invalid_solutions.clone()); + candidate_solutions.shuffle(rng); + + // Create a valid transaction for the block. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("10u64").unwrap()]; + let transfer_transaction = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + + // Create a block. + let block = ledger + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + candidate_solutions, + vec![transfer_transaction], + rng, + ) + .unwrap(); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Add the deployment block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); + + // Check that the block's solutions are well-formed. + assert_eq!(block.aborted_solution_ids().len(), NUM_INVALID_SOLUTIONS); + assert_eq!(block.solutions().len(), NUM_VALID_SOLUTIONS); + + let block_solutions = block.solutions().solution_ids().cloned().collect::>(); + let valid_solutions = valid_solutions.iter().map(|s| s.id()).collect::>(); + assert_eq!(block_solutions, valid_solutions, "Valid solutions do not match"); + + let block_aborted_solution_ids = block.aborted_solution_ids().iter().cloned().collect::>(); + let invalid_solutions = invalid_solutions.iter().map(|s| s.id()).collect::>(); + assert_eq!(block_aborted_solution_ids, invalid_solutions, "Invalid solutions do not match"); + } + + #[test] + fn test_excess_valid_solution_ids() { + // Note that this should be greater than the maximum number of solutions. + const NUM_VALID_SOLUTIONS: usize = 2 * CurrentNetwork::MAX_SOLUTIONS; + + // Initialize an RNG. + let rng = &mut TestRng::default(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = + crate::test_helpers::sample_test_env(rng); + + // Retrieve the puzzle parameters. + let puzzle = ledger.puzzle(); + let latest_epoch_hash = ledger.latest_epoch_hash().unwrap(); + let minimum_proof_target = ledger.latest_proof_target(); + + // Initialize storage for the valid solutions + let mut valid_solutions = Vec::with_capacity(NUM_VALID_SOLUTIONS); + + // Create solutions that are greater than the minimum proof target. + while valid_solutions.len() < NUM_VALID_SOLUTIONS { + let solution = puzzle.prove(latest_epoch_hash, address, rng.gen(), None).unwrap(); + if puzzle.get_proof_target(&solution).unwrap() >= minimum_proof_target { + valid_solutions.push(solution); + } + } + + // Check the length of the valid solutions. + assert_eq!(valid_solutions.len(), NUM_VALID_SOLUTIONS); + + // Shuffle the solutions. + let mut candidate_solutions = valid_solutions; + candidate_solutions.shuffle(rng); + + // Create a valid transaction for the block. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("10u64").unwrap()]; + let transfer_transaction = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + + // Create a block. + let block = ledger + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + candidate_solutions.clone(), + vec![transfer_transaction], + rng, + ) + .unwrap(); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Add the deployment block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); + + // Check that the block's solutions are well-formed. + assert_eq!(block.solutions().len(), CurrentNetwork::MAX_SOLUTIONS); + assert_eq!(block.aborted_solution_ids().len(), NUM_VALID_SOLUTIONS - CurrentNetwork::MAX_SOLUTIONS); + + let block_solutions = block.solutions().solution_ids().cloned().collect::>(); + let expected_accepted_solutions = + candidate_solutions.iter().take(CurrentNetwork::MAX_SOLUTIONS).map(|s| s.id()).collect::>(); + assert_eq!(block_solutions, expected_accepted_solutions, "Accepted solutions do not match"); + + let block_aborted_solution_ids = block.aborted_solution_ids().iter().cloned().collect::>(); + let expected_aborted_solutions = + candidate_solutions.iter().skip(CurrentNetwork::MAX_SOLUTIONS).map(|s| s.id()).collect::>(); + assert_eq!(block_aborted_solution_ids, expected_aborted_solutions, "Aborted solutions do not match"); + } + + #[test] + fn test_malicious_solution() { + // Initialize an RNG. + let rng = &mut TestRng::default(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = + crate::test_helpers::sample_test_env(rng); + + // Retrieve the puzzle parameters. + let puzzle = ledger.puzzle(); + let latest_epoch_hash = ledger.latest_epoch_hash().unwrap(); + let minimum_proof_target = ledger.latest_proof_target(); + + // Initialize a valid solution object. + let mut valid_solution = None; + while valid_solution.is_none() { + let solution = puzzle.prove(latest_epoch_hash, address, rng.gen(), None).unwrap(); + if puzzle.get_proof_target(&solution).unwrap() >= minimum_proof_target { + valid_solution = Some(solution); + } + } + // Unwrap the valid solution. + let valid_solution = valid_solution.unwrap(); + + // Construct a malicious solution with a different target. + let different_target = valid_solution.target().wrapping_sub(1); + let malicious_solution = Solution::new(*valid_solution.partial_solution(), different_target); + + assert_eq!( + valid_solution.id(), + malicious_solution.id(), + "The malicious solution should have the same ID as the valid solution" + ); + assert_ne!( + valid_solution.target(), + malicious_solution.target(), + "The malicious solution should have a different target than the valid solution" + ); + + // Create a valid transaction for the block. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("10u64").unwrap()]; + let transfer_transaction = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + + // Check that the block creation fixes the malformed solution. + let expected_solution_id = valid_solution.id(); + let expected_solution = valid_solution; + let mut check_block = |candidate_solutions: Vec>| { + // Create a block. + let block = ledger + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + candidate_solutions.clone(), + vec![transfer_transaction.clone()], + rng, + ) + .unwrap(); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Check that the block's solutions are well-formed. + assert_eq!(block.solutions().len(), 1); + assert_eq!(block.aborted_solution_ids().len(), 0); + + // Fetch the solution from the block. + let (solution_id, solution) = block.solutions().as_ref().unwrap().first().unwrap(); + assert_eq!(*solution_id, expected_solution_id, "Check that the block has the correct solution ID"); + assert_eq!(*solution, expected_solution, "Check that the block has the correct solution"); + }; + + // Case 1: The malicious solution is included in the block construction. + let candidate_solutions = vec![malicious_solution]; + check_block(candidate_solutions); + + // Case 2: The valid solution is included in the block construction. + let candidate_solutions = vec![valid_solution]; + check_block(candidate_solutions); + } + + #[test] + fn test_solution_with_insufficient_target() { + // Initialize an RNG. + let rng = &mut TestRng::default(); + + // Initialize the test environment. + let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = + crate::test_helpers::sample_test_env(rng); + + // Retrieve the puzzle parameters. + let puzzle = ledger.puzzle(); + let latest_epoch_hash = ledger.latest_epoch_hash().unwrap(); + let minimum_proof_target = ledger.latest_proof_target(); + + // Initialize a valid solution object. + let mut invalid_solution = None; + while invalid_solution.is_none() { + let solution = puzzle.prove(latest_epoch_hash, address, rng.gen(), None).unwrap(); + if puzzle.get_proof_target(&solution).unwrap() < minimum_proof_target { + invalid_solution = Some(solution); + } + } + // Unwrap the invalid solution. + let invalid_solution = invalid_solution.unwrap(); + + // Create a valid transaction for the block. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("10u64").unwrap()]; + let transfer_transaction = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + + // Create a block. + let block = ledger + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + vec![invalid_solution], + vec![transfer_transaction], + rng, + ) + .unwrap(); + + // Check that the next block is valid. + ledger.check_next_block(&block, rng).unwrap(); + + // Add the deployment block to the ledger. + ledger.advance_to_next_block(&block).unwrap(); + + // Check that the block's solutions are well-formed. + assert_eq!(block.solutions().len(), 0); + assert_eq!(block.aborted_solution_ids().len(), 1); + + // Check that the aborted solution is correct. + let block_aborted_solution_id = block.aborted_solution_ids().first().unwrap(); + assert_eq!(*block_aborted_solution_id, invalid_solution.id(), "Aborted solutions do not match"); + } +} + +#[test] +fn test_forged_block_subdags() { + let rng = &mut TestRng::default(); + + // Sample the genesis private key. + let private_key = PrivateKey::::new(rng).unwrap(); + // Initialize the store. + let store = ConsensusStore::<_, ConsensusMemory<_>>::open(None).unwrap(); + // Create a genesis block with a seeded RNG to reproduce the same genesis private keys. + let seed: u64 = rng.gen(); + let genesis_rng = &mut TestRng::from_seed(seed); + let genesis = VM::from(store).unwrap().genesis_beacon(&private_key, genesis_rng).unwrap(); + + // Extract the private keys from the genesis committee by using the same RNG to sample private keys. + let genesis_rng = &mut TestRng::from_seed(seed); + let private_keys = [ + private_key, + PrivateKey::new(genesis_rng).unwrap(), + PrivateKey::new(genesis_rng).unwrap(), + PrivateKey::new(genesis_rng).unwrap(), + ]; + + // Construct 3 quorum blocks. + let mut quorum_blocks = construct_quorum_blocks(private_keys.to_vec(), genesis.clone(), 3, rng); + + // Extract the individual blocks. + let block_1 = quorum_blocks.remove(0); + let block_2 = quorum_blocks.remove(0); + let block_3 = quorum_blocks.remove(0); + + // Construct the ledger. + let ledger = + Ledger::>::load(genesis, StorageMode::Production).unwrap(); + ledger.advance_to_next_block(&block_1).unwrap(); + ledger.check_next_block(&block_2, rng).unwrap(); + + //////////////////////////////////////////////////////////////////////////// + // Attack 1: Forge block 2' with the subdag of block 3. + //////////////////////////////////////////////////////////////////////////// + { + let block_3_subdag = + if let Authority::Quorum(subdag) = block_3.authority() { subdag } else { unreachable!("") }; + + // Fetch the transmissions. + let transmissions = extract_transmissions(&block_3); + + // Forge the block. + let forged_block_2 = ledger + .prepare_advance_to_next_quorum_block(block_3_subdag.clone(), transmissions, &mut rand::thread_rng()) + .unwrap(); + + assert_ne!(forged_block_2, block_2); + + // Attempt to verify the forged block. + assert!(ledger.check_next_block(&forged_block_2, &mut rand::thread_rng()).is_err()); + } + + //////////////////////////////////////////////////////////////////////////// + // Attack 2: Forge block 2' with the combined subdag of block 2 and 3. + //////////////////////////////////////////////////////////////////////////// + { + // Fetch the subdags. + let block_2_subdag = + if let Authority::Quorum(subdag) = block_2.authority() { subdag } else { unreachable!("") }; + let block_3_subdag = + if let Authority::Quorum(subdag) = block_3.authority() { subdag } else { unreachable!("") }; + + // Combined the subdags. + let mut combined_subdag = block_2_subdag.deref().clone(); + for (round, certificates) in block_3_subdag.iter() { + combined_subdag + .entry(*round) + .and_modify(|c| c.extend(certificates.clone())) + .or_insert(certificates.clone()); + } + + // Fetch the transmissions. + let block_2_transmissions = extract_transmissions(&block_2); + let block_3_transmissions = extract_transmissions(&block_3); + + // Combine the transmissions. + let mut combined_transmissions = block_2_transmissions; + combined_transmissions.extend(block_3_transmissions); + + // Forge the block. + let forged_block_2_from_both_subdags = ledger + .prepare_advance_to_next_quorum_block( + Subdag::from(combined_subdag).unwrap(), + combined_transmissions, + &mut rand::thread_rng(), + ) + .unwrap(); + + assert_ne!(forged_block_2_from_both_subdags, block_1); + + // Attempt to verify the forged block. + assert!(ledger.check_next_block(&forged_block_2_from_both_subdags, &mut rand::thread_rng()).is_err()); } } diff --git a/ledger/store/Cargo.toml b/ledger/store/Cargo.toml index 2491a5ae1b..0b9d22a7a3 100644 --- a/ledger/store/Cargo.toml +++ b/ledger/store/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-store" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A data store for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -18,11 +18,11 @@ edition = "2021" [features] default = [ "indexmap/rayon", "rayon" ] -rocks = [ "once_cell", "rocksdb", "tracing" ] +rocks = [ "once_cell", "rocksdb", "smallvec", "tracing" ] serial = [ "console/serial", "ledger-block/serial", - "ledger-coinbase/serial", + "ledger-puzzle/serial", "ledger-committee/serial", "synthesizer-program/serial", "synthesizer-snark/serial" @@ -31,7 +31,7 @@ wasm = [ "console/wasm", "ledger-authority/wasm", "ledger-block/wasm", - "ledger-coinbase/wasm", + "ledger-puzzle/wasm", "ledger-committee/wasm", "ledger-narwhal-batch-certificate/wasm", "synthesizer-program/wasm", @@ -42,42 +42,42 @@ test = [ ] [dependencies.console] package = "snarkvm-console" path = "../../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-authority] package = "snarkvm-ledger-authority" path = "../authority" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-block] package = "snarkvm-ledger-block" path = "../block" -version = "=0.16.19" - -[dependencies.ledger-coinbase] -package = "snarkvm-ledger-coinbase" -path = "../coinbase" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-committee] package = "snarkvm-ledger-committee" path = "../committee" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-narwhal-batch-certificate] package = "snarkvm-ledger-narwhal-batch-certificate" path = "../narwhal/batch-certificate" -version = "=0.16.19" +version = "=1.1.0" + +[dependencies.ledger-puzzle] +package = "snarkvm-ledger-puzzle" +path = "../puzzle" +version = "=1.1.0" [dependencies.synthesizer-program] package = "snarkvm-synthesizer-program" path = "../../synthesizer/program" -version = "=0.16.19" +version = "=1.1.0" [dependencies.synthesizer-snark] package = "snarkvm-synthesizer-snark" path = "../../synthesizer/snark" -version = "=0.16.19" +version = "=1.1.0" [dependencies.aleo-std-storage] version = "0.1.7" @@ -113,6 +113,16 @@ optional = true [dependencies.serde] version = "1.0" +[dependencies.serde_json] +version = "1.0" +features = [ "preserve_order" ] + +[dependencies.smallvec] +version = "1.11" +default-features = false +features = [ "write" ] +optional = true + [dependencies.tracing] version = "0.1" optional = true diff --git a/ledger/store/src/block/confirmed_tx_type/bytes.rs b/ledger/store/src/block/confirmed_tx_type/bytes.rs new file mode 100644 index 0000000000..beba8a7d92 --- /dev/null +++ b/ledger/store/src/block/confirmed_tx_type/bytes.rs @@ -0,0 +1,83 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl FromBytes for ConfirmedTxType { + /// Reads the confirmed transaction type from the buffer. + fn read_le(mut reader: R) -> IoResult { + // Read the variant. + let variant = u8::read_le(&mut reader)?; + // Match the variant. + match variant { + 0 => Ok(Self::AcceptedDeploy(u32::read_le(&mut reader)?)), + 1 => Ok(Self::AcceptedExecute(u32::read_le(&mut reader)?)), + 2 => Ok(Self::RejectedDeploy(u32::read_le(&mut reader)?, Rejected::read_le(&mut reader)?)), + 3 => Ok(Self::RejectedExecute(u32::read_le(&mut reader)?, Rejected::read_le(&mut reader)?)), + 4.. => Err(error("Invalid confirmed transaction type variant")), + } + } +} + +impl ToBytes for ConfirmedTxType { + /// Writes the confirmed transaction type to the buffer. + fn write_le(&self, mut writer: W) -> IoResult<()> { + // Write the confirmed transaction type. + match self { + Self::AcceptedDeploy(index) => { + // Write the variant. + 0u8.write_le(&mut writer)?; + // Write the index. + index.write_le(&mut writer) + } + Self::AcceptedExecute(index) => { + // Write the variant. + 1u8.write_le(&mut writer)?; + // Write the index. + index.write_le(&mut writer) + } + Self::RejectedDeploy(index, rejected) => { + // Write the variant. + 2u8.write_le(&mut writer)?; + // Write the index. + index.write_le(&mut writer)?; + // Write the rejected transaction. + rejected.write_le(&mut writer) + } + Self::RejectedExecute(index, rejected) => { + // Write the variant. + 3u8.write_le(&mut writer)?; + // Write the index. + index.write_le(&mut writer)?; + // Write the rejected transaction. + rejected.write_le(&mut writer) + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_bytes() { + for expected in crate::confirmed_tx_type::test_helpers::sample_confirmed_tx_types() { + // Check the byte representation. + let expected_bytes = expected.to_bytes_le().unwrap(); + assert_eq!(expected, ConfirmedTxType::read_le(&expected_bytes[..]).unwrap()); + } + } +} diff --git a/ledger/store/src/block/confirmed_tx_type/mod.rs b/ledger/store/src/block/confirmed_tx_type/mod.rs new file mode 100644 index 0000000000..2eb71a707d --- /dev/null +++ b/ledger/store/src/block/confirmed_tx_type/mod.rs @@ -0,0 +1,80 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +mod bytes; +mod serialize; +mod string; + +use super::*; + +#[derive(Clone, PartialEq, Eq)] +pub enum ConfirmedTxType { + /// A deploy transaction that was accepted. + AcceptedDeploy(u32), + /// An execute transaction that was accepted. + AcceptedExecute(u32), + /// A deploy transaction that was rejected. + RejectedDeploy(u32, Rejected), + /// An execute transaction that was rejected. + RejectedExecute(u32, Rejected), +} + +#[cfg(test)] +pub mod test_helpers { + use super::*; + use console::network::MainnetV0; + + type CurrentNetwork = MainnetV0; + + /// Samples an accepted deploy. + pub(crate) fn sample_accepted_deploy(rng: &mut TestRng) -> ConfirmedTxType { + // Return the accepted deploy. + ConfirmedTxType::AcceptedDeploy(rng.gen()) + } + + /// Samples an accepted execution. + pub(crate) fn sample_accepted_execution(rng: &mut TestRng) -> ConfirmedTxType { + // Return the accepted execution. + ConfirmedTxType::AcceptedExecute(rng.gen()) + } + + /// Samples a rejected deploy. + pub(crate) fn sample_rejected_deploy(rng: &mut TestRng) -> ConfirmedTxType { + // Sample the rejected deployment. + let rejected = ledger_test_helpers::sample_rejected_deployment(rng.gen(), rng); + // Return the rejected deploy. + ConfirmedTxType::RejectedDeploy(rng.gen(), rejected) + } + + /// Samples a rejected execution. + pub(crate) fn sample_rejected_execute(rng: &mut TestRng) -> ConfirmedTxType { + // Sample the rejected execution. + let rejected = ledger_test_helpers::sample_rejected_execution(rng.gen(), rng); + // Return the rejected execution. + ConfirmedTxType::RejectedExecute(rng.gen(), rejected) + } + + /// Sample a list of randomly rejected transactions. + pub(crate) fn sample_confirmed_tx_types() -> Vec> { + let rng = &mut TestRng::default(); + + vec![ + sample_accepted_deploy(rng), + sample_accepted_execution(rng), + sample_rejected_deploy(rng), + sample_rejected_execute(rng), + ] + } +} diff --git a/ledger/store/src/block/confirmed_tx_type/serialize.rs b/ledger/store/src/block/confirmed_tx_type/serialize.rs new file mode 100644 index 0000000000..1e29e74732 --- /dev/null +++ b/ledger/store/src/block/confirmed_tx_type/serialize.rs @@ -0,0 +1,148 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl Serialize for ConfirmedTxType { + #[inline] + fn serialize(&self, serializer: S) -> Result { + match serializer.is_human_readable() { + true => match self { + Self::AcceptedDeploy(index) => { + let mut confirmed_tx_type = serializer.serialize_struct("ConfirmedTxType", 2)?; + confirmed_tx_type.serialize_field("type", "AcceptedDeploy")?; + confirmed_tx_type.serialize_field("index", index)?; + confirmed_tx_type.end() + } + Self::AcceptedExecute(index) => { + let mut confirmed_tx_type = serializer.serialize_struct("ConfirmedTxType", 2)?; + confirmed_tx_type.serialize_field("type", "AcceptedExecute")?; + confirmed_tx_type.serialize_field("index", index)?; + confirmed_tx_type.end() + } + Self::RejectedDeploy(index, rejected) => { + let mut confirmed_tx_type = serializer.serialize_struct("ConfirmedTxType", 3)?; + confirmed_tx_type.serialize_field("type", "RejectedDeploy")?; + confirmed_tx_type.serialize_field("index", index)?; + confirmed_tx_type.serialize_field("rejected", rejected)?; + confirmed_tx_type.end() + } + Self::RejectedExecute(index, rejected) => { + let mut confirmed_tx_type = serializer.serialize_struct("ConfirmedTxType", 3)?; + confirmed_tx_type.serialize_field("type", "RejectedExecute")?; + confirmed_tx_type.serialize_field("index", index)?; + confirmed_tx_type.serialize_field("rejected", rejected)?; + confirmed_tx_type.end() + } + }, + false => ToBytesSerializer::serialize_with_size_encoding(self, serializer), + } + } +} + +impl<'de, N: Network> Deserialize<'de> for ConfirmedTxType { + #[inline] + fn deserialize>(deserializer: D) -> Result { + match deserializer.is_human_readable() { + true => { + let mut confirmed_tx_type = serde_json::Value::deserialize(deserializer)?; + let type_: String = DeserializeExt::take_from_value::(&mut confirmed_tx_type, "type")?; + + // Recover the confirmed transaction type. + match type_.as_str() { + "AcceptedDeploy" => Ok(Self::AcceptedDeploy( + DeserializeExt::take_from_value::(&mut confirmed_tx_type, "index") + .map_err(de::Error::custom)?, + )), + "AcceptedExecute" => Ok(Self::AcceptedExecute( + DeserializeExt::take_from_value::(&mut confirmed_tx_type, "index") + .map_err(de::Error::custom)?, + )), + "RejectedDeploy" => { + let index = DeserializeExt::take_from_value::(&mut confirmed_tx_type, "index") + .map_err(de::Error::custom)?; + let rejected = DeserializeExt::take_from_value::(&mut confirmed_tx_type, "rejected") + .map_err(de::Error::custom)?; + Ok(Self::RejectedDeploy(index, rejected)) + } + "RejectedExecute" => { + let index = DeserializeExt::take_from_value::(&mut confirmed_tx_type, "index") + .map_err(de::Error::custom)?; + let rejected = DeserializeExt::take_from_value::(&mut confirmed_tx_type, "rejected") + .map_err(de::Error::custom)?; + Ok(Self::RejectedExecute(index, rejected)) + } + _ => Err(de::Error::custom(error("Invalid confirmed transaction type"))), + } + } + false => FromBytesDeserializer::::deserialize_with_size_encoding( + deserializer, + "confirmed transaction type", + ), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn check_serde_json< + T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes, + >( + expected: T, + ) { + // Serialize + let expected_string = expected.to_string(); + let candidate_string = serde_json::to_string(&expected).unwrap(); + let candidate = serde_json::from_str::(&candidate_string).unwrap(); + assert_eq!(expected, candidate); + assert_eq!(expected_string, candidate_string); + assert_eq!(expected_string, candidate.to_string()); + + // Deserialize + assert_eq!(expected, T::from_str(&expected_string).unwrap_or_else(|_| panic!("FromStr: {expected_string}"))); + assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap()); + } + + fn check_bincode< + T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes, + >( + expected: T, + ) { + // Serialize + let expected_bytes = expected.to_bytes_le().unwrap(); + let expected_bytes_with_size_encoding = bincode::serialize(&expected).unwrap(); + assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]); + + // Deserialize + assert_eq!(expected, T::read_le(&expected_bytes[..]).unwrap()); + assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..]).unwrap()); + } + + #[test] + fn test_serde_json() { + for rejected in crate::confirmed_tx_type::test_helpers::sample_confirmed_tx_types() { + check_serde_json(rejected); + } + } + + #[test] + fn test_bincode() { + for rejected in crate::confirmed_tx_type::test_helpers::sample_confirmed_tx_types() { + check_bincode(rejected); + } + } +} diff --git a/ledger/store/src/block/confirmed_tx_type/string.rs b/ledger/store/src/block/confirmed_tx_type/string.rs new file mode 100644 index 0000000000..d00c2f3f25 --- /dev/null +++ b/ledger/store/src/block/confirmed_tx_type/string.rs @@ -0,0 +1,39 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl FromStr for ConfirmedTxType { + type Err = Error; + + /// Initializes the confirmed transaction type- from a JSON-string. + fn from_str(status: &str) -> Result { + Ok(serde_json::from_str(status)?) + } +} + +impl Debug for ConfirmedTxType { + /// Prints the confirmed transaction type as a JSON-string. + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(self, f) + } +} + +impl Display for ConfirmedTxType { + /// Displays the confirmed transaction type as a JSON-string. + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{}", serde_json::to_string(self).map_err::(ser::Error::custom)?) + } +} diff --git a/ledger/store/src/block/mod.rs b/ledger/store/src/block/mod.rs index 5ee1c5e467..88ed88b169 100644 --- a/ledger/store/src/block/mod.rs +++ b/ledger/store/src/block/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,15 +13,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +pub mod confirmed_tx_type; +pub use confirmed_tx_type::*; + use crate::{ - atomic_batch_scope, - cow_to_cloned, - cow_to_copied, - helpers::{Map, MapRead}, TransactionStorage, TransactionStore, TransitionStorage, TransitionStore, + atomic_batch_scope, + cow_to_cloned, + cow_to_copied, + helpers::{Map, MapRead}, }; use console::{ network::prelude::*, @@ -32,138 +36,70 @@ use ledger_block::{ Block, ConfirmedTransaction, Header, - NumFinalizeSize, Ratifications, Rejected, + Solutions, Transaction, Transactions, }; -use ledger_coinbase::{CoinbaseSolution, ProverSolution, PuzzleCommitment}; use ledger_narwhal_batch_certificate::BatchCertificate; -use synthesizer_program::Program; +use ledger_puzzle::{Solution, SolutionID}; +use synthesizer_program::{FinalizeOperation, Program}; use aleo_std_storage::StorageMode; use anyhow::Result; use parking_lot::RwLock; -use std::{borrow::Cow, io::Cursor, sync::Arc}; +use std::{borrow::Cow, sync::Arc}; #[cfg(not(feature = "serial"))] use rayon::prelude::*; -#[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub enum ConfirmedTxType { - /// A deploy transaction that was accepted. - AcceptedDeploy(u32), - /// An execute transaction that was accepted. - AcceptedExecute(u32), - /// A deploy transaction that was rejected. - RejectedDeploy(u32), - /// An execute transaction that was rejected. - RejectedExecute(u32), -} - /// Separates the confirmed transaction into a tuple. #[allow(clippy::type_complexity)] fn to_confirmed_tuple( confirmed: ConfirmedTransaction, -) -> Result<(ConfirmedTxType, Transaction, Vec, Option>)> { +) -> Result<(ConfirmedTxType, Transaction, Vec>)> { match confirmed { - ConfirmedTransaction::AcceptedDeploy(index, tx, finalize) => { - // Retrieve the number of finalize operations. - let num_finalize = NumFinalizeSize::try_from(finalize.len())?; + ConfirmedTransaction::AcceptedDeploy(index, tx, finalize_operations) => { // Return the confirmed tuple. - Ok((ConfirmedTxType::AcceptedDeploy(index), tx, (num_finalize, finalize).to_bytes_le()?, None)) + Ok((ConfirmedTxType::AcceptedDeploy(index), tx, finalize_operations)) } - ConfirmedTransaction::AcceptedExecute(index, tx, finalize) => { - // Retrieve the number of finalize operations. - let num_finalize = NumFinalizeSize::try_from(finalize.len())?; + ConfirmedTransaction::AcceptedExecute(index, tx, finalize_operations) => { // Return the confirmed tuple. - Ok((ConfirmedTxType::AcceptedExecute(index), tx, (num_finalize, finalize).to_bytes_le()?, None)) + Ok((ConfirmedTxType::AcceptedExecute(index), tx, finalize_operations)) } - ConfirmedTransaction::RejectedDeploy(index, tx, rejected, finalize) => { - // Retrieve the number of finalize operations. - let num_finalize = NumFinalizeSize::try_from(finalize.len())?; - - // Initialize a vector for the serialized blob. - let mut blob = Vec::new(); - // Serialize the rejected deployment. - rejected.write_le(&mut blob)?; - // Serialize the number of finalize operations. - num_finalize.write_le(&mut blob)?; - // Serialize the finalize operations. - finalize.write_le(&mut blob)?; - + ConfirmedTransaction::RejectedDeploy(index, tx, rejected, finalize_operations) => { // Return the confirmed tuple. - Ok((ConfirmedTxType::RejectedDeploy(index), tx, blob, Some(rejected))) + Ok((ConfirmedTxType::RejectedDeploy(index, rejected), tx, finalize_operations)) } - ConfirmedTransaction::RejectedExecute(index, tx, rejected, finalize) => { - // Retrieve the number of finalize operations. - let num_finalize = NumFinalizeSize::try_from(finalize.len())?; - - // Initialize a vector for the serialized blob. - let mut blob = Vec::new(); - // Serialize the rejected deployment. - rejected.write_le(&mut blob)?; - // Serialize the number of finalize operations. - num_finalize.write_le(&mut blob)?; - // Serialize the finalize operations. - finalize.write_le(&mut blob)?; - + ConfirmedTransaction::RejectedExecute(index, tx, rejected, finalize_operations) => { // Return the confirmed tuple. - Ok((ConfirmedTxType::RejectedExecute(index), tx, blob, Some(rejected))) + Ok((ConfirmedTxType::RejectedExecute(index, rejected), tx, finalize_operations)) } } } fn to_confirmed_transaction( - confirmed_type: ConfirmedTxType, + confirmed_type: ConfirmedTxType, transaction: Transaction, - blob: Vec, + finalize_operations: Vec>, ) -> Result> { match confirmed_type { ConfirmedTxType::AcceptedDeploy(index) => { - // Initialize a cursor. - let mut cursor = Cursor::new(blob); - // Read the number of finalize operations. - let num_finalize = NumFinalizeSize::read_le(&mut cursor)?; - // Read the finalize operations. - let finalize = (0..num_finalize).map(|_| FromBytes::read_le(&mut cursor)).collect::, _>>()?; // Return the confirmed transaction. - ConfirmedTransaction::accepted_deploy(index, transaction, finalize) + ConfirmedTransaction::accepted_deploy(index, transaction, finalize_operations) } ConfirmedTxType::AcceptedExecute(index) => { - // Initialize a cursor. - let mut cursor = Cursor::new(blob); - // Read the number of finalize operations. - let num_finalize = NumFinalizeSize::read_le(&mut cursor)?; - // Read the finalize operations. - let finalize = (0..num_finalize).map(|_| FromBytes::read_le(&mut cursor)).collect::, _>>()?; // Return the confirmed transaction. - ConfirmedTransaction::accepted_execute(index, transaction, finalize) + ConfirmedTransaction::accepted_execute(index, transaction, finalize_operations) } - ConfirmedTxType::RejectedDeploy(index) => { - // Initialize a cursor. - let mut cursor = Cursor::new(blob); - // Read the rejected deployment. - let rejected = Rejected::read_le(&mut cursor)?; - // Read the number of finalize operations. - let num_finalize = NumFinalizeSize::read_le(&mut cursor)?; - // Read the finalize operations. - let finalize = (0..num_finalize).map(|_| FromBytes::read_le(&mut cursor)).collect::, _>>()?; + ConfirmedTxType::RejectedDeploy(index, rejected) => { // Return the confirmed transaction. - ConfirmedTransaction::rejected_deploy(index, transaction, rejected, finalize) + ConfirmedTransaction::rejected_deploy(index, transaction, rejected, finalize_operations) } - ConfirmedTxType::RejectedExecute(index) => { - // Initialize a cursor. - let mut cursor = Cursor::new(blob); - // Read the rejected deployment. - let rejected = Rejected::read_le(&mut cursor)?; - // Read the number of finalize operations. - let num_finalize = NumFinalizeSize::read_le(&mut cursor)?; - // Read the finalize operations. - let finalize = (0..num_finalize).map(|_| FromBytes::read_le(&mut cursor)).collect::, _>>()?; + ConfirmedTxType::RejectedExecute(index, rejected) => { // Return the confirmed transaction. - ConfirmedTransaction::rejected_execute(index, transaction, rejected, finalize) + ConfirmedTransaction::rejected_execute(index, transaction, rejected, finalize_operations) } } } @@ -187,19 +123,21 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { /// The mapping of `block hash` to `block ratifications`. type RatificationsMap: for<'a> Map<'a, N::BlockHash, Ratifications>; /// The mapping of `block hash` to `block solutions`. - type SolutionsMap: for<'a> Map<'a, N::BlockHash, Option>>; - /// The mapping of `puzzle commitment` to `block height`. - type PuzzleCommitmentsMap: for<'a> Map<'a, PuzzleCommitment, u32>; + type SolutionsMap: for<'a> Map<'a, N::BlockHash, Solutions>; + /// The mapping of `solution ID` to `block height`. + type SolutionIDsMap: for<'a> Map<'a, SolutionID, u32>; + /// The mapping of `block hash` to `[aborted solution ID]`. + type AbortedSolutionIDsMap: for<'a> Map<'a, N::BlockHash, Vec>>; + /// The mapping of aborted `solution ID` to `block height`. + type AbortedSolutionHeightsMap: for<'a> Map<'a, SolutionID, u32>; /// The mapping of `block hash` to `[transaction ID]`. type TransactionsMap: for<'a> Map<'a, N::BlockHash, Vec>; /// The mapping of `block hash` to `[aborted transaction ID]`. type AbortedTransactionIDsMap: for<'a> Map<'a, N::BlockHash, Vec>; /// The mapping of rejected or aborted `transaction ID` to `block hash`. type RejectedOrAbortedTransactionIDMap: for<'a> Map<'a, N::TransactionID, N::BlockHash>; - /// The mapping of `transaction ID` to `(block hash, confirmed tx type, confirmed blob)`. - /// TODO (howardwu): For mainnet - With recent DB changes, to prevent breaking compatibility, - /// include rejected (d or e) ID into `ConfirmedTxType`, and change from `Vec` to `Vec`. - type ConfirmedTransactionsMap: for<'a> Map<'a, N::TransactionID, (N::BlockHash, ConfirmedTxType, Vec)>; + /// The mapping of `transaction ID` to `(block hash, confirmed tx type, finalize operations)`. + type ConfirmedTransactionsMap: for<'a> Map<'a, N::TransactionID, (N::BlockHash, ConfirmedTxType, Vec>)>; /// The rejected deployment or execution map. type RejectedDeploymentOrExecutionMap: for<'a> Map<'a, Field, Rejected>; /// The transaction storage. @@ -228,8 +166,12 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { fn ratifications_map(&self) -> &Self::RatificationsMap; /// Returns the solutions map. fn solutions_map(&self) -> &Self::SolutionsMap; - /// Returns the puzzle commitments map. - fn puzzle_commitments_map(&self) -> &Self::PuzzleCommitmentsMap; + /// Returns the solution IDs map. + fn solution_ids_map(&self) -> &Self::SolutionIDsMap; + /// Returns the aborted solution IDs map. + fn aborted_solution_ids_map(&self) -> &Self::AbortedSolutionIDsMap; + /// Returns the aborted solution heights map. + fn aborted_solution_heights_map(&self) -> &Self::AbortedSolutionHeightsMap; /// Returns the accepted transactions map. fn transactions_map(&self) -> &Self::TransactionsMap; /// Returns the aborted transaction IDs map. @@ -264,7 +206,9 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { self.certificate_map().start_atomic(); self.ratifications_map().start_atomic(); self.solutions_map().start_atomic(); - self.puzzle_commitments_map().start_atomic(); + self.solution_ids_map().start_atomic(); + self.aborted_solution_ids_map().start_atomic(); + self.aborted_solution_heights_map().start_atomic(); self.transactions_map().start_atomic(); self.aborted_transaction_ids_map().start_atomic(); self.rejected_or_aborted_transaction_id_map().start_atomic(); @@ -284,7 +228,9 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { || self.certificate_map().is_atomic_in_progress() || self.ratifications_map().is_atomic_in_progress() || self.solutions_map().is_atomic_in_progress() - || self.puzzle_commitments_map().is_atomic_in_progress() + || self.solution_ids_map().is_atomic_in_progress() + || self.aborted_solution_ids_map().is_atomic_in_progress() + || self.aborted_solution_heights_map().is_atomic_in_progress() || self.transactions_map().is_atomic_in_progress() || self.aborted_transaction_ids_map().is_atomic_in_progress() || self.rejected_or_aborted_transaction_id_map().is_atomic_in_progress() @@ -304,7 +250,9 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { self.certificate_map().atomic_checkpoint(); self.ratifications_map().atomic_checkpoint(); self.solutions_map().atomic_checkpoint(); - self.puzzle_commitments_map().atomic_checkpoint(); + self.solution_ids_map().atomic_checkpoint(); + self.aborted_solution_ids_map().atomic_checkpoint(); + self.aborted_solution_heights_map().atomic_checkpoint(); self.transactions_map().atomic_checkpoint(); self.aborted_transaction_ids_map().atomic_checkpoint(); self.rejected_or_aborted_transaction_id_map().atomic_checkpoint(); @@ -324,7 +272,9 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { self.certificate_map().clear_latest_checkpoint(); self.ratifications_map().clear_latest_checkpoint(); self.solutions_map().clear_latest_checkpoint(); - self.puzzle_commitments_map().clear_latest_checkpoint(); + self.solution_ids_map().clear_latest_checkpoint(); + self.aborted_solution_ids_map().clear_latest_checkpoint(); + self.aborted_solution_heights_map().clear_latest_checkpoint(); self.transactions_map().clear_latest_checkpoint(); self.aborted_transaction_ids_map().clear_latest_checkpoint(); self.rejected_or_aborted_transaction_id_map().clear_latest_checkpoint(); @@ -344,7 +294,9 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { self.certificate_map().atomic_rewind(); self.ratifications_map().atomic_rewind(); self.solutions_map().atomic_rewind(); - self.puzzle_commitments_map().atomic_rewind(); + self.solution_ids_map().atomic_rewind(); + self.aborted_solution_ids_map().atomic_rewind(); + self.aborted_solution_heights_map().atomic_rewind(); self.transactions_map().atomic_rewind(); self.aborted_transaction_ids_map().atomic_rewind(); self.rejected_or_aborted_transaction_id_map().atomic_rewind(); @@ -364,7 +316,9 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { self.certificate_map().abort_atomic(); self.ratifications_map().abort_atomic(); self.solutions_map().abort_atomic(); - self.puzzle_commitments_map().abort_atomic(); + self.solution_ids_map().abort_atomic(); + self.aborted_solution_ids_map().abort_atomic(); + self.aborted_solution_heights_map().abort_atomic(); self.transactions_map().abort_atomic(); self.aborted_transaction_ids_map().abort_atomic(); self.rejected_or_aborted_transaction_id_map().abort_atomic(); @@ -384,7 +338,9 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { self.certificate_map().finish_atomic()?; self.ratifications_map().finish_atomic()?; self.solutions_map().finish_atomic()?; - self.puzzle_commitments_map().finish_atomic()?; + self.solution_ids_map().finish_atomic()?; + self.aborted_solution_ids_map().finish_atomic()?; + self.aborted_solution_heights_map().finish_atomic()?; self.transactions_map().finish_atomic()?; self.aborted_transaction_ids_map().finish_atomic()?; self.rejected_or_aborted_transaction_id_map().finish_atomic()?; @@ -458,13 +414,19 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { self.ratifications_map().insert(block.hash(), block.ratifications().clone())?; // Store the block solutions. - self.solutions_map().insert(block.hash(), block.solutions().cloned())?; + self.solutions_map().insert(block.hash(), block.solutions().clone())?; - // Store the block puzzle commitments. - if let Some(solutions) = block.solutions() { - for puzzle_commitment in solutions.keys() { - self.puzzle_commitments_map().insert(*puzzle_commitment, block.height())?; - } + // Store the block solution IDs. + for solution_id in block.solutions().solution_ids() { + self.solution_ids_map().insert(*solution_id, block.height())?; + } + + // Store the aborted solution IDs. + self.aborted_solution_ids_map().insert(block.hash(), block.aborted_solution_ids().clone())?; + + // Store the block aborted solution heights. + for solution_id in block.aborted_solution_ids() { + self.aborted_solution_heights_map().insert(*solution_id, block.height())?; } // Store the transaction IDs. @@ -482,11 +444,14 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { } // Store the confirmed transactions. - for (confirmed_type, transaction, blob, rejected) in confirmed { + for (confirmed_type, transaction, finalize_operations) in confirmed { // Store the block hash and confirmed transaction data. - self.confirmed_transactions_map().insert(transaction.id(), (block.hash(), confirmed_type, blob))?; + self.confirmed_transactions_map() + .insert(transaction.id(), (block.hash(), confirmed_type.clone(), finalize_operations))?; // Store the rejected deployment or execution. - if let Some(rejected) = rejected { + if let ConfirmedTxType::RejectedDeploy(_, rejected) | ConfirmedTxType::RejectedExecute(_, rejected) = + confirmed_type + { self.rejected_deployment_or_execution_map().insert(rejected.to_id()?, rejected)?; } // Store the transaction. @@ -522,11 +487,11 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { } }; + // Retrieve the aborted solution IDs. + let aborted_solution_ids = (self.get_block_aborted_solution_ids(block_hash)?).unwrap_or_default(); + // Retrieve the aborted transaction IDs. - let aborted_transaction_ids = match self.get_block_aborted_transaction_ids(block_hash)? { - Some(transaction_ids) => transaction_ids, - None => Vec::new(), - }; + let aborted_transaction_ids = (self.get_block_aborted_transaction_ids(block_hash)?).unwrap_or_default(); // Retrieve the rejected transaction IDs, and the deployment or execution ID. let rejected_transaction_ids_and_deployment_or_execution_id = match self.get_block_transactions(block_hash)? { @@ -576,11 +541,17 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { // Remove the block solutions. self.solutions_map().remove(block_hash)?; - // Remove the block puzzle commitments. - if let Some(solutions) = solutions { - for puzzle_commitment in solutions.keys() { - self.puzzle_commitments_map().remove(puzzle_commitment)?; - } + // Remove the block solution IDs. + for solution_id in solutions.solution_ids() { + self.solution_ids_map().remove(solution_id)?; + } + + // Remove the aborted solution IDs. + self.aborted_solution_ids_map().remove(block_hash)?; + + // Remove the aborted solution heights. + for solution_id in aborted_solution_ids { + self.aborted_solution_heights_map().remove(&solution_id)?; } // Remove the transaction IDs. @@ -651,11 +622,14 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { } } - /// Returns the block height that contains the given `puzzle commitment`. - fn find_block_height_from_puzzle_commitment(&self, puzzle_commitment: &PuzzleCommitment) -> Result> { - match self.puzzle_commitments_map().get_confirmed(puzzle_commitment)? { + /// Returns the block height that contains the given `solution ID`. + fn find_block_height_from_solution_id(&self, solution_id: &SolutionID) -> Result> { + match self.solution_ids_map().get_confirmed(solution_id)? { Some(block_height) => Ok(Some(cow_to_copied!(block_height))), - None => Ok(None), + None => match self.aborted_solution_heights_map().get_confirmed(solution_id)? { + Some(block_height) => Ok(Some(cow_to_copied!(block_height))), + None => Ok(None), + }, } } @@ -839,7 +813,7 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { } /// Returns the block solutions for the given `block hash`. - fn get_block_solutions(&self, block_hash: &N::BlockHash) -> Result>> { + fn get_block_solutions(&self, block_hash: &N::BlockHash) -> Result> { match self.solutions_map().get_confirmed(block_hash)? { Some(solutions) => Ok(cow_to_cloned!(solutions)), None => bail!("Missing solutions for block ('{block_hash}')"), @@ -847,10 +821,10 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { } /// Returns the prover solution for the given solution ID. - fn get_solution(&self, puzzle_commitment: &PuzzleCommitment) -> Result> { - // Retrieve the block height for the puzzle commitment. - let Some(block_height) = self.find_block_height_from_puzzle_commitment(puzzle_commitment)? else { - bail!("The block height for puzzle commitment '{puzzle_commitment}' is missing in block storage") + fn get_solution(&self, solution_id: &SolutionID) -> Result> { + // Retrieve the block height for the solution ID. + let Some(block_height) = self.find_block_height_from_solution_id(solution_id)? else { + bail!("The block height for solution ID '{solution_id}' is missing in block storage") }; // Retrieve the block hash. let Some(block_hash) = self.get_block_hash(block_height)? else { @@ -861,15 +835,19 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { bail!("The solutions for block '{block_height}' are missing in block storage") }; // Retrieve the prover solution. - match solutions { - Cow::Owned(Some(ref solutions)) | Cow::Borrowed(Some(ref solutions)) => { - solutions.get(puzzle_commitment).cloned().ok_or_else(|| { - anyhow!( - "The prover solution for puzzle commitment '{puzzle_commitment}' is missing in block storage" - ) - }) - } - _ => bail!("The prover solution for puzzle commitment '{puzzle_commitment}' is missing in block storage"), + match solutions.deref().deref() { + Some(ref solutions) => solutions.get(solution_id).cloned().ok_or_else(|| { + anyhow!("The prover solution for solution ID '{solution_id}' is missing in block storage") + }), + _ => bail!("The prover solution for solution ID '{solution_id}' is missing in block storage"), + } + } + + /// Returns the block aborted solution IDs for the given `block hash`. + fn get_block_aborted_solution_ids(&self, block_hash: &N::BlockHash) -> Result>>> { + match self.aborted_solution_ids_map().get_confirmed(block_hash)? { + Some(aborted_solution_ids) => Ok(Some(cow_to_cloned!(aborted_solution_ids))), + None => Ok(None), } } @@ -930,12 +908,13 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { Err(err) => return Err(err), }; // Retrieve the confirmed attributes. - let (_, confirmed_type, blob) = match self.confirmed_transactions_map().get_confirmed(&transaction.id())? { - Some(confirmed_attributes) => cow_to_cloned!(confirmed_attributes), - None => bail!("Missing confirmed transaction '{transaction_id}' in block storage"), - }; + let (_, confirmed_type, finalize_operations) = + match self.confirmed_transactions_map().get_confirmed(&transaction.id())? { + Some(confirmed_attributes) => cow_to_cloned!(confirmed_attributes), + None => bail!("Missing confirmed transaction '{transaction_id}' in block storage"), + }; // Construct the confirmed transaction. - to_confirmed_transaction(confirmed_type, transaction, blob).map(Some) + to_confirmed_transaction(confirmed_type, transaction, finalize_operations).map(Some) } /// Returns the unconfirmed transaction for the given `transaction ID`. @@ -986,6 +965,10 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { let Ok(solutions) = self.get_block_solutions(block_hash) else { bail!("Missing solutions for block {height} ('{block_hash}')"); }; + // Retrieve the block aborted solution IDs. + let Some(aborted_solution_ids) = self.get_block_aborted_solution_ids(block_hash)? else { + bail!("Missing aborted solutions IDs for block {height} ('{block_hash}')"); + }; // Retrieve the block transactions. let Some(transactions) = self.get_block_transactions(block_hash)? else { bail!("Missing transactions for block {height} ('{block_hash}')"); @@ -1002,6 +985,7 @@ pub trait BlockStorage: 'static + Clone + Send + Sync { authority, ratifications, solutions, + aborted_solution_ids, transactions, aborted_transaction_ids, )?)) @@ -1025,18 +1009,13 @@ impl> BlockStore { // Compute the block tree. let tree = { - // Prepare an iterator over the block heights. - let heights = storage.id_map().keys_confirmed(); - // Prepare the leaves of the block tree. - let hashes = match heights.max() { - Some(height) => cfg_into_iter!(0..=cow_to_copied!(height)) - .map(|height| match storage.get_block_hash(height)? { - Some(hash) => Ok(hash.to_bits_le()), - None => bail!("Missing block hash for block {height}"), - }) - .collect::>>>()?, - None => vec![], - }; + // Prepare an iterator over the block heights and prepare the leaves of the block tree. + let hashes = storage + .id_map() + .iter_confirmed() + .sorted_unstable_by(|(h1, _), (h2, _)| h1.cmp(h2)) + .map(|(_, hash)| hash.to_bits_le()) + .collect::>>(); // Construct the block tree. Arc::new(RwLock::new(N::merkle_tree_bhp(&hashes)?)) }; @@ -1086,10 +1065,8 @@ impl> BlockStore { let mut tree = self.tree.write(); // Determine the block heights to remove. - let heights = match self.storage.id_map().keys_confirmed().max() { - Some(height) => { - // Determine the end block height to remove. - let end_height = cow_to_copied!(height); + let heights = match self.max_height() { + Some(end_height) => { // Determine the start block height to remove. let start_height = end_height .checked_sub(n - 1) @@ -1198,12 +1175,9 @@ impl> BlockStore { self.storage.find_block_hash(transaction_id) } - /// Returns the block height that contains the given `puzzle commitment`. - pub fn find_block_height_from_puzzle_commitment( - &self, - puzzle_commitment: &PuzzleCommitment, - ) -> Result> { - self.storage.find_block_height_from_puzzle_commitment(puzzle_commitment) + /// Returns the block height that contains the given `solution ID`. + pub fn find_block_height_from_solution_id(&self, solution_id: &SolutionID) -> Result> { + self.storage.find_block_height_from_solution_id(solution_id) } } @@ -1213,6 +1187,11 @@ impl> BlockStore { (*self.tree.read().root()).into() } + /// Returns the current block height. + pub fn current_block_height(&self) -> u32 { + u32::try_from(self.tree.read().number_of_leaves()).unwrap() - 1 + } + /// Returns the state root that contains the given `block height`. pub fn get_state_root(&self, block_height: u32) -> Result> { self.storage.get_state_root(block_height) @@ -1254,12 +1233,12 @@ impl> BlockStore { } /// Returns the block solutions for the given `block hash`. - pub fn get_block_solutions(&self, block_hash: &N::BlockHash) -> Result>> { + pub fn get_block_solutions(&self, block_hash: &N::BlockHash) -> Result> { self.storage.get_block_solutions(block_hash) } /// Returns the prover solution for the given solution ID. - pub fn get_solution(&self, solution_id: &PuzzleCommitment) -> Result> { + pub fn get_solution(&self, solution_id: &SolutionID) -> Result> { self.storage.get_solution(solution_id) } @@ -1346,9 +1325,15 @@ impl> BlockStore { self.storage.certificate_map().contains_key_confirmed(certificate_id) } - /// Returns `true` if the given puzzle commitment exists. - pub fn contains_puzzle_commitment(&self, puzzle_commitment: &PuzzleCommitment) -> Result { - self.storage.puzzle_commitments_map().contains_key_confirmed(puzzle_commitment) + /// Returns `true` if the given solution ID exists. + pub fn contains_solution_id(&self, solution_id: &SolutionID) -> Result { + Ok(self.storage.solution_ids_map().contains_key_confirmed(solution_id)? + || self.contains_aborted_solution_id(solution_id)?) + } + + /// Returns `true` if the given aborted solution ID exists. + fn contains_aborted_solution_id(&self, solution_id: &SolutionID) -> Result { + self.storage.aborted_solution_heights_map().contains_key_confirmed(solution_id) } } @@ -1363,14 +1348,19 @@ impl> BlockStore { self.storage.id_map().keys_confirmed() } + /// Returns the height of the latest block in the storage. + pub fn max_height(&self) -> Option { + self.storage.id_map().len_confirmed().checked_sub(1)?.try_into().ok() + } + /// Returns an iterator over the block hashes, for all blocks in `self`. pub fn hashes(&self) -> impl '_ + Iterator> { self.storage.reverse_id_map().keys_confirmed() } - /// Returns an iterator over the puzzle commitments, for all blocks in `self`. - pub fn puzzle_commitments(&self) -> impl '_ + Iterator>> { - self.storage.puzzle_commitments_map().keys_confirmed() + /// Returns an iterator over the solution IDs, for all blocks in `self`. + pub fn solution_ids(&self) -> impl '_ + Iterator>> { + self.storage.solution_ids_map().keys_confirmed() } } @@ -1379,7 +1369,7 @@ mod tests { use super::*; use crate::helpers::memory::BlockMemory; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; #[test] fn test_insert_get_remove() { diff --git a/ledger/store/src/consensus/mod.rs b/ledger/store/src/consensus/mod.rs index d4672f7414..4f46f46fb8 100644 --- a/ledger/store/src/consensus/mod.rs +++ b/ledger/store/src/consensus/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/memory/block.rs b/ledger/store/src/helpers/memory/block.rs index 11663eacc7..04ee35c308 100644 --- a/ledger/store/src/helpers/memory/block.rs +++ b/ledger/store/src/helpers/memory/block.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,21 +14,23 @@ // limitations under the License. use crate::{ - helpers::memory::{MemoryMap, TransactionMemory, TransitionMemory}, BlockStorage, ConfirmedTxType, TransactionStore, TransitionStore, + helpers::memory::{MemoryMap, TransactionMemory, TransitionMemory}, }; use console::{prelude::*, types::Field}; use ledger_authority::Authority; -use ledger_block::{Header, Ratifications, Rejected}; -use ledger_coinbase::{CoinbaseSolution, PuzzleCommitment}; +use ledger_block::{Header, Ratifications, Rejected, Solutions}; +use ledger_puzzle::SolutionID; +use synthesizer_program::FinalizeOperation; use aleo_std_storage::StorageMode; /// An in-memory block storage. #[derive(Clone)] +#[allow(clippy::type_complexity)] pub struct BlockMemory { /// The mapping of `block height` to `state root`. state_root_map: MemoryMap, @@ -46,9 +49,13 @@ pub struct BlockMemory { /// The ratifications map. ratifications_map: MemoryMap>, /// The solutions map. - solutions_map: MemoryMap>>, - /// The puzzle commitments map. - puzzle_commitments_map: MemoryMap, u32>, + solutions_map: MemoryMap>, + /// The solution IDs map. + solution_ids_map: MemoryMap, u32>, + /// The aborted solution IDs map. + aborted_solution_ids_map: MemoryMap>>, + /// The aborted solution heights map. + aborted_solution_heights_map: MemoryMap, u32>, /// The transactions map. transactions_map: MemoryMap>, /// The aborted transaction IDs map. @@ -56,7 +63,8 @@ pub struct BlockMemory { /// The rejected transaction ID or aborted transaction ID map. rejected_or_aborted_transaction_id_map: MemoryMap, /// The confirmed transactions map. - confirmed_transactions_map: MemoryMap)>, + confirmed_transactions_map: + MemoryMap, Vec>)>, /// The rejected deployment or execution map. rejected_deployment_or_execution_map: MemoryMap, Rejected>, /// The transaction store. @@ -73,12 +81,14 @@ impl BlockStorage for BlockMemory { type AuthorityMap = MemoryMap>; type CertificateMap = MemoryMap, (u32, u64)>; type RatificationsMap = MemoryMap>; - type SolutionsMap = MemoryMap>>; - type PuzzleCommitmentsMap = MemoryMap, u32>; + type SolutionsMap = MemoryMap>; + type SolutionIDsMap = MemoryMap, u32>; + type AbortedSolutionIDsMap = MemoryMap>>; + type AbortedSolutionHeightsMap = MemoryMap, u32>; type TransactionsMap = MemoryMap>; type AbortedTransactionIDsMap = MemoryMap>; type RejectedOrAbortedTransactionIDMap = MemoryMap; - type ConfirmedTransactionsMap = MemoryMap)>; + type ConfirmedTransactionsMap = MemoryMap, Vec>)>; type RejectedDeploymentOrExecutionMap = MemoryMap, Rejected>; type TransactionStorage = TransactionMemory; type TransitionStorage = TransitionMemory; @@ -100,7 +110,9 @@ impl BlockStorage for BlockMemory { certificate_map: MemoryMap::default(), ratifications_map: MemoryMap::default(), solutions_map: MemoryMap::default(), - puzzle_commitments_map: MemoryMap::default(), + solution_ids_map: MemoryMap::default(), + aborted_solution_ids_map: MemoryMap::default(), + aborted_solution_heights_map: MemoryMap::default(), transactions_map: MemoryMap::default(), aborted_transaction_ids_map: MemoryMap::default(), rejected_or_aborted_transaction_id_map: MemoryMap::default(), @@ -155,9 +167,19 @@ impl BlockStorage for BlockMemory { &self.solutions_map } - /// Returns the puzzle commitments map. - fn puzzle_commitments_map(&self) -> &Self::PuzzleCommitmentsMap { - &self.puzzle_commitments_map + /// Returns the solution IDs map. + fn solution_ids_map(&self) -> &Self::SolutionIDsMap { + &self.solution_ids_map + } + + /// Returns the aborted solution IDs map. + fn aborted_solution_ids_map(&self) -> &Self::AbortedSolutionIDsMap { + &self.aborted_solution_ids_map + } + + /// Returns the aborted solution heights map. + fn aborted_solution_heights_map(&self) -> &Self::AbortedSolutionHeightsMap { + &self.aborted_solution_heights_map } /// Returns the transactions map. diff --git a/ledger/store/src/helpers/memory/consensus.rs b/ledger/store/src/helpers/memory/consensus.rs index d5adf20141..b29a1cad6e 100644 --- a/ledger/store/src/helpers/memory/consensus.rs +++ b/ledger/store/src/helpers/memory/consensus.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,10 +14,10 @@ // limitations under the License. use crate::{ - helpers::memory::{BlockMemory, FinalizeMemory, TransactionMemory, TransitionMemory}, BlockStore, ConsensusStorage, FinalizeStore, + helpers::memory::{BlockMemory, FinalizeMemory, TransactionMemory, TransitionMemory}, }; use console::prelude::*; diff --git a/ledger/store/src/helpers/memory/internal/map.rs b/ledger/store/src/helpers/memory/internal/map.rs index 514e4d551c..e932b7a416 100644 --- a/ledger/store/src/helpers/memory/internal/map.rs +++ b/ledger/store/src/helpers/memory/internal/map.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -22,10 +23,10 @@ use core::{borrow::Borrow, hash::Hash}; use parking_lot::{Mutex, RwLock}; use std::{ borrow::Cow, - collections::{btree_map, BTreeMap}, + collections::{BTreeMap, btree_map}, sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, }; @@ -383,10 +384,10 @@ impl< #[cfg(test)] mod tests { use super::*; - use crate::{atomic_batch_scope, atomic_finalize, FinalizeMode}; - use console::{account::Address, network::Testnet3}; + use crate::{FinalizeMode, atomic_batch_scope, atomic_finalize}; + use console::{account::Address, network::MainnetV0}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_contains_key_sanity_check() { diff --git a/ledger/store/src/helpers/memory/internal/mod.rs b/ledger/store/src/helpers/memory/internal/mod.rs index dea20c2ef0..db111021e7 100644 --- a/ledger/store/src/helpers/memory/internal/mod.rs +++ b/ledger/store/src/helpers/memory/internal/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/memory/internal/nested_map.rs b/ledger/store/src/helpers/memory/internal/nested_map.rs index 2ad1ccdaf2..1133e7a42f 100644 --- a/ledger/store/src/helpers/memory/internal/nested_map.rs +++ b/ledger/store/src/helpers/memory/internal/nested_map.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,10 +22,10 @@ use core::hash::Hash; use parking_lot::{Mutex, RwLock}; use std::{ borrow::Cow, - collections::{btree_map, BTreeMap, BTreeSet}, + collections::{BTreeMap, BTreeSet, btree_map}, sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, }; @@ -590,10 +591,10 @@ fn to_map_key(m: &[u8], k: &[u8]) -> Vec { #[cfg(test)] mod tests { use super::*; - use crate::{atomic_batch_scope, atomic_finalize, FinalizeMode}; - use console::{account::Address, network::Testnet3}; + use crate::{FinalizeMode, atomic_batch_scope, atomic_finalize}; + use console::{account::Address, network::MainnetV0}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_contains_key_sanity_check() { diff --git a/ledger/store/src/helpers/memory/mod.rs b/ledger/store/src/helpers/memory/mod.rs index 6a41a4ffd6..d7c6e4a6c1 100644 --- a/ledger/store/src/helpers/memory/mod.rs +++ b/ledger/store/src/helpers/memory/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/memory/program.rs b/ledger/store/src/helpers/memory/program.rs index 04675cff7d..b48edf62c0 100644 --- a/ledger/store/src/helpers/memory/program.rs +++ b/ledger/store/src/helpers/memory/program.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,10 +16,10 @@ #![allow(clippy::type_complexity)] use crate::{ - helpers::memory::{MemoryMap, NestedMemoryMap}, CommitteeStorage, CommitteeStore, FinalizeStorage, + helpers::memory::{MemoryMap, NestedMemoryMap}, }; use console::{ prelude::*, diff --git a/ledger/store/src/helpers/memory/transaction.rs b/ledger/store/src/helpers/memory/transaction.rs index 66b7b14867..31dc8ac3d3 100644 --- a/ledger/store/src/helpers/memory/transaction.rs +++ b/ledger/store/src/helpers/memory/transaction.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,6 @@ // limitations under the License. use crate::{ - helpers::memory::{MemoryMap, TransitionMemory}, DeploymentStorage, DeploymentStore, ExecutionStorage, @@ -23,6 +23,7 @@ use crate::{ TransactionStorage, TransactionType, TransitionStore, + helpers::memory::{MemoryMap, TransitionMemory}, }; use console::{ prelude::*, diff --git a/ledger/store/src/helpers/memory/transition.rs b/ledger/store/src/helpers/memory/transition.rs index b72b6fa4b6..1b1b56be27 100644 --- a/ledger/store/src/helpers/memory/transition.rs +++ b/ledger/store/src/helpers/memory/transition.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{helpers::memory::MemoryMap, InputStorage, InputStore, OutputStorage, OutputStore, TransitionStorage}; +use crate::{InputStorage, InputStore, OutputStorage, OutputStore, TransitionStorage, helpers::memory::MemoryMap}; use console::{ prelude::*, program::{Ciphertext, Future, Identifier, Plaintext, ProgramID, Record}, @@ -38,6 +39,8 @@ pub struct TransitionMemory { tcm_map: MemoryMap>, /// The reverse `tcm` map. reverse_tcm_map: MemoryMap, N::TransitionID>, + /// The signer commitments. + scm_map: MemoryMap>, } #[rustfmt::skip] @@ -49,6 +52,7 @@ impl TransitionStorage for TransitionMemory { type ReverseTPKMap = MemoryMap, N::TransitionID>; type TCMMap = MemoryMap>; type ReverseTCMMap = MemoryMap, N::TransitionID>; + type SCMMap = MemoryMap>; /// Initializes the transition storage. fn open>(storage: S) -> Result { @@ -60,6 +64,7 @@ impl TransitionStorage for TransitionMemory { reverse_tpk_map: MemoryMap::default(), tcm_map: MemoryMap::default(), reverse_tcm_map: MemoryMap::default(), + scm_map: MemoryMap::default(), }) } @@ -97,6 +102,11 @@ impl TransitionStorage for TransitionMemory { fn reverse_tcm_map(&self) -> &Self::ReverseTCMMap { &self.reverse_tcm_map } + + /// Returns the signer commitments. + fn scm_map(&self) -> &Self::SCMMap { + &self.scm_map + } } /// An in-memory transition input storage. diff --git a/ledger/store/src/helpers/mod.rs b/ledger/store/src/helpers/mod.rs index deb8926700..746d5b48e6 100644 --- a/ledger/store/src/helpers/mod.rs +++ b/ledger/store/src/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/rocksdb/block.rs b/ledger/store/src/helpers/rocksdb/block.rs index eed26472b0..97a86cc3d1 100644 --- a/ledger/store/src/helpers/rocksdb/block.rs +++ b/ledger/store/src/helpers/rocksdb/block.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,27 +14,29 @@ // limitations under the License. use crate::{ + BlockStorage, + ConfirmedTxType, + TransactionStore, + TransitionStore, helpers::rocksdb::{ - internal::{self, DataMap, Database}, BlockMap, MapID, TransactionDB, TransitionDB, + internal::{self, DataMap, Database}, }, - BlockStorage, - ConfirmedTxType, - TransactionStore, - TransitionStore, }; use console::{prelude::*, types::Field}; use ledger_authority::Authority; -use ledger_block::{Header, Ratifications, Rejected}; -use ledger_coinbase::{CoinbaseSolution, PuzzleCommitment}; +use ledger_block::{Header, Ratifications, Rejected, Solutions}; +use ledger_puzzle::SolutionID; +use synthesizer_program::FinalizeOperation; use aleo_std_storage::StorageMode; /// A RocksDB block storage. #[derive(Clone)] +#[allow(clippy::type_complexity)] pub struct BlockDB { /// The mapping of `block height` to `state root`. state_root_map: DataMap, @@ -52,9 +55,13 @@ pub struct BlockDB { /// The ratifications map. ratifications_map: DataMap>, /// The solutions map. - solutions_map: DataMap>>, - /// The puzzle commitments map. - puzzle_commitments_map: DataMap, u32>, + solutions_map: DataMap>, + /// The solution IDs map. + solution_ids_map: DataMap, u32>, + /// The aborted solution IDs map. + aborted_solution_ids_map: DataMap>>, + /// The aborted solution heights map. + aborted_solution_heights_map: DataMap, u32>, /// The transactions map. transactions_map: DataMap>, /// The aborted transaction IDs map. @@ -62,7 +69,8 @@ pub struct BlockDB { /// The rejected or aborted transaction ID map. rejected_or_aborted_transaction_id_map: DataMap, /// The confirmed transactions map. - confirmed_transactions_map: DataMap)>, + confirmed_transactions_map: + DataMap, Vec>)>, /// The rejected deployment or execution map. rejected_deployment_or_execution_map: DataMap, Rejected>, /// The transaction store. @@ -79,12 +87,14 @@ impl BlockStorage for BlockDB { type AuthorityMap = DataMap>; type CertificateMap = DataMap, (u32, u64)>; type RatificationsMap = DataMap>; - type SolutionsMap = DataMap>>; - type PuzzleCommitmentsMap = DataMap, u32>; + type SolutionsMap = DataMap>; + type SolutionIDsMap = DataMap, u32>; + type AbortedSolutionIDsMap = DataMap>>; + type AbortedSolutionHeightsMap = DataMap, u32>; type TransactionsMap = DataMap>; type AbortedTransactionIDsMap = DataMap>; type RejectedOrAbortedTransactionIDMap = DataMap; - type ConfirmedTransactionsMap = DataMap)>; + type ConfirmedTransactionsMap = DataMap, Vec>)>; type RejectedDeploymentOrExecutionMap = DataMap, Rejected>; type TransactionStorage = TransactionDB; type TransitionStorage = TransitionDB; @@ -106,7 +116,9 @@ impl BlockStorage for BlockDB { certificate_map: internal::RocksDB::open_map(N::ID, storage.clone(), MapID::Block(BlockMap::Certificate))?, ratifications_map: internal::RocksDB::open_map(N::ID, storage.clone(), MapID::Block(BlockMap::Ratifications))?, solutions_map: internal::RocksDB::open_map(N::ID, storage.clone(), MapID::Block(BlockMap::Solutions))?, - puzzle_commitments_map: internal::RocksDB::open_map(N::ID, storage.clone(), MapID::Block(BlockMap::PuzzleCommitments))?, + solution_ids_map: internal::RocksDB::open_map(N::ID, storage.clone(), MapID::Block(BlockMap::PuzzleCommitments))?, + aborted_solution_ids_map: internal::RocksDB::open_map(N::ID, storage.clone(), MapID::Block(BlockMap::AbortedSolutionIDs))?, + aborted_solution_heights_map: internal::RocksDB::open_map(N::ID, storage.clone(), MapID::Block(BlockMap::AbortedSolutionHeights))?, transactions_map: internal::RocksDB::open_map(N::ID, storage.clone(), MapID::Block(BlockMap::Transactions))?, aborted_transaction_ids_map: internal::RocksDB::open_map(N::ID, storage.clone(), MapID::Block(BlockMap::AbortedTransactionIDs))?, rejected_or_aborted_transaction_id_map: internal::RocksDB::open_map(N::ID, storage.clone(), MapID::Block(BlockMap::RejectedOrAbortedTransactionID))?, @@ -161,9 +173,19 @@ impl BlockStorage for BlockDB { &self.solutions_map } - /// Returns the puzzle commitments map. - fn puzzle_commitments_map(&self) -> &Self::PuzzleCommitmentsMap { - &self.puzzle_commitments_map + /// Returns the solution IDs map. + fn solution_ids_map(&self) -> &Self::SolutionIDsMap { + &self.solution_ids_map + } + + /// Returns the aborted solution IDs map. + fn aborted_solution_ids_map(&self) -> &Self::AbortedSolutionIDsMap { + &self.aborted_solution_ids_map + } + + /// Returns the aborted solution heights map. + fn aborted_solution_heights_map(&self) -> &Self::AbortedSolutionHeightsMap { + &self.aborted_solution_heights_map } /// Returns the transactions map. diff --git a/ledger/store/src/helpers/rocksdb/consensus.rs b/ledger/store/src/helpers/rocksdb/consensus.rs index 3735a31e67..0ff5df0aff 100644 --- a/ledger/store/src/helpers/rocksdb/consensus.rs +++ b/ledger/store/src/helpers/rocksdb/consensus.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,10 +14,10 @@ // limitations under the License. use crate::{ - helpers::rocksdb::{BlockDB, FinalizeDB, TransactionDB, TransitionDB}, BlockStore, ConsensusStorage, FinalizeStore, + helpers::rocksdb::{BlockDB, FinalizeDB, TransactionDB, TransitionDB}, }; use console::prelude::*; diff --git a/ledger/store/src/helpers/rocksdb/internal/id.rs b/ledger/store/src/helpers/rocksdb/internal/id.rs index 4a8dd7d3ad..b01dc7b99c 100644 --- a/ledger/store/src/helpers/rocksdb/internal/id.rs +++ b/ledger/store/src/helpers/rocksdb/internal/id.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -59,6 +60,7 @@ impl From for u16 { #[repr(u16)] pub enum BFTMap { Transmissions = DataID::BFTTransmissionsMap as u16, + AbortedTransmissionIDs = DataID::BFTAbortedTransmissionIDsMap as u16, } /// The RocksDB map prefix for block-related entries. @@ -76,7 +78,9 @@ pub enum BlockMap { Certificate = DataID::BlockCertificateMap as u16, Ratifications = DataID::BlockRatificationsMap as u16, Solutions = DataID::BlockSolutionsMap as u16, - PuzzleCommitments = DataID::BlockPuzzleCommitmentsMap as u16, + PuzzleCommitments = DataID::BlockSolutionIDsMap as u16, + AbortedSolutionIDs = DataID::BlockAbortedSolutionIDsMap as u16, + AbortedSolutionHeights = DataID::BlockAbortedSolutionHeightsMap as u16, Transactions = DataID::BlockTransactionsMap as u16, AbortedTransactionIDs = DataID::BlockAbortedTransactionIDsMap as u16, RejectedOrAbortedTransactionID = DataID::BlockRejectedOrAbortedTransactionIDMap as u16, @@ -184,6 +188,7 @@ pub enum TransitionMap { ReverseTPK = DataID::TransitionReverseTPKMap as u16, TCM = DataID::TransitionTCMMap as u16, ReverseTCM = DataID::TransitionReverseTCMMap as u16, + SCM = DataID::TransitionSCMMap as u16, } /// The RocksDB map prefix for program-related entries. @@ -217,6 +222,9 @@ pub enum TestMap { #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[repr(u16)] enum DataID { + // BFT + BFTTransmissionsMap, + BFTAbortedTransmissionIDsMap, // Block BlockStateRootMap, BlockReverseStateRootMap, @@ -227,11 +235,14 @@ enum DataID { BlockCertificateMap, BlockRatificationsMap, BlockSolutionsMap, - BlockPuzzleCommitmentsMap, + BlockSolutionIDsMap, + BlockAbortedSolutionIDsMap, + BlockAbortedSolutionHeightsMap, BlockTransactionsMap, BlockAbortedTransactionIDsMap, BlockRejectedOrAbortedTransactionIDMap, BlockConfirmedTransactionsMap, + BlockRejectedDeploymentOrExecutionMap, // Committee CurrentRoundMap, RoundToHeightMap, @@ -278,14 +289,11 @@ enum DataID { TransitionReverseTPKMap, TransitionTCMMap, TransitionReverseTCMMap, + TransitionSCMMap, // Program ProgramIDMap, KeyValueMap, - // TODO (howardwu): For mainnet - Reorder this up above. - BlockRejectedDeploymentOrExecutionMap, - BFTTransmissionsMap, - // Testing #[cfg(test)] Test, diff --git a/ledger/store/src/helpers/rocksdb/internal/map.rs b/ledger/store/src/helpers/rocksdb/internal/map.rs index bd868d4bc6..c4c6c0a02b 100644 --- a/ledger/store/src/helpers/rocksdb/internal/map.rs +++ b/ledger/store/src/helpers/rocksdb/internal/map.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,6 +20,7 @@ use crate::helpers::{Map, MapRead}; use core::{fmt, fmt::Debug, hash::Hash, mem}; use indexmap::IndexMap; +use smallvec::SmallVec; use std::{borrow::Cow, ops::Deref, sync::atomic::Ordering}; use tracing::error; @@ -275,17 +277,21 @@ impl< // Count the number of keys belonging to the map. let mut len = 0usize; - while let Some(key) = iter.key() { - // Only compare the map ID - the network ID is guaranteed to - // remain the same as long as there is more than a single map. - if key[2..][..2] != self.context[2..][..2] { - // If the map ID is different, it's the end of iteration. + while iter.valid() { + if let Some(key) = iter.key() { + // Only compare the map ID - the network ID is guaranteed to + // remain the same as long as there is more than a single map. + if key[2..][..2] != self.context[2..][..2] { + // If the map ID is different, it's the end of iteration. + break; + } + + // Increment the length and go to the next record. + len += 1; + iter.next(); + } else { break; } - - // Increment the length and go to the next record. - len += 1; - iter.next(); } len @@ -399,7 +405,7 @@ pub struct Iter< K: 'a + Debug + PartialEq + Eq + Hash + Serialize + DeserializeOwned, V: 'a + PartialEq + Eq + Serialize + DeserializeOwned, > { - db_iter: rocksdb::DBIterator<'a>, + db_iter: rocksdb::DBRawIterator<'a>, _phantom: PhantomData<(K, V)>, } @@ -410,7 +416,7 @@ impl< > Iter<'a, K, V> { pub(super) fn new(db_iter: rocksdb::DBIterator<'a>) -> Self { - Self { db_iter, _phantom: PhantomData } + Self { db_iter: db_iter.into(), _phantom: PhantomData } } } @@ -423,13 +429,11 @@ impl< type Item = (Cow<'a, K>, Cow<'a, V>); fn next(&mut self) -> Option { - let (key, value) = self - .db_iter - .next()? - .map_err(|e| { - error!("RocksDB Iter iterator error: {e}"); - }) - .ok()?; + if !self.db_iter.valid() { + return None; + } + + let (key, value) = self.db_iter.item()?; // Deserialize the key and value. let key = bincode::deserialize(&key[PREFIX_LEN..]) @@ -437,25 +441,27 @@ impl< error!("RocksDB Iter deserialize(key) error: {e}"); }) .ok()?; - let value = bincode::deserialize(&value) + let value = bincode::deserialize(value) .map_err(|e| { error!("RocksDB Iter deserialize(value) error: {e}"); }) .ok()?; + self.db_iter.next(); + Some((Cow::Owned(key), Cow::Owned(value))) } } /// An iterator over the keys of a prefix. pub struct Keys<'a, K: 'a + Debug + PartialEq + Eq + Hash + Serialize + DeserializeOwned> { - db_iter: rocksdb::DBIterator<'a>, + db_iter: rocksdb::DBRawIterator<'a>, _phantom: PhantomData, } impl<'a, K: 'a + Debug + PartialEq + Eq + Hash + Serialize + DeserializeOwned> Keys<'a, K> { pub(crate) fn new(db_iter: rocksdb::DBIterator<'a>) -> Self { - Self { db_iter, _phantom: PhantomData } + Self { db_iter: db_iter.into(), _phantom: PhantomData } } } @@ -463,34 +469,32 @@ impl<'a, K: 'a + Clone + Debug + PartialEq + Eq + Hash + Serialize + Deserialize type Item = Cow<'a, K>; fn next(&mut self) -> Option { - let (key, _) = self - .db_iter - .next()? - .map_err(|e| { - error!("RocksDB Keys iterator error: {e}"); - }) - .ok()?; + if !self.db_iter.valid() { + return None; + } // Deserialize the key. - let key = bincode::deserialize(&key[PREFIX_LEN..]) + let key = bincode::deserialize(&self.db_iter.key()?[PREFIX_LEN..]) .map_err(|e| { error!("RocksDB Keys deserialize(key) error: {e}"); }) .ok()?; + self.db_iter.next(); + Some(Cow::Owned(key)) } } /// An iterator over the values of a prefix. pub struct Values<'a, V: 'a + PartialEq + Eq + Serialize + DeserializeOwned> { - db_iter: rocksdb::DBIterator<'a>, + db_iter: rocksdb::DBRawIterator<'a>, _phantom: PhantomData, } impl<'a, V: 'a + PartialEq + Eq + Serialize + DeserializeOwned> Values<'a, V> { pub(crate) fn new(db_iter: rocksdb::DBIterator<'a>) -> Self { - Self { db_iter, _phantom: PhantomData } + Self { db_iter: db_iter.into(), _phantom: PhantomData } } } @@ -498,33 +502,32 @@ impl<'a, V: 'a + Clone + PartialEq + Eq + Serialize + DeserializeOwned> Iterator type Item = Cow<'a, V>; fn next(&mut self) -> Option { - let (_, value) = self - .db_iter - .next()? - .map_err(|e| { - error!("RocksDB Values iterator error: {e}"); - }) - .ok()?; + if !self.db_iter.valid() { + return None; + } // Deserialize the value. - let value = bincode::deserialize(&value) + let value = bincode::deserialize(self.db_iter.value()?) .map_err(|e| { error!("RocksDB Values deserialize(value) error: {e}"); }) .ok()?; + self.db_iter.next(); + Some(Cow::Owned(value)) } } impl DataMap { #[inline] - fn create_prefixed_key(&self, key: &Q) -> Result> + fn create_prefixed_key(&self, key: &Q) -> Result> where K: Borrow, Q: Serialize + ?Sized, { - let mut raw_key = self.context.clone(); + let mut raw_key: SmallVec<[u8; 64]> = SmallVec::new(); + raw_key.extend_from_slice(&self.context); bincode::serialize_into(&mut raw_key, &key)?; Ok(raw_key) } @@ -535,7 +538,7 @@ impl DataMap Ok(Some(data)), None => Ok(None), } @@ -552,21 +555,21 @@ impl fmt::Debu mod tests { use super::*; use crate::{ + FinalizeMode, atomic_batch_scope, atomic_finalize, - helpers::rocksdb::{internal::tests::temp_dir, MapID, TestMap}, - FinalizeMode, + helpers::rocksdb::{MapID, TestMap, internal::tests::temp_dir}, }; use console::{ account::{Address, FromStr}, - network::Testnet3, + network::MainnetV0, }; use anyhow::anyhow; use serial_test::serial; use tracing_test::traced_test; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; // Below are a few objects that mimic the way our DataMaps are organized, // in order to provide a more accurate test setup for some scenarios. diff --git a/ledger/store/src/helpers/rocksdb/internal/mod.rs b/ledger/store/src/helpers/rocksdb/internal/mod.rs index 20222de928..a5c5d3c7e4 100644 --- a/ledger/store/src/helpers/rocksdb/internal/mod.rs +++ b/ledger/store/src/helpers/rocksdb/internal/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -25,18 +26,18 @@ pub use nested_map::*; mod tests; use aleo_std_storage::StorageMode; -use anyhow::{bail, ensure, Result}; +use anyhow::{Result, bail, ensure}; use once_cell::sync::OnceCell; use parking_lot::Mutex; -use serde::{de::DeserializeOwned, Serialize}; +use serde::{Serialize, de::DeserializeOwned}; use std::{ borrow::Borrow, marker::PhantomData, mem, ops::Deref, sync::{ - atomic::{AtomicBool, AtomicUsize, Ordering}, Arc, + atomic::{AtomicBool, AtomicUsize, Ordering}, }, }; @@ -75,7 +76,6 @@ pub trait Database { } /// An instance of a RocksDB database. -#[derive(Clone)] pub struct RocksDB { /// The RocksDB instance. rocksdb: Arc, @@ -91,6 +91,22 @@ pub struct RocksDB { pub(super) atomic_depth: Arc, /// A flag indicating whether the atomic writes are currently paused. pub(super) atomic_writes_paused: Arc, + /// This is an optimization that avoids some allocations when querying the database. + pub(super) default_readopts: rocksdb::ReadOptions, +} + +impl Clone for RocksDB { + fn clone(&self) -> Self { + Self { + rocksdb: self.rocksdb.clone(), + network_id: self.network_id, + storage_mode: self.storage_mode.clone(), + atomic_batch: self.atomic_batch.clone(), + atomic_depth: self.atomic_depth.clone(), + atomic_writes_paused: self.atomic_writes_paused.clone(), + default_readopts: Default::default(), + } + } } impl Deref for RocksDB { @@ -125,6 +141,7 @@ impl Database for RocksDB { options.increase_parallelism(2); options.set_max_background_jobs(4); options.create_if_missing(true); + options.set_max_open_files(8192); Arc::new(rocksdb::DB::open(&options, primary)?) }; @@ -136,6 +153,7 @@ impl Database for RocksDB { atomic_batch: Default::default(), atomic_depth: Default::default(), atomic_writes_paused: Default::default(), + default_readopts: Default::default(), }) })? .clone(); @@ -309,6 +327,7 @@ impl RocksDB { atomic_batch: Default::default(), atomic_depth: Default::default(), atomic_writes_paused: Default::default(), + default_readopts: Default::default(), }) }?; diff --git a/ledger/store/src/helpers/rocksdb/internal/nested_map.rs b/ledger/store/src/helpers/rocksdb/internal/nested_map.rs index 86366628e9..245b50d913 100644 --- a/ledger/store/src/helpers/rocksdb/internal/nested_map.rs +++ b/ledger/store/src/helpers/rocksdb/internal/nested_map.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,7 +17,7 @@ use super::*; use crate::helpers::{NestedMap, NestedMapRead}; -use console::prelude::{anyhow, cfg_into_iter, FromBytes}; +use console::prelude::{FromBytes, anyhow, cfg_into_iter}; use core::{fmt, fmt::Debug, hash::Hash, mem}; use std::{borrow::Cow, sync::atomic::Ordering}; @@ -75,7 +76,7 @@ impl Result> { let raw_map_key = self.create_prefixed_map_key(map, key)?; - match self.database.get_pinned(&raw_map_key)? { + match self.database.get_pinned_opt(&raw_map_key, &self.database.default_readopts)? { Some(data) => Ok(Some(data)), None => Ok(None), } @@ -371,18 +372,22 @@ impl< // Count the number of keys belonging to the nested map. let mut len = 0usize; - while let Some(key) = iter.key() { - // Only compare the nested map - the network ID and the outer map - // ID are guaranteed to remain the same as long as there is more - // than a single map in the database. - if !key[PREFIX_LEN + 4..].starts_with(serialized_map) { - // If the nested map ID is different, it's the end of iteration. + while iter.valid() { + if let Some(key) = iter.key() { + // Only compare the nested map - the network ID and the outer map + // ID are guaranteed to remain the same as long as there is more + // than a single map in the database. + if !key[PREFIX_LEN + 4..].starts_with(serialized_map) { + // If the nested map ID is different, it's the end of iteration. + break; + } + + // Increment the length and go to the next record. + len += 1; + iter.next(); + } else { break; } - - // Increment the length and go to the next record. - len += 1; - iter.next(); } Ok(len) @@ -594,7 +599,7 @@ pub struct NestedIter< K: 'a + Debug + PartialEq + Eq + Serialize + DeserializeOwned, V: 'a + PartialEq + Eq + Serialize + DeserializeOwned, > { - db_iter: rocksdb::DBIterator<'a>, + db_iter: rocksdb::DBRawIterator<'a>, _phantom: PhantomData<(M, K, V)>, } @@ -606,7 +611,7 @@ impl< > NestedIter<'a, M, K, V> { pub(super) fn new(db_iter: rocksdb::DBIterator<'a>) -> Self { - Self { db_iter, _phantom: PhantomData } + Self { db_iter: db_iter.into(), _phantom: PhantomData } } } @@ -620,16 +625,14 @@ impl< type Item = (Cow<'a, M>, Cow<'a, K>, Cow<'a, V>); fn next(&mut self) -> Option { - let (map_key, value) = self - .db_iter - .next()? - .map_err(|e| { - error!("RocksDB NestedIter iterator error: {e}"); - }) - .ok()?; + if !self.db_iter.valid() { + return None; + } + + let (map_key, value) = self.db_iter.item()?; // Extract the bytes belonging to the map and the key. - let (entry_map, entry_key) = get_map_and_key(&map_key) + let (entry_map, entry_key) = get_map_and_key(map_key) .map_err(|e| { error!("RocksDB NestedIter get_map_and_key error: {e}"); }) @@ -647,12 +650,14 @@ impl< }) .ok()?; // Deserialize the value. - let value = bincode::deserialize(&value) + let value = bincode::deserialize(value) .map_err(|e| { error!("RocksDB NestedIter deserialize(value) error: {e}"); }) .ok()?; + self.db_iter.next(); + Some((Cow::Owned(map), Cow::Owned(key), Cow::Owned(value))) } } @@ -663,7 +668,7 @@ pub struct NestedKeys< M: 'a + Clone + Debug + PartialEq + Eq + Hash + Serialize + DeserializeOwned, K: 'a + Clone + Debug + PartialEq + Eq + Serialize + DeserializeOwned, > { - db_iter: rocksdb::DBIterator<'a>, + db_iter: rocksdb::DBRawIterator<'a>, _phantom: PhantomData<(M, K)>, } @@ -674,7 +679,7 @@ impl< > NestedKeys<'a, M, K> { pub(crate) fn new(db_iter: rocksdb::DBIterator<'a>) -> Self { - Self { db_iter, _phantom: PhantomData } + Self { db_iter: db_iter.into(), _phantom: PhantomData } } } @@ -687,16 +692,14 @@ impl< type Item = (Cow<'a, M>, Cow<'a, K>); fn next(&mut self) -> Option { - let (map_key, _) = self - .db_iter - .next()? - .map_err(|e| { - error!("RocksDB NestedKeys iterator error: {e}"); - }) - .ok()?; + if !self.db_iter.valid() { + return None; + } + + let map_key = self.db_iter.key()?; // Extract the bytes belonging to the map and the key. - let (entry_map, entry_key) = get_map_and_key(&map_key) + let (entry_map, entry_key) = get_map_and_key(map_key) .map_err(|e| { error!("RocksDB NestedKeys get_map_and_key error: {e}"); }) @@ -714,19 +717,21 @@ impl< }) .ok()?; + self.db_iter.next(); + Some((Cow::Owned(map), Cow::Owned(key))) } } /// An iterator over the values of a prefix. pub struct NestedValues<'a, V: 'a + PartialEq + Eq + Serialize + DeserializeOwned> { - db_iter: rocksdb::DBIterator<'a>, + db_iter: rocksdb::DBRawIterator<'a>, _phantom: PhantomData, } impl<'a, V: 'a + PartialEq + Eq + Serialize + DeserializeOwned> NestedValues<'a, V> { pub(crate) fn new(db_iter: rocksdb::DBIterator<'a>) -> Self { - Self { db_iter, _phantom: PhantomData } + Self { db_iter: db_iter.into(), _phantom: PhantomData } } } @@ -734,21 +739,21 @@ impl<'a, V: 'a + Clone + PartialEq + Eq + Serialize + DeserializeOwned> Iterator type Item = Cow<'a, V>; fn next(&mut self) -> Option { - let (_, value) = self - .db_iter - .next()? - .map_err(|e| { - error!("RocksDB NestedValues iterator error: {e}"); - }) - .ok()?; + if !self.db_iter.valid() { + return None; + } + + let value = self.db_iter.value()?; // Deserialize the value. - let value = bincode::deserialize(&value) + let value = bincode::deserialize(value) .map_err(|e| { error!("RocksDB NestedValues deserialize(value) error: {e}"); }) .ok()?; + self.db_iter.next(); + Some(Cow::Owned(value)) } } @@ -757,24 +762,24 @@ impl<'a, V: 'a + Clone + PartialEq + Eq + Serialize + DeserializeOwned> Iterator mod tests { use super::*; use crate::{ + FinalizeMode, atomic_batch_scope, atomic_finalize, helpers::{ - rocksdb::{internal::tests::temp_dir, MapID, TestMap}, + rocksdb::{MapID, TestMap, internal::tests::temp_dir}, traits::Map, }, - FinalizeMode, }; use console::{ account::{Address, FromStr}, - network::Testnet3, + network::MainnetV0, }; use anyhow::anyhow; use serial_test::serial; use tracing_test::traced_test; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; // Below are a few objects that mimic the way our NestedDataMaps are organized, // in order to provide a more accurate test setup for some scenarios. diff --git a/ledger/store/src/helpers/rocksdb/internal/tests.rs b/ledger/store/src/helpers/rocksdb/internal/tests.rs index d45466a256..cbae47a770 100644 --- a/ledger/store/src/helpers/rocksdb/internal/tests.rs +++ b/ledger/store/src/helpers/rocksdb/internal/tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,12 +14,12 @@ // limitations under the License. use crate::helpers::{ - rocksdb::{MapID, RocksDB, TestMap as TestMapID}, Map, MapRead, + rocksdb::{MapID, RocksDB, TestMap as TestMapID}, }; use console::{ - network::{Network, Testnet3}, + network::{MainnetV0, Network}, prelude::{TestRng, Uniform}, types::Scalar, }; @@ -154,7 +155,7 @@ fn test_insert_and_values() { #[test] #[serial] fn test_scalar_mul() { - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; let rng = &mut TestRng::default(); diff --git a/ledger/store/src/helpers/rocksdb/mod.rs b/ledger/store/src/helpers/rocksdb/mod.rs index 6a41a4ffd6..d7c6e4a6c1 100644 --- a/ledger/store/src/helpers/rocksdb/mod.rs +++ b/ledger/store/src/helpers/rocksdb/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/rocksdb/program.rs b/ledger/store/src/helpers/rocksdb/program.rs index 9e11bda792..d57a6fb286 100644 --- a/ledger/store/src/helpers/rocksdb/program.rs +++ b/ledger/store/src/helpers/rocksdb/program.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,10 +16,10 @@ #![allow(clippy::type_complexity)] use crate::{ - helpers::rocksdb::{self, CommitteeMap, DataMap, Database, MapID, NestedDataMap, ProgramMap}, CommitteeStorage, CommitteeStore, FinalizeStorage, + helpers::rocksdb::{self, CommitteeMap, DataMap, Database, MapID, NestedDataMap, ProgramMap}, }; use console::{ prelude::*, @@ -70,7 +71,7 @@ impl FinalizeStorage for FinalizeDB { Ok(Self { committee_store, program_id_map: rocksdb::RocksDB::open_map_testing(temp_dir.clone(), dev, MapID::Program(ProgramMap::ProgramID))?, - key_value_map: rocksdb::RocksDB::open_nested_map_testing(temp_dir.clone(), dev, MapID::Program(ProgramMap::KeyValueID))?, + key_value_map: rocksdb::RocksDB::open_nested_map_testing(temp_dir, dev, MapID::Program(ProgramMap::KeyValueID))?, storage_mode: dev.into(), }) } diff --git a/ledger/store/src/helpers/rocksdb/transaction.rs b/ledger/store/src/helpers/rocksdb/transaction.rs index 2cac1c9c2c..fbb026a5c9 100644 --- a/ledger/store/src/helpers/rocksdb/transaction.rs +++ b/ledger/store/src/helpers/rocksdb/transaction.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,6 +14,15 @@ // limitations under the License. use crate::{ + DeploymentStorage, + DeploymentStore, + ExecutionStorage, + ExecutionStore, + FeeStorage, + FeeStore, + TransactionStorage, + TransactionType, + TransitionStore, helpers::rocksdb::{ self, DataMap, @@ -24,15 +34,6 @@ use crate::{ TransactionMap, TransitionDB, }, - DeploymentStorage, - DeploymentStore, - ExecutionStorage, - ExecutionStore, - FeeStorage, - FeeStore, - TransactionStorage, - TransactionType, - TransitionStore, }; use console::{ prelude::*, diff --git a/ledger/store/src/helpers/rocksdb/transition.rs b/ledger/store/src/helpers/rocksdb/transition.rs index 8c636a10ec..0b6e801c71 100644 --- a/ledger/store/src/helpers/rocksdb/transition.rs +++ b/ledger/store/src/helpers/rocksdb/transition.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,12 +14,12 @@ // limitations under the License. use crate::{ - helpers::rocksdb::{self, DataMap, Database, MapID, TransitionInputMap, TransitionMap, TransitionOutputMap}, InputStorage, InputStore, OutputStorage, OutputStore, TransitionStorage, + helpers::rocksdb::{self, DataMap, Database, MapID, TransitionInputMap, TransitionMap, TransitionOutputMap}, }; use console::{ prelude::*, @@ -45,6 +46,8 @@ pub struct TransitionDB { tcm_map: DataMap>, /// The reverse `tcm` map. reverse_tcm_map: DataMap, N::TransitionID>, + /// The signer commitments. + scm_map: DataMap>, } #[rustfmt::skip] @@ -56,6 +59,7 @@ impl TransitionStorage for TransitionDB { type ReverseTPKMap = DataMap, N::TransitionID>; type TCMMap = DataMap>; type ReverseTCMMap = DataMap, N::TransitionID>; + type SCMMap = DataMap>; /// Initializes the transition storage. fn open>(storage: S) -> Result { @@ -66,7 +70,8 @@ impl TransitionStorage for TransitionDB { tpk_map: rocksdb::RocksDB::open_map(N::ID, storage.clone(), MapID::Transition(TransitionMap::TPK))?, reverse_tpk_map: rocksdb::RocksDB::open_map(N::ID, storage.clone(), MapID::Transition(TransitionMap::ReverseTPK))?, tcm_map: rocksdb::RocksDB::open_map(N::ID, storage.clone(), MapID::Transition(TransitionMap::TCM))?, - reverse_tcm_map: rocksdb::RocksDB::open_map(N::ID, storage, MapID::Transition(TransitionMap::ReverseTCM))?, + reverse_tcm_map: rocksdb::RocksDB::open_map(N::ID, storage.clone(), MapID::Transition(TransitionMap::ReverseTCM))?, + scm_map: rocksdb::RocksDB::open_map(N::ID, storage.clone(), MapID::Transition(TransitionMap::SCM))?, }) } @@ -104,6 +109,11 @@ impl TransitionStorage for TransitionDB { fn reverse_tcm_map(&self) -> &Self::ReverseTCMMap { &self.reverse_tcm_map } + + /// Returns the signer commitments. + fn scm_map(&self) -> &Self::SCMMap { + &self.scm_map + } } /// An database transition input storage. diff --git a/ledger/store/src/helpers/test_helpers/map/check_atomic_writes_are_batched.rs b/ledger/store/src/helpers/test_helpers/map/check_atomic_writes_are_batched.rs index e27b9a532b..22cc8a22ee 100644 --- a/ledger/store/src/helpers/test_helpers/map/check_atomic_writes_are_batched.rs +++ b/ledger/store/src/helpers/test_helpers/map/check_atomic_writes_are_batched.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/map/check_atomic_writes_can_be_aborted.rs b/ledger/store/src/helpers/test_helpers/map/check_atomic_writes_can_be_aborted.rs index e238fdfee6..248444dfbc 100644 --- a/ledger/store/src/helpers/test_helpers/map/check_atomic_writes_can_be_aborted.rs +++ b/ledger/store/src/helpers/test_helpers/map/check_atomic_writes_can_be_aborted.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/map/check_contains_key.rs b/ledger/store/src/helpers/test_helpers/map/check_contains_key.rs index cde5881d98..4e6ed265a0 100644 --- a/ledger/store/src/helpers/test_helpers/map/check_contains_key.rs +++ b/ledger/store/src/helpers/test_helpers/map/check_contains_key.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/map/check_insert_and_get_speculative.rs b/ledger/store/src/helpers/test_helpers/map/check_insert_and_get_speculative.rs index b10aa93afe..e071baee88 100644 --- a/ledger/store/src/helpers/test_helpers/map/check_insert_and_get_speculative.rs +++ b/ledger/store/src/helpers/test_helpers/map/check_insert_and_get_speculative.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/map/check_iterators_match.rs b/ledger/store/src/helpers/test_helpers/map/check_iterators_match.rs index 386c1e36d7..a51db1515a 100644 --- a/ledger/store/src/helpers/test_helpers/map/check_iterators_match.rs +++ b/ledger/store/src/helpers/test_helpers/map/check_iterators_match.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/map/check_remove_and_get_speculative.rs b/ledger/store/src/helpers/test_helpers/map/check_remove_and_get_speculative.rs index e686abe226..3b452c598d 100644 --- a/ledger/store/src/helpers/test_helpers/map/check_remove_and_get_speculative.rs +++ b/ledger/store/src/helpers/test_helpers/map/check_remove_and_get_speculative.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/map/mod.rs b/ledger/store/src/helpers/test_helpers/map/mod.rs index 94bf296e4f..64da072d78 100644 --- a/ledger/store/src/helpers/test_helpers/map/mod.rs +++ b/ledger/store/src/helpers/test_helpers/map/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/mod.rs b/ledger/store/src/helpers/test_helpers/mod.rs index 3a94764b25..e0411c9a9c 100644 --- a/ledger/store/src/helpers/test_helpers/mod.rs +++ b/ledger/store/src/helpers/test_helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/nested_map/check_atomic_writes_are_batched.rs b/ledger/store/src/helpers/test_helpers/nested_map/check_atomic_writes_are_batched.rs index 694575e3f6..e27185d008 100644 --- a/ledger/store/src/helpers/test_helpers/nested_map/check_atomic_writes_are_batched.rs +++ b/ledger/store/src/helpers/test_helpers/nested_map/check_atomic_writes_are_batched.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/nested_map/check_atomic_writes_can_be_aborted.rs b/ledger/store/src/helpers/test_helpers/nested_map/check_atomic_writes_can_be_aborted.rs index c2182d129c..bc733f30a5 100644 --- a/ledger/store/src/helpers/test_helpers/nested_map/check_atomic_writes_can_be_aborted.rs +++ b/ledger/store/src/helpers/test_helpers/nested_map/check_atomic_writes_can_be_aborted.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/nested_map/check_contains_key.rs b/ledger/store/src/helpers/test_helpers/nested_map/check_contains_key.rs index b7c4f79596..1625be7bda 100644 --- a/ledger/store/src/helpers/test_helpers/nested_map/check_contains_key.rs +++ b/ledger/store/src/helpers/test_helpers/nested_map/check_contains_key.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/nested_map/check_get_map.rs b/ledger/store/src/helpers/test_helpers/nested_map/check_get_map.rs index a57f6819f0..5cc3ad889b 100644 --- a/ledger/store/src/helpers/test_helpers/nested_map/check_get_map.rs +++ b/ledger/store/src/helpers/test_helpers/nested_map/check_get_map.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/nested_map/check_insert_and_get_value_speculative.rs b/ledger/store/src/helpers/test_helpers/nested_map/check_insert_and_get_value_speculative.rs index c2689e6cd1..78fd100ed9 100644 --- a/ledger/store/src/helpers/test_helpers/nested_map/check_insert_and_get_value_speculative.rs +++ b/ledger/store/src/helpers/test_helpers/nested_map/check_insert_and_get_value_speculative.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/nested_map/check_iterators_match.rs b/ledger/store/src/helpers/test_helpers/nested_map/check_iterators_match.rs index 19ba023e0b..5fbd2ae3be 100644 --- a/ledger/store/src/helpers/test_helpers/nested_map/check_iterators_match.rs +++ b/ledger/store/src/helpers/test_helpers/nested_map/check_iterators_match.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/nested_map/check_remove_and_get_value_speculative.rs b/ledger/store/src/helpers/test_helpers/nested_map/check_remove_and_get_value_speculative.rs index 8889c828ca..ea814aba1f 100644 --- a/ledger/store/src/helpers/test_helpers/nested_map/check_remove_and_get_value_speculative.rs +++ b/ledger/store/src/helpers/test_helpers/nested_map/check_remove_and_get_value_speculative.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/test_helpers/nested_map/mod.rs b/ledger/store/src/helpers/test_helpers/nested_map/mod.rs index b39f1a4c30..a8e833fd38 100644 --- a/ledger/store/src/helpers/test_helpers/nested_map/mod.rs +++ b/ledger/store/src/helpers/test_helpers/nested_map/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/traits/map.rs b/ledger/store/src/helpers/traits/map.rs index b0eef6a4ac..15dc60babd 100644 --- a/ledger/store/src/helpers/traits/map.rs +++ b/ledger/store/src/helpers/traits/map.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/traits/mod.rs b/ledger/store/src/helpers/traits/mod.rs index dea20c2ef0..db111021e7 100644 --- a/ledger/store/src/helpers/traits/mod.rs +++ b/ledger/store/src/helpers/traits/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/helpers/traits/nested_map.rs b/ledger/store/src/helpers/traits/nested_map.rs index 263dffc551..3052694bbc 100644 --- a/ledger/store/src/helpers/traits/nested_map.rs +++ b/ledger/store/src/helpers/traits/nested_map.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/lib.rs b/ledger/store/src/lib.rs index 9d50462adc..6eb10f7b69 100644 --- a/ledger/store/src/lib.rs +++ b/ledger/store/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -52,7 +53,7 @@ macro_rules! cow_to_cloned { }; } -use console::prelude::{bail, Result}; +use console::prelude::{Result, bail}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum FinalizeMode { diff --git a/ledger/store/src/program/committee.rs b/ledger/store/src/program/committee.rs index aad82c6c34..a3261e99d1 100644 --- a/ledger/store/src/program/committee.rs +++ b/ledger/store/src/program/committee.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -413,7 +414,7 @@ mod tests { use super::*; use crate::helpers::memory::CommitteeMemory; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; #[test] fn test_insert_get_remove() { diff --git a/ledger/store/src/program/finalize.rs b/ledger/store/src/program/finalize.rs index 1e227b7bfb..f0662a6feb 100644 --- a/ledger/store/src/program/finalize.rs +++ b/ledger/store/src/program/finalize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -244,7 +245,7 @@ pub trait FinalizeStorage: 'static + Clone + Send + Sync { })?; // Return the finalize operation. - Ok(FinalizeOperation::UpdateKeyValue(to_mapping_id(&program_id, &mapping_name)?, 0u64, key_id, value_id)) + Ok(FinalizeOperation::UpdateKeyValue(to_mapping_id(&program_id, &mapping_name)?, key_id, value_id)) } /// Removes the key-value pair for the given `program ID`, `mapping name`, and `key` from storage. @@ -264,6 +265,9 @@ pub trait FinalizeStorage: 'static + Clone + Send + Sync { return Ok(None); } + // Compute the key ID. + let key_id = to_key_id(&program_id, &mapping_name, key)?; + atomic_batch_scope!(self, { // Update the key-value map with the new key. self.key_value_map().remove_key(&(program_id, mapping_name), key)?; @@ -272,7 +276,7 @@ pub trait FinalizeStorage: 'static + Clone + Send + Sync { })?; // Return the finalize operation. - Ok(Some(FinalizeOperation::RemoveKeyValue(to_mapping_id(&program_id, &mapping_name)?, 0u64))) + Ok(Some(FinalizeOperation::RemoveKeyValue(to_mapping_id(&program_id, &mapping_name)?, key_id))) } /// Replaces the mapping for the given `program ID` and `mapping name` from storage, @@ -769,9 +773,9 @@ impl> FinalizeStore { mod tests { use super::*; use crate::helpers::memory::FinalizeMemory; - use console::{network::Testnet3, program::Literal, types::U64}; + use console::{network::MainnetV0, program::Literal, types::U64}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Checks `initialize_mapping`, `insert_key_value`, `remove_key_value`, and `remove_mapping`. fn check_initialize_insert_remove( @@ -1314,7 +1318,7 @@ mod tests { // Insert the key and value. let timer = std::time::Instant::now(); - finalize_store.insert_key_value(program_id, mapping_name, key.clone(), value.clone()).unwrap(); + finalize_store.insert_key_value(program_id, mapping_name, key.clone(), value).unwrap(); println!("FinalizeStore::insert_key_value - {} μs", timer.elapsed().as_micros()); // Insert the list of keys and values. diff --git a/ledger/store/src/program/mod.rs b/ledger/store/src/program/mod.rs index 435debde8b..3da9877418 100644 --- a/ledger/store/src/program/mod.rs +++ b/ledger/store/src/program/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/transaction/deployment.rs b/ledger/store/src/transaction/deployment.rs index bdc7d95b46..a0c3d685a7 100644 --- a/ledger/store/src/transaction/deployment.rs +++ b/ledger/store/src/transaction/deployment.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,12 +14,12 @@ // limitations under the License. use crate::{ + FeeStorage, + FeeStore, atomic_batch_scope, cow_to_cloned, cow_to_copied, helpers::{Map, MapRead}, - FeeStorage, - FeeStore, }; use console::{ network::prelude::*, @@ -342,7 +343,12 @@ pub trait DeploymentStorage: Clone + Send + Sync { if program_id == &ProgramID::from_str("credits.aleo")? { // Load the verifying key. let verifying_key = N::get_credits_verifying_key(function_name.to_string())?; - return Ok(Some(VerifyingKey::new(verifying_key.clone()))); + // Retrieve the number of public and private variables. + // Note: This number does *NOT* include the number of constants. This is safe because + // this program is never deployed, as it is a first-class citizen of the protocol. + let num_variables = verifying_key.circuit_info.num_public_and_private_variables as u64; + // Return the verifying key. + return Ok(Some(VerifyingKey::new(verifying_key.clone(), num_variables))); } // Retrieve the edition. @@ -666,7 +672,7 @@ impl> DeploymentStore { #[cfg(test)] mod tests { use super::*; - use crate::{helpers::memory::DeploymentMemory, TransitionStore}; + use crate::{TransitionStore, helpers::memory::DeploymentMemory}; #[test] fn test_insert_get_remove() { diff --git a/ledger/store/src/transaction/execution.rs b/ledger/store/src/transaction/execution.rs index 39c11f4c79..089372b788 100644 --- a/ledger/store/src/transaction/execution.rs +++ b/ledger/store/src/transaction/execution.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,13 +14,13 @@ // limitations under the License. use crate::{ + FeeStorage, + FeeStore, + TransitionStore, atomic_batch_scope, cow_to_cloned, cow_to_copied, helpers::{Map, MapRead}, - FeeStorage, - FeeStore, - TransitionStore, }; use console::network::prelude::*; use ledger_block::{Execution, Transaction, Transition}; @@ -392,9 +393,9 @@ impl> ExecutionStore { #[cfg(test)] mod tests { use super::*; - use crate::{helpers::memory::ExecutionMemory, TransitionStore}; + use crate::{TransitionStore, helpers::memory::ExecutionMemory}; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; fn insert_get_remove(transaction: Transaction) -> Result<()> { let transaction_id = transaction.id(); diff --git a/ledger/store/src/transaction/fee.rs b/ledger/store/src/transaction/fee.rs index f821afaea8..a757d73981 100644 --- a/ledger/store/src/transaction/fee.rs +++ b/ledger/store/src/transaction/fee.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,12 +14,12 @@ // limitations under the License. use crate::{ + TransitionStorage, + TransitionStore, atomic_batch_scope, cow_to_cloned, cow_to_copied, helpers::{Map, MapRead}, - TransitionStorage, - TransitionStore, }; use console::network::prelude::*; use ledger_block::Fee; diff --git a/ledger/store/src/transaction/mod.rs b/ledger/store/src/transaction/mod.rs index 7d62c529b1..1bb6966e1d 100644 --- a/ledger/store/src/transaction/mod.rs +++ b/ledger/store/src/transaction/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -22,11 +23,11 @@ mod fee; pub use fee::*; use crate::{ + TransitionStorage, + TransitionStore, atomic_batch_scope, cow_to_copied, helpers::{Map, MapRead}, - TransitionStorage, - TransitionStore, }; use console::{ network::prelude::*, diff --git a/ledger/store/src/transition/input.rs b/ledger/store/src/transition/input.rs index 33ba49dc71..8889d344a4 100644 --- a/ledger/store/src/transition/input.rs +++ b/ledger/store/src/transition/input.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/store/src/transition/mod.rs b/ledger/store/src/transition/mod.rs index 074c4756be..bb0eff8629 100644 --- a/ledger/store/src/transition/mod.rs +++ b/ledger/store/src/transition/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -51,6 +52,8 @@ pub trait TransitionStorage: Clone + Send + Sync { type TCMMap: for<'a> Map<'a, N::TransitionID, Field>; /// The mapping of `transition commitment` to `transition ID`. type ReverseTCMMap: for<'a> Map<'a, Field, N::TransitionID>; + /// The signer commitments. + type SCMMap: for<'a> Map<'a, N::TransitionID, Field>; /// Initializes the transition storage. fn open>(storage: S) -> Result; @@ -69,6 +72,8 @@ pub trait TransitionStorage: Clone + Send + Sync { fn tcm_map(&self) -> &Self::TCMMap; /// Returns the reverse `tcm` map. fn reverse_tcm_map(&self) -> &Self::ReverseTCMMap; + /// Returns the signer commitments map. + fn scm_map(&self) -> &Self::SCMMap; /// Returns the storage mode. fn storage_mode(&self) -> &StorageMode { @@ -85,6 +90,7 @@ pub trait TransitionStorage: Clone + Send + Sync { self.reverse_tpk_map().start_atomic(); self.tcm_map().start_atomic(); self.reverse_tcm_map().start_atomic(); + self.scm_map().start_atomic(); } /// Checks if an atomic batch is in progress. @@ -96,6 +102,7 @@ pub trait TransitionStorage: Clone + Send + Sync { || self.reverse_tpk_map().is_atomic_in_progress() || self.tcm_map().is_atomic_in_progress() || self.reverse_tcm_map().is_atomic_in_progress() + || self.scm_map().is_atomic_in_progress() } /// Checkpoints the atomic batch. @@ -107,6 +114,7 @@ pub trait TransitionStorage: Clone + Send + Sync { self.reverse_tpk_map().atomic_checkpoint(); self.tcm_map().atomic_checkpoint(); self.reverse_tcm_map().atomic_checkpoint(); + self.scm_map().atomic_checkpoint(); } /// Clears the latest atomic batch checkpoint. @@ -118,6 +126,7 @@ pub trait TransitionStorage: Clone + Send + Sync { self.reverse_tpk_map().clear_latest_checkpoint(); self.tcm_map().clear_latest_checkpoint(); self.reverse_tcm_map().clear_latest_checkpoint(); + self.scm_map().clear_latest_checkpoint(); } /// Rewinds the atomic batch to the previous checkpoint. @@ -129,6 +138,7 @@ pub trait TransitionStorage: Clone + Send + Sync { self.reverse_tpk_map().atomic_rewind(); self.tcm_map().atomic_rewind(); self.reverse_tcm_map().atomic_rewind(); + self.scm_map().atomic_rewind(); } /// Aborts an atomic batch write operation. @@ -140,6 +150,7 @@ pub trait TransitionStorage: Clone + Send + Sync { self.reverse_tpk_map().abort_atomic(); self.tcm_map().abort_atomic(); self.reverse_tcm_map().abort_atomic(); + self.scm_map().abort_atomic(); } /// Finishes an atomic batch write operation. @@ -150,7 +161,8 @@ pub trait TransitionStorage: Clone + Send + Sync { self.tpk_map().finish_atomic()?; self.reverse_tpk_map().finish_atomic()?; self.tcm_map().finish_atomic()?; - self.reverse_tcm_map().finish_atomic() + self.reverse_tcm_map().finish_atomic()?; + self.scm_map().finish_atomic() } /// Stores the given `transition` into storage. @@ -172,6 +184,8 @@ pub trait TransitionStorage: Clone + Send + Sync { self.tcm_map().insert(transition_id, *transition.tcm())?; // Store the reverse `tcm` entry. self.reverse_tcm_map().insert(*transition.tcm(), transition_id)?; + // Store `scm`. + self.scm_map().insert(transition_id, *transition.scm())?; Ok(()) }) @@ -205,6 +219,8 @@ pub trait TransitionStorage: Clone + Send + Sync { self.tcm_map().remove(transition_id)?; // Remove the reverse `tcm` entry. self.reverse_tcm_map().remove(&tcm)?; + // Remove `scm`. + self.scm_map().remove(transition_id)?; Ok(()) }) @@ -225,9 +241,11 @@ pub trait TransitionStorage: Clone + Send + Sync { let tpk = self.tpk_map().get_confirmed(transition_id)?; // Retrieve `tcm`. let tcm = self.tcm_map().get_confirmed(transition_id)?; + // Retrieve `scm`. + let scm = self.scm_map().get_confirmed(transition_id)?; - match (tpk, tcm) { - (Some(tpk), Some(tcm)) => { + match (tpk, tcm, scm) { + (Some(tpk), Some(tcm), Some(scm)) => { // Construct the transition. let transition = Transition::new( program_id, @@ -236,6 +254,7 @@ pub trait TransitionStorage: Clone + Send + Sync { outputs, cow_to_cloned!(tpk), cow_to_cloned!(tcm), + cow_to_cloned!(scm), )?; // Ensure the transition ID matches. match transition.id() == transition_id { @@ -265,6 +284,8 @@ pub struct TransitionStore> { tcm: T::TCMMap, /// The reverse `tcm` map. reverse_tcm: T::ReverseTCMMap, + /// The map of signer commitments. + scm: T::SCMMap, /// The transition storage. storage: T, } @@ -283,6 +304,7 @@ impl> TransitionStore { reverse_tpk: storage.reverse_tpk_map().clone(), tcm: storage.tcm_map().clone(), reverse_tcm: storage.reverse_tcm_map().clone(), + scm: storage.scm_map().clone(), storage, }) } @@ -297,6 +319,7 @@ impl> TransitionStore { reverse_tpk: storage.reverse_tpk_map().clone(), tcm: storage.tcm_map().clone(), reverse_tcm: storage.reverse_tcm_map().clone(), + scm: storage.scm_map().clone(), storage, } } @@ -615,6 +638,11 @@ impl> TransitionStore { pub fn tcms(&self) -> impl '_ + Iterator>> { self.tcm.values_confirmed() } + + /// Returns an iterator over the signer commitments, for all transitions. + pub fn scms(&self) -> impl '_ + Iterator>> { + self.scm.values_confirmed() + } } #[cfg(test)] diff --git a/ledger/store/src/transition/output.rs b/ledger/store/src/transition/output.rs index 01acfa41cb..30d53bcc4b 100644 --- a/ledger/store/src/transition/output.rs +++ b/ledger/store/src/transition/output.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/ledger/test-helpers/Cargo.toml b/ledger/test-helpers/Cargo.toml index eba63ce2ee..a07898640f 100644 --- a/ledger/test-helpers/Cargo.toml +++ b/ledger/test-helpers/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-ledger-test-helpers" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Test helpers for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -19,39 +19,39 @@ edition = "2021" [dependencies.console] package = "snarkvm-console" path = "../../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.circuit] package = "snarkvm-circuit" path = "../../circuit" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-block] package = "snarkvm-ledger-block" path = "../block" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-query] package = "snarkvm-ledger-query" path = "../query" -version = "=0.16.19" +version = "=1.1.0" default-features = false features = [ "query" ] [dependencies.ledger-store] package = "snarkvm-ledger-store" path = "../store" -version = "=0.16.19" +version = "=1.1.0" [dependencies.synthesizer-program] package = "snarkvm-synthesizer-program" path = "../../synthesizer/program" -version = "=0.16.19" +version = "=1.1.0" [dependencies.synthesizer-process] package = "snarkvm-synthesizer-process" path = "../../synthesizer/process" -version = "=0.16.19" +version = "=1.1.0" [dependencies.once_cell] version = "1.18" diff --git a/ledger/test-helpers/src/lib.rs b/ledger/test-helpers/src/lib.rs index eac0196063..7d789c6fdd 100644 --- a/ledger/test-helpers/src/lib.rs +++ b/ledger/test-helpers/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,7 +16,7 @@ use console::{ account::{Address, PrivateKey}, prelude::*, - program::{Ciphertext, Literal, Plaintext, ProgramOwner, Record}, + program::{Ciphertext, Literal, Plaintext, ProgramOwner, Record, Value}, types::Field, }; use ledger_block::{ @@ -28,18 +29,19 @@ use ledger_block::{ Input, Output, Ratifications, + Rejected, Transaction, Transactions, Transition, }; use ledger_query::Query; -use ledger_store::{helpers::memory::BlockMemory, BlockStore}; +use ledger_store::{BlockStore, helpers::memory::BlockMemory}; use synthesizer_process::Process; use synthesizer_program::Program; use once_cell::sync::OnceCell; -type CurrentNetwork = console::network::Testnet3; +type CurrentNetwork = console::network::MainnetV0; type CurrentAleo = circuit::network::AleoV0; /****************************************** Transition ********************************************/ @@ -158,6 +160,23 @@ function compute: .clone() } +/// Samples a rejected deployment. +pub fn sample_rejected_deployment(is_fee_private: bool, rng: &mut TestRng) -> Rejected { + // Sample a deploy transaction. + let deployment = match crate::sample_deployment_transaction(is_fee_private, rng) { + Transaction::Deploy(_, _, deployment, _) => (*deployment).clone(), + _ => unreachable!(), + }; + + // Sample a new program owner. + let private_key = PrivateKey::new(rng).unwrap(); + let deployment_id = deployment.to_deployment_id().unwrap(); + let program_owner = ProgramOwner::new(&private_key, deployment_id, rng).unwrap(); + + // Return the rejected deployment. + Rejected::new_deployment(program_owner, deployment) +} + /******************************************* Execution ********************************************/ /// Samples a random execution. @@ -170,6 +189,18 @@ pub fn sample_execution(rng: &mut TestRng) -> Execution { if let Transaction::Execute(_, execution, _) = transaction { execution } else { unreachable!() } } +/// Samples a rejected execution. +pub fn sample_rejected_execution(is_fee_private: bool, rng: &mut TestRng) -> Rejected { + // Sample an execute transaction. + let execution = match crate::sample_execution_transaction_with_fee(is_fee_private, rng) { + Transaction::Execute(_, execution, _) => execution, + _ => unreachable!(), + }; + + // Return the rejected execution. + Rejected::new_execution(execution) +} + /********************************************** Fee ***********************************************/ /// Samples a random hardcoded private fee. @@ -283,6 +314,40 @@ pub fn sample_fee_public(deployment_or_execution_id: Field, rng: Fee::from_str(&fee.to_string()).unwrap() } +/******************************************** Program *********************************************/ + +/// Deploy a program that produces large transactions under the maximum transaction size. +pub fn small_transaction_program() -> Program { + Program::from_str( + r" +program testing_small.aleo; +function small_transaction: + cast 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field into r0 as [field; 32u32]; + cast r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 into r1 as [[field; 32u32]; 32u32]; + cast r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 into r2 as [[field; 32u32]; 32u32]; + cast r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 into r3 as [[field; 32u32]; 32u32]; + output r1 as [[field; 32u32]; 32u32].public; + output r2 as [[field; 32u32]; 32u32].public; + output r3 as [[field; 32u32]; 32u32].public;").unwrap() +} + +/// Deploy a program that produces large transactions above the maximum transaction size. +pub fn large_transaction_program() -> Program { + Program::from_str( + r" +program testing_large.aleo; +function large_transaction: + cast 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field 0field into r0 as [field; 32u32]; + cast r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 into r1 as [[field; 32u32]; 27u32]; + cast r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 into r2 as [[field; 32u32]; 27u32]; + cast r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 into r3 as [[field; 32u32]; 27u32]; + cast r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 into r4 as [[field; 32u32]; 27u32]; + output r1 as [[field; 32u32]; 27u32].public; + output r2 as [[field; 32u32]; 27u32].public; + output r3 as [[field; 32u32]; 27u32].public; + output r4 as [[field; 32u32]; 27u32].public;").unwrap() +} + /****************************************** Transaction *******************************************/ /// Samples a random deployment transaction with a private or public fee. @@ -324,6 +389,61 @@ pub fn sample_execution_transaction_with_fee(is_fee_private: bool, rng: &mut Tes Transaction::from_execution(execution, Some(fee)).unwrap() } +/// Samples a large transaction. +pub fn sample_large_execution_transaction(rng: &mut TestRng) -> Transaction { + static INSTANCE: once_cell::sync::OnceCell> = once_cell::sync::OnceCell::new(); + + let execution = INSTANCE + .get_or_init(|| { + // Initialize a program that produces large transactions. + let program = large_transaction_program(); + + // Construct the process. + let mut process = synthesizer_process::Process::load().unwrap(); + // Add the program. + process.add_program(&program).unwrap(); + + // Initialize a private key. + let private_key = PrivateKey::new(rng).unwrap(); + + // Authorize the function. + let authorization = process + .authorize::( + &private_key, + "testing_large.aleo", + "large_transaction", + Vec::>::new().iter(), + rng, + ) + .unwrap(); + // Execute the function. + let (_, mut trace) = process.execute::(authorization, rng).unwrap(); + + // Initialize a new block store. + let block_store = + ledger_store::BlockStore::>::open(None) + .unwrap(); + + // Prepare the assignments. + trace.prepare(ledger_query::Query::from(block_store)).unwrap(); + // Compute the proof and construct the execution. + let execution = trace.prove_execution::("testing.aleo", rng).unwrap(); + // Reconstruct the execution from bytes. + // This is a hack to get around Rust dependency resolution. + Execution::from_bytes_le(&execution.to_bytes_le().unwrap()).unwrap() + }) + .clone(); + + // Compute the execution ID. + let execution_id = execution.to_execution_id().unwrap(); + + // Sample the fee. + let fee = crate::sample_fee_public(execution_id, rng); + + // Construct an execution transaction. + Transaction::from_execution(execution, Some(fee)).unwrap() +} + /// Samples a random private fee transaction. pub fn sample_fee_private_transaction(rng: &mut TestRng) -> Transaction { // Sample a private fee. @@ -424,8 +544,18 @@ fn sample_genesis_block_and_components_raw( let previous_hash = ::BlockHash::default(); // Construct the block. - let block = - Block::new_beacon(&private_key, previous_hash, header, ratifications, None, transactions, vec![], rng).unwrap(); + let block = Block::new_beacon( + &private_key, + previous_hash, + header, + ratifications, + None.into(), + vec![], + transactions, + vec![], + rng, + ) + .unwrap(); assert!(block.header().is_genesis(), "Failed to initialize a genesis block"); // Return the block, transaction, and private key. (block, transaction, private_key) diff --git a/metrics/Cargo.toml b/metrics/Cargo.toml index 457d43f039..1e192d82af 100644 --- a/metrics/Cargo.toml +++ b/metrics/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-metrics" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Metrics for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", diff --git a/metrics/src/lib.rs b/metrics/src/lib.rs index 81cfa46bbd..3d8f42ed16 100644 --- a/metrics/src/lib.rs +++ b/metrics/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -98,3 +99,7 @@ pub fn histogram>(name: &'static str, value: V) { let histogram = ::metrics::histogram!(name); histogram.record(value.into()); } + +pub fn histogram_label>(name: &'static str, label_key: &'static str, label_value: String, value: V) { + ::metrics::histogram!(name, label_key => label_value).record(value.into()); +} diff --git a/parameters/Cargo.toml b/parameters/Cargo.toml index d735149b19..c4e6f93496 100644 --- a/parameters/Cargo.toml +++ b/parameters/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-parameters" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Parameters for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -31,12 +31,12 @@ wasm = [ "encoding", "js-sys", "web-sys" ] [dependencies.snarkvm-curves] path = "../curves" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.snarkvm-utilities] path = "../utilities" -version = "=0.16.19" +version = "=1.1.0" [dependencies.aleo-std] version = "0.1.24" @@ -115,6 +115,9 @@ path = "../circuit" [dev-dependencies.snarkvm-console] path = "../console" +[dev-dependencies.snarkvm-ledger-block] +path = "../ledger/block" + [dev-dependencies.snarkvm-ledger-store] path = "../ledger/store" diff --git a/parameters/examples/inclusion.rs b/parameters/examples/inclusion.rs index e7d0812197..dc241cbd95 100644 --- a/parameters/examples/inclusion.rs +++ b/parameters/examples/inclusion.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,17 +17,17 @@ use snarkvm_algorithms::crypto_hash::sha256::sha256; use snarkvm_circuit::{Aleo, Assignment}; use snarkvm_console::{ account::PrivateKey, - network::{Network, Testnet3}, + network::{CanaryV0, MainnetV0, Network, TestnetV0}, prelude::{One, ToBytes, Zero}, program::{Plaintext, Record, StatePath}, types::Field, }; -use snarkvm_ledger_store::{helpers::memory::ConsensusMemory, ConsensusStore}; -use snarkvm_synthesizer::{process::InclusionAssignment, snark::UniversalSRS, VM}; +use snarkvm_ledger_store::{ConsensusStore, helpers::memory::ConsensusMemory}; +use snarkvm_synthesizer::{VM, process::InclusionAssignment, snark::UniversalSRS}; -use anyhow::{anyhow, Result}; +use anyhow::{Result, anyhow}; use rand::thread_rng; -use serde_json::{json, Value}; +use serde_json::{Value, json}; use std::{ fs::File, io::{BufWriter, Write}, @@ -170,8 +171,14 @@ pub fn main() -> Result<()> { } match args[1].as_str() { - "testnet3" => { - inclusion::()?; + "mainnet" => { + inclusion::()?; + } + "testnet" => { + inclusion::()?; + } + "canary" => { + inclusion::()?; } _ => panic!("Invalid network"), }; diff --git a/parameters/examples/setup.rs b/parameters/examples/setup.rs index b7c5765652..323581081a 100644 --- a/parameters/examples/setup.rs +++ b/parameters/examples/setup.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,11 +15,11 @@ use snarkvm_algorithms::crypto_hash::sha256::sha256; use snarkvm_circuit::Aleo; -use snarkvm_console::network::{prelude::ToBytes, Network, Testnet3}; +use snarkvm_console::network::{CanaryV0, MainnetV0, Network, TestnetV0, prelude::ToBytes}; use snarkvm_synthesizer::{Process, Program}; use anyhow::Result; -use serde_json::{json, Value}; +use serde_json::{Value, json}; use std::{ fs, fs::File, @@ -60,7 +61,7 @@ fn write_metadata(filename: &str, metadata: &Value) -> Result<()> { /// (Do not use) Writes the metadata files. (cargo run --release --example setup usrs) pub fn usrs() -> Result<()> { - let paths = fs::read_dir("../src/testnet3/resources/").unwrap(); + let paths = fs::read_dir("../src/mainnet/resources/").unwrap(); for path in paths { let path = path?.path(); if let Some("usrs") = path.extension().and_then(|s| s.to_str()) { @@ -142,14 +143,19 @@ pub fn credits_program>() -> Result<()> { /// `cargo run --example setup [variant]` pub fn main() -> Result<()> { let args: Vec = std::env::args().collect(); - if args.len() < 2 { - eprintln!("Invalid number of arguments. Given: {} - Required: 1", args.len() - 1); + if args.len() < 3 { + eprintln!("Invalid number of arguments. Given: {} - Required: 2", args.len() - 1); return Ok(()); } match args[1].as_str() { "usrs" => usrs()?, - "credits" => credits_program::()?, + "credits" => match args[2].as_str() { + "mainnet" => credits_program::(), + "testnet" => credits_program::(), + "canary" => credits_program::(), + _ => panic!("Invalid network"), + }?, _ => panic!("Invalid parameter"), }; diff --git a/parameters/scripts/README.md b/parameters/scripts/README.md index 12185721de..02dd421eb7 100644 --- a/parameters/scripts/README.md +++ b/parameters/scripts/README.md @@ -1,6 +1,6 @@ # Parameter Scripts These scripts will run the parameter setup programs in the `examples` folder and move the resulting `.params` -and `.checksum` files to `testnet*` folder under the `src` directory. +and `.checksum` files to `mainnet*` folder under the `src` directory. If the parameter size has changed, you will need to manually update these in each corresponding struct. diff --git a/parameters/scripts/canary/credits.sh b/parameters/scripts/canary/credits.sh new file mode 100755 index 0000000000..5b816dfb84 --- /dev/null +++ b/parameters/scripts/canary/credits.sh @@ -0,0 +1,9 @@ +# Generate proving and verifying keys. + +# Inputs: program name + +cargo run --release --example setup credits canary -- --nocapture || exit + +mv *.metadata ../../src/canary/resources || exit +mv *.prover.* ~/.aleo/resources || exit +mv *.verifier ../../src/canary/resources || exit diff --git a/parameters/scripts/canary/inclusion.sh b/parameters/scripts/canary/inclusion.sh new file mode 100755 index 0000000000..339e1615af --- /dev/null +++ b/parameters/scripts/canary/inclusion.sh @@ -0,0 +1,9 @@ +# Generates the inclusion proving and verifying key. + +# Inputs: network + +cargo run --release --example inclusion canary -- --nocapture || exit + +mv inclusion.metadata ../../src/canary/resources || exit +mv inclusion.prover.* ~/.aleo/resources || exit +mv inclusion.verifier ../../src/canary/resources || exit diff --git a/parameters/scripts/mainnet/credits.sh b/parameters/scripts/mainnet/credits.sh new file mode 100755 index 0000000000..7f2cebdb47 --- /dev/null +++ b/parameters/scripts/mainnet/credits.sh @@ -0,0 +1,9 @@ +# Generate proving and verifying keys. + +# Inputs: program name + +cargo run --release --example setup credits mainnet -- --nocapture || exit + +mv *.metadata ../../src/mainnet/resources || exit +mv *.prover.* ~/.aleo/resources || exit +mv *.verifier ../../src/mainnet/resources || exit diff --git a/parameters/scripts/mainnet/inclusion.sh b/parameters/scripts/mainnet/inclusion.sh new file mode 100755 index 0000000000..f9f6d7797e --- /dev/null +++ b/parameters/scripts/mainnet/inclusion.sh @@ -0,0 +1,9 @@ +# Generates the inclusion proving and verifying key. + +# Inputs: network + +cargo run --release --example inclusion mainnet -- --nocapture || exit + +mv inclusion.metadata ../../src/mainnet/resources || exit +mv inclusion.prover.* ~/.aleo/resources || exit +mv inclusion.verifier ../../src/mainnet/resources || exit diff --git a/parameters/scripts/testnet/credits.sh b/parameters/scripts/testnet/credits.sh new file mode 100755 index 0000000000..412aa30ac0 --- /dev/null +++ b/parameters/scripts/testnet/credits.sh @@ -0,0 +1,9 @@ +# Generate proving and verifying keys. + +# Inputs: program name + +cargo run --release --example setup credits testnet -- --nocapture || exit + +mv *.metadata ../../src/testnet/resources || exit +mv *.prover.* ~/.aleo/resources || exit +mv *.verifier ../../src/testnet/resources || exit diff --git a/parameters/scripts/testnet/inclusion.sh b/parameters/scripts/testnet/inclusion.sh new file mode 100755 index 0000000000..f87da63f33 --- /dev/null +++ b/parameters/scripts/testnet/inclusion.sh @@ -0,0 +1,9 @@ +# Generates the inclusion proving and verifying key. + +# Inputs: network + +cargo run --release --example inclusion testnet -- --nocapture || exit + +mv inclusion.metadata ../../src/testnet/resources || exit +mv inclusion.prover.* ~/.aleo/resources || exit +mv inclusion.verifier ../../src/testnet/resources || exit diff --git a/parameters/scripts/testnet3/credits.sh b/parameters/scripts/testnet3/credits.sh deleted file mode 100755 index df8a1a68d0..0000000000 --- a/parameters/scripts/testnet3/credits.sh +++ /dev/null @@ -1,9 +0,0 @@ -# Generate proving and verifying keys. - -# Inputs: program name - -cargo run --release --example setup credits -- --nocapture || exit - -mv *.metadata ../../src/testnet3/resources || exit -mv *.prover.* ~/.aleo/resources || exit -mv *.verifier ../../src/testnet3/resources || exit diff --git a/parameters/scripts/testnet3/inclusion.sh b/parameters/scripts/testnet3/inclusion.sh deleted file mode 100755 index 3472647ec5..0000000000 --- a/parameters/scripts/testnet3/inclusion.sh +++ /dev/null @@ -1,9 +0,0 @@ -# Generates the inclusion proving and verifying key. - -# Inputs: network - -cargo run --release --example inclusion testnet3 -- --nocapture || exit - -mv inclusion.metadata ../../src/testnet3/resources || exit -mv inclusion.prover.* ~/.aleo/resources || exit -mv inclusion.verifier ../../src/testnet3/resources || exit diff --git a/parameters/src/testnet3/genesis.rs b/parameters/src/canary/genesis.rs similarity index 89% rename from parameters/src/testnet3/genesis.rs rename to parameters/src/canary/genesis.rs index 344db0d17e..50030e48db 100644 --- a/parameters/src/testnet3/genesis.rs +++ b/parameters/src/canary/genesis.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -27,6 +28,6 @@ mod tests { #[test] fn test_genesis_block() { let bytes = GenesisBytes::load_bytes(); - assert_eq!(13728, bytes.len() as u64, "Update me if serialization has changed"); + assert_eq!(19241, bytes.len() as u64, "Update me if serialization has changed"); } } diff --git a/parameters/src/canary/mod.rs b/parameters/src/canary/mod.rs new file mode 100644 index 0000000000..9a35444aa0 --- /dev/null +++ b/parameters/src/canary/mod.rs @@ -0,0 +1,141 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +pub mod genesis; +pub use genesis::*; + +/// The restrictions list as a JSON-compatible string. +pub const RESTRICTIONS_LIST: &str = include_str!("./resources/restrictions.json"); + +const REMOTE_URL: &str = "https://parameters.aleo.org/canary"; + +// BondPublic +impl_remote!(BondPublicProver, REMOTE_URL, "resources/", "bond_public", "prover"); +impl_local!(BondPublicVerifier, "resources/", "bond_public", "verifier"); +// BondValidator +impl_remote!(BondValidatorProver, REMOTE_URL, "resources/", "bond_validator", "prover"); +impl_local!(BondValidatorVerifier, "resources/", "bond_validator", "verifier"); +// UnbondPublic +impl_remote!(UnbondPublicProver, REMOTE_URL, "resources/", "unbond_public", "prover"); +impl_local!(UnbondPublicVerifier, "resources/", "unbond_public", "verifier"); +// ClaimUnbondPublic +impl_remote!(ClaimUnbondPublicProver, REMOTE_URL, "resources/", "claim_unbond_public", "prover"); +impl_local!(ClaimUnbondPublicVerifier, "resources/", "claim_unbond_public", "verifier"); +// SetValidatorState +impl_remote!(SetValidatorStateProver, REMOTE_URL, "resources/", "set_validator_state", "prover"); +impl_local!(SetValidatorStateVerifier, "resources/", "set_validator_state", "verifier"); +// TransferPrivate +impl_remote!(TransferPrivateProver, REMOTE_URL, "resources/", "transfer_private", "prover"); +impl_local!(TransferPrivateVerifier, "resources/", "transfer_private", "verifier"); +// TransferPublic +impl_remote!(TransferPublicProver, REMOTE_URL, "resources/", "transfer_public", "prover"); +impl_local!(TransferPublicVerifier, "resources/", "transfer_public", "verifier"); +// TransferPublicAsSigner +impl_remote!(TransferPublicAsSignerProver, REMOTE_URL, "resources/", "transfer_public_as_signer", "prover"); +impl_local!(TransferPublicAsSignerVerifier, "resources/", "transfer_public_as_signer", "verifier"); +// TransferPrivateToPublic +impl_remote!(TransferPrivateToPublicProver, REMOTE_URL, "resources/", "transfer_private_to_public", "prover"); +impl_local!(TransferPrivateToPublicVerifier, "resources/", "transfer_private_to_public", "verifier"); +// TransferPublicToPrivate +impl_remote!(TransferPublicToPrivateProver, REMOTE_URL, "resources/", "transfer_public_to_private", "prover"); +impl_local!(TransferPublicToPrivateVerifier, "resources/", "transfer_public_to_private", "verifier"); +// Join +impl_remote!(JoinProver, REMOTE_URL, "resources/", "join", "prover"); +impl_local!(JoinVerifier, "resources/", "join", "verifier"); +// Split +impl_remote!(SplitProver, REMOTE_URL, "resources/", "split", "prover"); +impl_local!(SplitVerifier, "resources/", "split", "verifier"); +// FeePrivate +impl_remote!(FeePrivateProver, REMOTE_URL, "resources/", "fee_private", "prover"); +impl_local!(FeePrivateVerifier, "resources/", "fee_private", "verifier"); +// FeePublic +impl_remote!(FeePublicProver, REMOTE_URL, "resources/", "fee_public", "prover"); +impl_local!(FeePublicVerifier, "resources/", "fee_public", "verifier"); + +#[macro_export] +macro_rules! insert_canary_credit_keys { + ($map:ident, $type:ident<$network:ident>, $variant:ident) => {{ + paste::paste! { + let string = stringify!([<$variant:lower>]); + $crate::insert_canary_key!($map, string, $type<$network>, ("bond_public", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("bond_validator", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("unbond_public", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("claim_unbond_public", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("set_validator_state", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("transfer_private", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("transfer_public", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("transfer_public_as_signer", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("transfer_private_to_public", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("transfer_public_to_private", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("join", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("split", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("fee_private", $crate::canary::[]::load_bytes())); + $crate::insert_canary_key!($map, string, $type<$network>, ("fee_public", $crate::canary::[]::load_bytes())); + } + }}; +} + +#[macro_export] +macro_rules! insert_canary_key { + ($map:ident, $string:tt, $type:ident<$network:ident>, ($name:tt, $circuit_key:expr)) => {{ + // Load the circuit key bytes. + let key_bytes: Vec = $circuit_key.expect(&format!("Failed to load {} bytes", $string)); + // Recover the circuit key. + let key = $type::<$network>::from_bytes_le(&key_bytes[1..]).expect(&format!("Failed to recover {}", $string)); + // Insert the circuit key. + $map.insert($name.to_string(), std::sync::Arc::new(key)); + }}; +} + +// Inclusion +impl_remote!(InclusionProver, REMOTE_URL, "resources/", "inclusion", "prover"); +impl_local!(InclusionVerifier, "resources/", "inclusion", "verifier"); + +/// The function name for the inclusion circuit. +pub const NETWORK_INCLUSION_FUNCTION_NAME: &str = "inclusion"; + +lazy_static! { + pub static ref INCLUSION_PROVING_KEY: Vec = + InclusionProver::load_bytes().expect("Failed to load inclusion proving key"); + pub static ref INCLUSION_VERIFYING_KEY: Vec = + InclusionVerifier::load_bytes().expect("Failed to load inclusion verifying key"); +} + +#[cfg(test)] +mod tests { + use super::*; + use wasm_bindgen_test::*; + wasm_bindgen_test_configure!(run_in_browser); + + #[wasm_bindgen_test] + fn test_load_bytes() { + BondPublicVerifier::load_bytes().expect("Failed to load bond_public verifier"); + BondValidatorVerifier::load_bytes().expect("Failed to load bond_validator verifier"); + UnbondPublicVerifier::load_bytes().expect("Failed to load unbond_public verifier"); + ClaimUnbondPublicVerifier::load_bytes().expect("Failed to load claim_unbond_public verifier"); + SetValidatorStateVerifier::load_bytes().expect("Failed to load set_validator_state verifier"); + TransferPrivateVerifier::load_bytes().expect("Failed to load transfer_private verifier"); + TransferPublicVerifier::load_bytes().expect("Failed to load transfer_public verifier"); + TransferPublicAsSignerVerifier::load_bytes().expect("Failed to load transfer_public_as_signer verifier"); + TransferPrivateToPublicVerifier::load_bytes().expect("Failed to load transfer_private_to_public verifier"); + TransferPublicToPrivateVerifier::load_bytes().expect("Failed to load transfer_public_to_private verifier"); + FeePrivateProver::load_bytes().expect("Failed to load fee_private prover"); + FeePrivateVerifier::load_bytes().expect("Failed to load fee_private verifier"); + FeePublicProver::load_bytes().expect("Failed to load fee_public prover"); + FeePublicVerifier::load_bytes().expect("Failed to load fee_public verifier"); + InclusionProver::load_bytes().expect("Failed to load inclusion prover"); + InclusionVerifier::load_bytes().expect("Failed to load inclusion verifier"); + } +} diff --git a/parameters/src/canary/resources/block.genesis b/parameters/src/canary/resources/block.genesis new file mode 100644 index 0000000000..e271fd884e Binary files /dev/null and b/parameters/src/canary/resources/block.genesis differ diff --git a/parameters/src/canary/resources/bond_public.metadata b/parameters/src/canary/resources/bond_public.metadata new file mode 100644 index 0000000000..a1cdb6b711 --- /dev/null +++ b/parameters/src/canary/resources/bond_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "e2c9caa4710ed422b63ea56fab5841b6bd3c27d647feb688b12e7d1e26f8a57b", + "prover_size": 29352706, + "verifier_checksum": "2c7affb18cab94022584e7dd09738a1ec24efbae0aebe955ae108209f3fea6ec", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/bond_public.verifier b/parameters/src/canary/resources/bond_public.verifier new file mode 100644 index 0000000000..5b37bec305 Binary files /dev/null and b/parameters/src/canary/resources/bond_public.verifier differ diff --git a/parameters/src/canary/resources/bond_validator.metadata b/parameters/src/canary/resources/bond_validator.metadata new file mode 100644 index 0000000000..6c7a6bbd5b --- /dev/null +++ b/parameters/src/canary/resources/bond_validator.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "4f1b10b099ff6ec98af0f4719df8fc4dacd60f6dc0ada8ae6f1aa1fb8ab27b37", + "prover_size": 29188482, + "verifier_checksum": "aaf7c90d4692c872b0153d3906531fa3bad547c780afd612254d5d36a815296d", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/bond_validator.verifier b/parameters/src/canary/resources/bond_validator.verifier new file mode 100644 index 0000000000..0950e826fd Binary files /dev/null and b/parameters/src/canary/resources/bond_validator.verifier differ diff --git a/parameters/src/canary/resources/claim_unbond_public.metadata b/parameters/src/canary/resources/claim_unbond_public.metadata new file mode 100644 index 0000000000..97400fa444 --- /dev/null +++ b/parameters/src/canary/resources/claim_unbond_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "92a44f7c51f6b80227ef6b7c1cfdcd2d7d8aefe728dbea65300d794f94772eb7", + "prover_size": 26927162, + "verifier_checksum": "586d5917bd34b703bcb2e4ca646c3ff468675a9dbfd7b26512e4de6d924c3725", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/claim_unbond_public.verifier b/parameters/src/canary/resources/claim_unbond_public.verifier new file mode 100644 index 0000000000..7b209890d1 Binary files /dev/null and b/parameters/src/canary/resources/claim_unbond_public.verifier differ diff --git a/parameters/src/canary/resources/fee_private.metadata b/parameters/src/canary/resources/fee_private.metadata new file mode 100644 index 0000000000..d09bee560b --- /dev/null +++ b/parameters/src/canary/resources/fee_private.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "b3640d77dd92a0a03aa3cb9e7e5d7241e10165d61066cc2cf8e3dd2aeb9bc0b2", + "prover_size": 66297972, + "verifier_checksum": "c1242f35a0943dbe9d3d68ae29c5e69871e2ed62a876792324f2583320a6b07a", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/fee_private.verifier b/parameters/src/canary/resources/fee_private.verifier new file mode 100644 index 0000000000..a261e295ab Binary files /dev/null and b/parameters/src/canary/resources/fee_private.verifier differ diff --git a/parameters/src/canary/resources/fee_public.metadata b/parameters/src/canary/resources/fee_public.metadata new file mode 100644 index 0000000000..1476ce96c7 --- /dev/null +++ b/parameters/src/canary/resources/fee_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "1667bf508398fb94cb97dc7c99b647195492e0e8a9bf57fdb73fa3c294a3ceaf", + "prover_size": 29174402, + "verifier_checksum": "63936b8503ef8daf476e48d54106872fe813041a0b81e0f44c9714999866ebc4", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/fee_public.verifier b/parameters/src/canary/resources/fee_public.verifier new file mode 100644 index 0000000000..3fbae8a941 Binary files /dev/null and b/parameters/src/canary/resources/fee_public.verifier differ diff --git a/parameters/src/canary/resources/genesis_delegations.json b/parameters/src/canary/resources/genesis_delegations.json new file mode 100644 index 0000000000..8810baeadd --- /dev/null +++ b/parameters/src/canary/resources/genesis_delegations.json @@ -0,0 +1,21 @@ +{ + "aleo1anfdhn0hr934qh0kw5lk7a43ulj3tpe50ax5hgwnf8h8k5tv7cgqxtg8dq": ["aleo10calatc7mgmaplmd7kg55jqswmjmy9zl4de9qmxvq9c4c632zuqsnm0nad", "aleo1anfw4m9t84d06ql6x7g7xsev9u9xgnpegx607j54mwxskj3ahgpqx62xg5", 30000000000000], + "aleo1anfdjlvutswne298kqgdrq57m4axmw4u6j0qcttv0l5vtanfkczq60ksht": ["aleo180jksy0d30lzwpjejmy8ug8jsn8e8nu9as05cmh2rgf8se6jeyqsammtys", "aleo1anfwgpyk20huq2jljen4raj2l6j344ccuvp0vnwv8wyv2ktvayrq5mwn7m", 20000000000000], + "aleo1anfdugp3vz0aw3yu5j8c3m92g4n3u7ktdl4fp4sa8edv5k9h3ygspu2ktu": ["aleo1ca07qvzu4ystav8y65dxrur0hlzxcl8aj7h49zvzx48ag0kmlcqqnaergh", "aleo1anfw2jx7ll6reykpn4x2kkry3s0qlvrz4rz9mkgtjn5248yuvc9qkmer05", 20000000000000], + "aleo1anfdenyche8deevqhyuk2s8a55g4x3yn5xtf9k3wth99nt80ygqqlxymad": ["aleo1u4hq6gemptr297g30yjhpl42zz6z24u99qclls9n0jynw443kqpq893z08", "aleo1anfwfn87pdpztp9pdmqgh5hpqycuc0gtka27rt0deqjv33n9hqpqz9ehfj", 150000000000000], + "aleo1anfd6m679q4kf8ars2e87xfjz3f7ezvr59lpahynuxux0symsqpq95wgap": ["aleo1e4l5tmdps84rle0lu048rk5x83deld4w0q09qzsdcc2a4h8evc9qm8ydch", "aleo1anfw6t0man4sllvn3xjfwu4wt80xwt2eu67ayfhg8h5z6ezwlsqqtd9fwl", 20000000000000], + "aleo1anfd9pwgf9czrvhtxwpg2u0gqpvajaam8fc6xfrpqqasvuvtjcxqf36rxw": ["aleo1lqvdmn0jc8nfj5veakrhnyyxegv3u7f4rlgg6hessvfunlev9cfqmyka37", "aleo1anfw6drxwrr4puuu7wsf7vzvjfjrwml4cps9ww8xxwptwy7u6yqqvj0e6t", 20000000000000], + "aleo1anfdkfd6r5u6g05fds62d4474dqhsmjdkr0tuxsheznatqv895qqfdkj04": ["aleo1cal2xtpm30ypt5078kfttu3epeuhac3mmv8ndkewchq3tlatmczs3qxnlv", "aleo1anfw0uqseujaqvqllq24pr7em547ekt5exmr4uhah9mwfz7xxqqsl0thxd", 20000000000000], + "aleo1anfd2awgqsmy2ut3pfxj8rcm3szjl7xsm6j6r2shz7hu69hgyurqrsthkz": ["aleo1l7avejc23yv6e8nx4udjwz89dw6mg95dzsp936hf77yuhnjywv9syl0ywc", "aleo1anfwps4q9y4ywvv294y79xf30tnfvpt224n92wg79rtlvm3epvxsc3vyr0", 20000000000000], + "aleo1anfds8fhnswgj2mjaem063le2w7x307mgn2xj7wckssvd40csu8qd6ptcc": ["aleo1z838c4zukt8qpwndz3gnjd374skg6zucd8q6pz30r3v2gcuh4q8qvdf8p9", "aleo1anfwgntsh7x667gvscw02m94gv7d2f92dd45whr9l4ghgr60qy9saltswj", 30000000000000], + "aleo1anfdyfvq9gh49dr2ctr38473q32ne3pga8p7y4wzqvegtmasrgfqrejqeh": ["aleo128vwxfvffrw2kfhg472z7sa0erg54zutxjqexvfa9t9qlrgcuy9qtdem0x", "aleo1anfw0rd60fl8crky5cjut4n7tz9wkv2hltvfmx7p8ksh7va4muyq20cr4y", 20000000000000], + "aleo1anfdv7v0z2dj84tz53jxeke4zsm8usla4s5pm37fprr5cyfkrc8sn02j9y": ["aleo1psngnx6kt4y20zewd50x2zw6lfdehwzdarn2vazw346ur4hhjqrqhrz2qv", "aleo1anfwdmy4ldcm4dr7vw00kcsgxh64p44520nuve74h8a8a7edlqyqglkpwk", 150000000000000], + "aleo1anfdylfnpf06fjdskmmrg9tks49jdpmuhvykkq4lkreqycsy6gxqra3ucy": ["aleo1wksvl4eswnhj0wgzn8vutqk8p2svml7jzx5w85fxce5w46jhncxsdee9df", "aleo1anfwju3fme8srle6wruzpxw9zkx6vcn3unl55hj4sw8pawnqaq9sl09pe9", 150000000000000], + "aleo1anfd4qdndn3we5huql9d68azx59hl33jqts8jvnm68qs6s96k58sre7vf4": ["aleo1t8dng2slj2rjhgmf8r7kklk0gwnpcgy85kn079ltgmmjwnedvvrqdkku32", "aleo1anfwtsvr9l4zhhk6e360yw7jd867utmh3xe4f2v2qje4wwzeggyqr60x0h", 150000000000000], + "aleo1anfd9de8nfttnsw2tyma89vl6hudf2dgss696ys79qlp57u4jqqqfpynuq": ["aleo1anfvmly4uldmvdu7435f78n5qt7eprvttru85rqcn9tfc4j28cqqmxeu7s", "aleo1anfw2ku5gk9zxh8ltke7tck0telugnpuyvahrpkq6xeek4cjzsps5ryeas", 150000000000000], + "aleo1q60cnaukr2fgx9dcnjwz3ka4uj3svk6d7pgalqfln690yjwykszsu7j5eq": ["aleo1l2a3lakq9pz9w9hyre7rk9zmk64wzr62z0q26wglr8tmf8w5cyqqxtt364", "aleo13yjkljfnaq5996geg5xz8rctqdcfv6j0hkxxam9rp6z2wr3jkgxqt0t8l8", 25000000000000], + "aleo1ag7jp4cwyvmdhpfxc5cdcygue2f602erjlhhvq3wky9evt4tjs9qrrhaxk": ["aleo1l2a3lakq9pz9w9hyre7rk9zmk64wzr62z0q26wglr8tmf8w5cyqqxtt364", "aleo10thxce29gedea3fa7z8rkkcqjzhgpe8c8sa6s0lzqmq9pkkdl58qtphg5t", 25000000000000], + "aleo1x46fux6zu2u6evg0j3xtu26nt9ska6v3cf3a4cfyy4u0ldzaxyxstcz60s": ["aleo1l2a3lakq9pz9w9hyre7rk9zmk64wzr62z0q26wglr8tmf8w5cyqqxtt364", "aleo1gy3khx6e5pzzn47juv83878jdckw6zl8p50hjns07awun7myhyzq96xgkr", 25000000000000], + "aleo1e8rj993j028m0csjmwjlyt6tuemd892ghnwsp0h8lryy2l3cnvrs8rt96n": ["aleo1l2a3lakq9pz9w9hyre7rk9zmk64wzr62z0q26wglr8tmf8w5cyqqxtt364", "aleo1l8dq0c9er0hwc6sgk5awgqhp0agq8tvspy8qxm6a3yehn37v6qqqdwdcac", 25000000000000], + "aleo1r8a9gsd03kqd7nl4d64a6xrvwvcfquef9r7cv46m074qk2nuksps8ns77y": ["aleo1l2a3lakq9pz9w9hyre7rk9zmk64wzr62z0q26wglr8tmf8w5cyqqxtt364", "aleo1cek9kjj77432njfthtmxg04ymrf6eyjdw9zeqa7fn0kc7zywa5psdwdptf", 25000000000000] +} \ No newline at end of file diff --git a/parameters/src/canary/resources/genesis_public_balances.json b/parameters/src/canary/resources/genesis_public_balances.json new file mode 100644 index 0000000000..2e1c997cf7 --- /dev/null +++ b/parameters/src/canary/resources/genesis_public_balances.json @@ -0,0 +1,38 @@ +{ + "aleo1anfxjkwvf4cnpdrx4ukqdrgwjcfkplgtg7eftzq3ktz89duv5czqrpxtgy": 167000000000000, + "aleo1anfxl5cy59amxgyks9y6kr7xwh9yrh4d4sm4472sw8eqnj4x5czqzrmmdy": 135000000000000, + "aleo1anfxkkrn9lyj82jceaugh4662kn0mf0vpje85l7ds69zm7atfcysvsv4ez": 122995290000000, + "aleo1pzuc98fpz8xrvdjtx9umtcdu720v5zt2u79h49e39tqc3qhgayzqnn47js": 100000000, + "aleo1wqtpfauqtpp7f3m00muh9nsx7k38lm9acqey3279vqdvsscc7c8slm0nad": 100000000, + "aleo10ez0l4589luwgk4d6wexr7j80ng6ty4h5g4uue9p5cdet0prcyps54egw7": 100000000, + "aleo15zvde6z6z6kwhjrljz5p2v2e34aeqytuugylht42f4fwgzkwty8s8c22au": 100000000, + "aleo1dmysvldxgm4t74ncwyzmzd9p6f22df9hlu6s4tzx2t78kgwgh59qxvdraw": 100000000, + "aleo1ptzknxyc9zm6wxqv4p8dnj92kgxr6fgew4mkdcc2p54xrjrjryfqtr8pe5": 100000000, + "aleo18jdhm4a0927c7c4jagzznldapuqxceuzel9rkwlzvr5cwk6mecxqpensa9": 100000000, + "aleo19g99vj20nq6d6v33kvnaw5dfjakdhdmu2a7swyaxe5q654l8pyqqy397g6": 100000000, + "aleo147vv6vxe97l6v6ur0re0prpy4d2yhsn959fha0fwtec2vp300cfq98c08q": 100000000, + "aleo1gdh9cs48uswy8uc8kyd3nmgqtf9mzu4ucl4pkrg7fyc6syr9rq9qtgkccm": 100000000, + "aleo16r36k8t7fhc72uhkdsx3aj4uy0dk7s87szc6wcgexlxpc4hl8gys0dem0x": 100000000, + "aleo16gecle3925np3hq6c9xg5e0slvhjysy73fpwax2d4ezhgqax9yqswayf6r": 100000000, + "aleo1ql6v479rs938zwq8slf7ktrzryln869mrxeqxpt8hnlr9fulk5pq7492tt": 100000000, + "aleo13hg7km34zaxgffec9jsdgvmfh9wsh9zchymd8tnawf35qcm0tc9sw472yk": 100000000, + "aleo13yjkljfnaq5996geg5xz8rctqdcfv6j0hkxxam9rp6z2wr3jkgxqt0t8l8": 100000000, + "aleo10thxce29gedea3fa7z8rkkcqjzhgpe8c8sa6s0lzqmq9pkkdl58qtphg5t": 100000000, + "aleo1gy3khx6e5pzzn47juv83878jdckw6zl8p50hjns07awun7myhyzq96xgkr": 100000000, + "aleo1l8dq0c9er0hwc6sgk5awgqhp0agq8tvspy8qxm6a3yehn37v6qqqdwdcac": 100000000, + "aleo1cek9kjj77432njfthtmxg04ymrf6eyjdw9zeqa7fn0kc7zywa5psdwdptf": 100000000, + "aleo1anfw4m9t84d06ql6x7g7xsev9u9xgnpegx607j54mwxskj3ahgpqx62xg5": 100000000, + "aleo1anfwgpyk20huq2jljen4raj2l6j344ccuvp0vnwv8wyv2ktvayrq5mwn7m": 100000000, + "aleo1anfw2jx7ll6reykpn4x2kkry3s0qlvrz4rz9mkgtjn5248yuvc9qkmer05": 100000000, + "aleo1anfwfn87pdpztp9pdmqgh5hpqycuc0gtka27rt0deqjv33n9hqpqz9ehfj": 100000000, + "aleo1anfw6t0man4sllvn3xjfwu4wt80xwt2eu67ayfhg8h5z6ezwlsqqtd9fwl": 100000000, + "aleo1anfw6drxwrr4puuu7wsf7vzvjfjrwml4cps9ww8xxwptwy7u6yqqvj0e6t": 100000000, + "aleo1anfw0uqseujaqvqllq24pr7em547ekt5exmr4uhah9mwfz7xxqqsl0thxd": 100000000, + "aleo1anfwps4q9y4ywvv294y79xf30tnfvpt224n92wg79rtlvm3epvxsc3vyr0": 100000000, + "aleo1anfwgntsh7x667gvscw02m94gv7d2f92dd45whr9l4ghgr60qy9saltswj": 100000000, + "aleo1anfw0rd60fl8crky5cjut4n7tz9wkv2hltvfmx7p8ksh7va4muyq20cr4y": 100000000, + "aleo1anfwdmy4ldcm4dr7vw00kcsgxh64p44520nuve74h8a8a7edlqyqglkpwk": 100000000, + "aleo1anfwju3fme8srle6wruzpxw9zkx6vcn3unl55hj4sw8pawnqaq9sl09pe9": 100000000, + "aleo1anfwtsvr9l4zhhk6e360yw7jd867utmh3xe4f2v2qje4wwzeggyqr60x0h": 100000000, + "aleo1anfgedfl9phdyrzz3r88hrxkevk36wnegjdkzrfz276fj85shsps8u0zyx": 10000000 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/genesis_validators.json b/parameters/src/canary/resources/genesis_validators.json new file mode 100644 index 0000000000..6032a8595a --- /dev/null +++ b/parameters/src/canary/resources/genesis_validators.json @@ -0,0 +1,17 @@ +{ + "aleo10calatc7mgmaplmd7kg55jqswmjmy9zl4de9qmxvq9c4c632zuqsnm0nad": ["aleo1wqtpfauqtpp7f3m00muh9nsx7k38lm9acqey3279vqdvsscc7c8slm0nad", 100000000, true, 10], + "aleo180jksy0d30lzwpjejmy8ug8jsn8e8nu9as05cmh2rgf8se6jeyqsammtys": ["aleo10ez0l4589luwgk4d6wexr7j80ng6ty4h5g4uue9p5cdet0prcyps54egw7", 100000000, true, 10], + "aleo1ca07qvzu4ystav8y65dxrur0hlzxcl8aj7h49zvzx48ag0kmlcqqnaergh": ["aleo15zvde6z6z6kwhjrljz5p2v2e34aeqytuugylht42f4fwgzkwty8s8c22au", 100000000, true, 10], + "aleo1u4hq6gemptr297g30yjhpl42zz6z24u99qclls9n0jynw443kqpq893z08": ["aleo1dmysvldxgm4t74ncwyzmzd9p6f22df9hlu6s4tzx2t78kgwgh59qxvdraw", 100000000, true, 10], + "aleo1e4l5tmdps84rle0lu048rk5x83deld4w0q09qzsdcc2a4h8evc9qm8ydch": ["aleo1ptzknxyc9zm6wxqv4p8dnj92kgxr6fgew4mkdcc2p54xrjrjryfqtr8pe5", 100000000, true, 10], + "aleo1lqvdmn0jc8nfj5veakrhnyyxegv3u7f4rlgg6hessvfunlev9cfqmyka37": ["aleo18jdhm4a0927c7c4jagzznldapuqxceuzel9rkwlzvr5cwk6mecxqpensa9", 100000000, true, 10], + "aleo1cal2xtpm30ypt5078kfttu3epeuhac3mmv8ndkewchq3tlatmczs3qxnlv": ["aleo19g99vj20nq6d6v33kvnaw5dfjakdhdmu2a7swyaxe5q654l8pyqqy397g6", 100000000, true, 10], + "aleo1l7avejc23yv6e8nx4udjwz89dw6mg95dzsp936hf77yuhnjywv9syl0ywc": ["aleo147vv6vxe97l6v6ur0re0prpy4d2yhsn959fha0fwtec2vp300cfq98c08q", 100000000, true, 10], + "aleo1z838c4zukt8qpwndz3gnjd374skg6zucd8q6pz30r3v2gcuh4q8qvdf8p9": ["aleo1gdh9cs48uswy8uc8kyd3nmgqtf9mzu4ucl4pkrg7fyc6syr9rq9qtgkccm", 100000000, true, 10], + "aleo128vwxfvffrw2kfhg472z7sa0erg54zutxjqexvfa9t9qlrgcuy9qtdem0x": ["aleo16r36k8t7fhc72uhkdsx3aj4uy0dk7s87szc6wcgexlxpc4hl8gys0dem0x", 100000000, true, 10], + "aleo1psngnx6kt4y20zewd50x2zw6lfdehwzdarn2vazw346ur4hhjqrqhrz2qv": ["aleo16gecle3925np3hq6c9xg5e0slvhjysy73fpwax2d4ezhgqax9yqswayf6r", 100000000, true, 10], + "aleo1wksvl4eswnhj0wgzn8vutqk8p2svml7jzx5w85fxce5w46jhncxsdee9df": ["aleo1ql6v479rs938zwq8slf7ktrzryln869mrxeqxpt8hnlr9fulk5pq7492tt", 100000000, true, 10], + "aleo1t8dng2slj2rjhgmf8r7kklk0gwnpcgy85kn079ltgmmjwnedvvrqdkku32": ["aleo13hg7km34zaxgffec9jsdgvmfh9wsh9zchymd8tnawf35qcm0tc9sw472yk", 100000000, true, 10], + "aleo1l2a3lakq9pz9w9hyre7rk9zmk64wzr62z0q26wglr8tmf8w5cyqqxtt364": ["aleo1pzuc98fpz8xrvdjtx9umtcdu720v5zt2u79h49e39tqc3qhgayzqnn47js", 100000000, true, 0], + "aleo1anfvmly4uldmvdu7435f78n5qt7eprvttru85rqcn9tfc4j28cqqmxeu7s": ["aleo1anfw2ku5gk9zxh8ltke7tck0telugnpuyvahrpkq6xeek4cjzsps5ryeas", 100000000, true, 100] +} \ No newline at end of file diff --git a/parameters/src/canary/resources/inclusion.metadata b/parameters/src/canary/resources/inclusion.metadata new file mode 100644 index 0000000000..8df45d6edb --- /dev/null +++ b/parameters/src/canary/resources/inclusion.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "8faa4d3aaaa5e786d20b61f825e50901f9dcf470455d1d2994e091eefcc66a4e", + "prover_size": 233812212, + "verifier_checksum": "57bf79c7a493ee79f8ebed2c8e6e7e8a0a6d11b2f6edcba6e943768cb6a250cc", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/inclusion.verifier b/parameters/src/canary/resources/inclusion.verifier new file mode 100644 index 0000000000..d037956880 Binary files /dev/null and b/parameters/src/canary/resources/inclusion.verifier differ diff --git a/parameters/src/canary/resources/join.metadata b/parameters/src/canary/resources/join.metadata new file mode 100644 index 0000000000..42ed8eb33c --- /dev/null +++ b/parameters/src/canary/resources/join.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "11c8e1702e4644ac8b31e2ad67c97ebf7d2f84e7f82298bbc52d25fe69b26150", + "prover_size": 74722164, + "verifier_checksum": "ec6395b9c03b49c941fcba788c16f73ff4896c4ee1cbb0dd19c9d13d43f51479", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/join.verifier b/parameters/src/canary/resources/join.verifier new file mode 100644 index 0000000000..8a5b2fbde7 Binary files /dev/null and b/parameters/src/canary/resources/join.verifier differ diff --git a/parameters/src/canary/resources/restrictions.json b/parameters/src/canary/resources/restrictions.json new file mode 100644 index 0000000000..0a49b4071f --- /dev/null +++ b/parameters/src/canary/resources/restrictions.json @@ -0,0 +1,6 @@ +{ + "restrictions_id": "7562506206353711030068167991213732850758501012603348777370400520506564970105field", + "programs": {}, + "functions": {}, + "arguments": {} +} \ No newline at end of file diff --git a/parameters/src/canary/resources/set_validator_state.metadata b/parameters/src/canary/resources/set_validator_state.metadata new file mode 100644 index 0000000000..aba7a5b4f6 --- /dev/null +++ b/parameters/src/canary/resources/set_validator_state.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "e8fbb86008343485bb95c3e3e75d41b493ba654cc161d8b9f9c6901cb71d7a9d", + "prover_size": 17390188, + "verifier_checksum": "d0942ee642048e21cbf562737b4760524dd378ac17867e7a225736badb23f614", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/set_validator_state.verifier b/parameters/src/canary/resources/set_validator_state.verifier new file mode 100644 index 0000000000..b4b175c97c Binary files /dev/null and b/parameters/src/canary/resources/set_validator_state.verifier differ diff --git a/parameters/src/canary/resources/split.metadata b/parameters/src/canary/resources/split.metadata new file mode 100644 index 0000000000..b1d9624677 --- /dev/null +++ b/parameters/src/canary/resources/split.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "5bf027bcf0476784edd3192c3c0731dbd65f955220ef3d6c060acc0e3d1a5555", + "prover_size": 75161428, + "verifier_checksum": "5eb3cea5fa953b36272b1a4f315df955253840acbb1ff900dd9e1126bb012437", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/split.verifier b/parameters/src/canary/resources/split.verifier new file mode 100644 index 0000000000..ccdd8a0970 Binary files /dev/null and b/parameters/src/canary/resources/split.verifier differ diff --git a/parameters/src/canary/resources/transfer_private.metadata b/parameters/src/canary/resources/transfer_private.metadata new file mode 100644 index 0000000000..f9cad9090b --- /dev/null +++ b/parameters/src/canary/resources/transfer_private.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "3e4a7a7332889f9a2ad4fd1f1c8d7cb1d8c4b783dca7a832133a6a845fbc757a", + "prover_size": 75949172, + "verifier_checksum": "b50fcfdebda26d1fbc86f497e945f33118ca3f8d1c9ac95918199a8695408903", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/transfer_private.verifier b/parameters/src/canary/resources/transfer_private.verifier new file mode 100644 index 0000000000..867e4d93d3 Binary files /dev/null and b/parameters/src/canary/resources/transfer_private.verifier differ diff --git a/parameters/src/canary/resources/transfer_private_to_public.metadata b/parameters/src/canary/resources/transfer_private_to_public.metadata new file mode 100644 index 0000000000..0a224a18dc --- /dev/null +++ b/parameters/src/canary/resources/transfer_private_to_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "c96d674e52911b0a8b2d0c6d07e5499b90783d8b8e6623d348fa33547835d64b", + "prover_size": 66299476, + "verifier_checksum": "38d0157f70c16badcfd472dd0c045f754b4ac6572e62be48a0053aaa1157f846", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/transfer_private_to_public.verifier b/parameters/src/canary/resources/transfer_private_to_public.verifier new file mode 100644 index 0000000000..5903d51a14 Binary files /dev/null and b/parameters/src/canary/resources/transfer_private_to_public.verifier differ diff --git a/parameters/src/canary/resources/transfer_public.metadata b/parameters/src/canary/resources/transfer_public.metadata new file mode 100644 index 0000000000..3482a6c295 --- /dev/null +++ b/parameters/src/canary/resources/transfer_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "f143e4c90526e0f08a43daa8977323177587778602b9a3dbb0426908eabe7874", + "prover_size": 28913482, + "verifier_checksum": "12da9fc8d7284177cc6bcdfb6c8b48217a11a6c70767e6e71f17ffb4e69f17ee", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/transfer_public.verifier b/parameters/src/canary/resources/transfer_public.verifier new file mode 100644 index 0000000000..8008e2d53b Binary files /dev/null and b/parameters/src/canary/resources/transfer_public.verifier differ diff --git a/parameters/src/canary/resources/transfer_public_as_signer.metadata b/parameters/src/canary/resources/transfer_public_as_signer.metadata new file mode 100644 index 0000000000..b7d7d062d7 --- /dev/null +++ b/parameters/src/canary/resources/transfer_public_as_signer.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "e1f2676aeae5d639cc2212a514c50a5dd42efce8b28015ac56a4600200066713", + "prover_size": 28915282, + "verifier_checksum": "059827d436bd76af3c65c05b518dbcdd56370be4e5524b016c2f0dc702505eb4", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/transfer_public_as_signer.verifier b/parameters/src/canary/resources/transfer_public_as_signer.verifier new file mode 100644 index 0000000000..f511b174e8 Binary files /dev/null and b/parameters/src/canary/resources/transfer_public_as_signer.verifier differ diff --git a/parameters/src/canary/resources/transfer_public_to_private.metadata b/parameters/src/canary/resources/transfer_public_to_private.metadata new file mode 100644 index 0000000000..12d9e0df2e --- /dev/null +++ b/parameters/src/canary/resources/transfer_public_to_private.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "cf5854ed4d0976aecd30f3753d9b3322fa369a4fa7e35748dbb27eb35df3791d", + "prover_size": 38413316, + "verifier_checksum": "db3285742eac86cc061e408cc2ec16c4318bcee98ccd5f19c358d572e83967e9", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/transfer_public_to_private.verifier b/parameters/src/canary/resources/transfer_public_to_private.verifier new file mode 100644 index 0000000000..90d7f127f0 Binary files /dev/null and b/parameters/src/canary/resources/transfer_public_to_private.verifier differ diff --git a/parameters/src/canary/resources/unbond_public.metadata b/parameters/src/canary/resources/unbond_public.metadata new file mode 100644 index 0000000000..ddf8ecadf5 --- /dev/null +++ b/parameters/src/canary/resources/unbond_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "e66bb2f7c74ce22e3774bb5b7804238b493f9ae0b975267a7e3707c00b01dbd1", + "prover_size": 28913482, + "verifier_checksum": "775abaecf38aaca0bd1a7884e61be132b85a8cdc30a01ba6ef8e433f8d0744a4", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/canary/resources/unbond_public.verifier b/parameters/src/canary/resources/unbond_public.verifier new file mode 100644 index 0000000000..e710a2fe75 Binary files /dev/null and b/parameters/src/canary/resources/unbond_public.verifier differ diff --git a/parameters/src/errors/mod.rs b/parameters/src/errors/mod.rs index 930294ae30..598d38e40d 100644 --- a/parameters/src/errors/mod.rs +++ b/parameters/src/errors/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/parameters/src/errors/parameter.rs b/parameters/src/errors/parameter.rs index 6643f2c8ca..3584bbeae2 100644 --- a/parameters/src/errors/parameter.rs +++ b/parameters/src/errors/parameter.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/parameters/src/lib.rs b/parameters/src/lib.rs index 7dcf27c5f0..959e12987c 100644 --- a/parameters/src/lib.rs +++ b/parameters/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -30,7 +31,11 @@ pub mod macros; pub mod errors; pub use errors::*; -pub mod testnet3; +pub mod canary; + +pub mod mainnet; + +pub mod testnet; pub mod prelude { pub use crate::errors::*; diff --git a/parameters/src/macros.rs b/parameters/src/macros.rs index 7a2455d677..14ec141d40 100644 --- a/parameters/src/macros.rs +++ b/parameters/src/macros.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/parameters/src/mainnet/genesis.rs b/parameters/src/mainnet/genesis.rs new file mode 100644 index 0000000000..a178a1a42f --- /dev/null +++ b/parameters/src/mainnet/genesis.rs @@ -0,0 +1,33 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +pub struct GenesisBytes; + +impl GenesisBytes { + pub const fn load_bytes() -> &'static [u8] { + include_bytes!("./resources/block.genesis") + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_genesis_block() { + let bytes = GenesisBytes::load_bytes(); + assert_eq!(31083, bytes.len() as u64, "Update me if serialization has changed"); + } +} diff --git a/parameters/src/testnet3/mod.rs b/parameters/src/mainnet/mod.rs similarity index 78% rename from parameters/src/testnet3/mod.rs rename to parameters/src/mainnet/mod.rs index 5233242d83..029e0922f5 100644 --- a/parameters/src/testnet3/mod.rs +++ b/parameters/src/mainnet/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,16 +19,16 @@ pub use genesis::*; pub mod powers; pub use powers::*; -const REMOTE_URL: &str = "https://s3-us-west-1.amazonaws.com/testnet3.parameters"; +/// The restrictions list as a JSON-compatible string. +pub const RESTRICTIONS_LIST: &str = include_str!("./resources/restrictions.json"); + +const REMOTE_URL: &str = "https://parameters.aleo.org/mainnet"; // Degrees #[cfg(not(feature = "wasm"))] impl_local!(Degree15, "resources/", "powers-of-beta-15", "usrs"); #[cfg(feature = "wasm")] impl_remote!(Degree15, REMOTE_URL, "resources/", "powers-of-beta-15", "usrs"); -#[cfg(not(feature = "wasm"))] -impl_local!(Degree16, "resources/", "powers-of-beta-16", "usrs"); -#[cfg(feature = "wasm")] impl_remote!(Degree16, REMOTE_URL, "resources/", "powers-of-beta-16", "usrs"); impl_remote!(Degree17, REMOTE_URL, "resources/", "powers-of-beta-17", "usrs"); impl_remote!(Degree18, REMOTE_URL, "resources/", "powers-of-beta-18", "usrs"); @@ -73,12 +74,12 @@ impl_local!(BetaH, "resources/", "beta-h", "usrs"); // BondPublic impl_remote!(BondPublicProver, REMOTE_URL, "resources/", "bond_public", "prover"); impl_local!(BondPublicVerifier, "resources/", "bond_public", "verifier"); +// BondValidator +impl_remote!(BondValidatorProver, REMOTE_URL, "resources/", "bond_validator", "prover"); +impl_local!(BondValidatorVerifier, "resources/", "bond_validator", "verifier"); // UnbondPublic impl_remote!(UnbondPublicProver, REMOTE_URL, "resources/", "unbond_public", "prover"); impl_local!(UnbondPublicVerifier, "resources/", "unbond_public", "verifier"); -// UnbondDelegatorAsValidator -impl_remote!(UnbondDelegatorAsValidatorProver, REMOTE_URL, "resources/", "unbond_delegator_as_validator", "prover"); -impl_local!(UnbondDelegatorAsValidatorVerifier, "resources/", "unbond_delegator_as_validator", "verifier"); // ClaimUnbondPublic impl_remote!(ClaimUnbondPublicProver, REMOTE_URL, "resources/", "claim_unbond_public", "prover"); impl_local!(ClaimUnbondPublicVerifier, "resources/", "claim_unbond_public", "verifier"); @@ -91,6 +92,9 @@ impl_local!(TransferPrivateVerifier, "resources/", "transfer_private", "verifier // TransferPublic impl_remote!(TransferPublicProver, REMOTE_URL, "resources/", "transfer_public", "prover"); impl_local!(TransferPublicVerifier, "resources/", "transfer_public", "verifier"); +// TransferPublicAsSigner +impl_remote!(TransferPublicAsSignerProver, REMOTE_URL, "resources/", "transfer_public_as_signer", "prover"); +impl_local!(TransferPublicAsSignerVerifier, "resources/", "transfer_public_as_signer", "verifier"); // TransferPrivateToPublic impl_remote!(TransferPrivateToPublicProver, REMOTE_URL, "resources/", "transfer_private_to_public", "prover"); impl_local!(TransferPrivateToPublicVerifier, "resources/", "transfer_private_to_public", "verifier"); @@ -115,19 +119,20 @@ macro_rules! insert_credit_keys { ($map:ident, $type:ident<$network:ident>, $variant:ident) => {{ paste::paste! { let string = stringify!([<$variant:lower>]); - $crate::insert_key!($map, string, $type<$network>, ("bond_public", $crate::testnet3::[]::load_bytes())); - $crate::insert_key!($map, string, $type<$network>, ("unbond_public", $crate::testnet3::[]::load_bytes())); - $crate::insert_key!($map, string, $type<$network>, ("unbond_delegator_as_validator", $crate::testnet3::[]::load_bytes())); - $crate::insert_key!($map, string, $type<$network>, ("claim_unbond_public", $crate::testnet3::[]::load_bytes())); - $crate::insert_key!($map, string, $type<$network>, ("set_validator_state", $crate::testnet3::[]::load_bytes())); - $crate::insert_key!($map, string, $type<$network>, ("transfer_private", $crate::testnet3::[]::load_bytes())); - $crate::insert_key!($map, string, $type<$network>, ("transfer_public", $crate::testnet3::[]::load_bytes())); - $crate::insert_key!($map, string, $type<$network>, ("transfer_private_to_public", $crate::testnet3::[]::load_bytes())); - $crate::insert_key!($map, string, $type<$network>, ("transfer_public_to_private", $crate::testnet3::[]::load_bytes())); - $crate::insert_key!($map, string, $type<$network>, ("join", $crate::testnet3::[]::load_bytes())); - $crate::insert_key!($map, string, $type<$network>, ("split", $crate::testnet3::[]::load_bytes())); - $crate::insert_key!($map, string, $type<$network>, ("fee_private", $crate::testnet3::[]::load_bytes())); - $crate::insert_key!($map, string, $type<$network>, ("fee_public", $crate::testnet3::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("bond_public", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("bond_validator", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("unbond_public", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("claim_unbond_public", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("set_validator_state", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("transfer_private", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("transfer_public", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("transfer_public_as_signer", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("transfer_private_to_public", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("transfer_public_to_private", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("join", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("split", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("fee_private", $crate::mainnet::[]::load_bytes())); + $crate::insert_key!($map, string, $type<$network>, ("fee_public", $crate::mainnet::[]::load_bytes())); } }}; } @@ -149,7 +154,7 @@ impl_remote!(InclusionProver, REMOTE_URL, "resources/", "inclusion", "prover"); impl_local!(InclusionVerifier, "resources/", "inclusion", "verifier"); /// The function name for the inclusion circuit. -pub const TESTNET3_INCLUSION_FUNCTION_NAME: &str = "inclusion"; +pub const NETWORK_INCLUSION_FUNCTION_NAME: &str = "inclusion"; lazy_static! { pub static ref INCLUSION_PROVING_KEY: Vec = @@ -164,6 +169,17 @@ mod tests { use wasm_bindgen_test::*; wasm_bindgen_test_configure!(run_in_browser); + #[ignore] + #[test] + fn test_load_bytes_mini() { + Degree16::load_bytes().expect("Failed to load degree 16"); + BondPublicVerifier::load_bytes().expect("Failed to load bond_public verifier"); + FeePublicProver::load_bytes().expect("Failed to load fee_public prover"); + FeePublicVerifier::load_bytes().expect("Failed to load fee_public verifier"); + InclusionProver::load_bytes().expect("Failed to load inclusion prover"); + InclusionVerifier::load_bytes().expect("Failed to load inclusion verifier"); + } + #[wasm_bindgen_test] fn test_load_bytes() { Degree16::load_bytes().expect("Failed to load degree 16"); @@ -172,13 +188,13 @@ mod tests { Degree19::load_bytes().expect("Failed to load degree 19"); Degree20::load_bytes().expect("Failed to load degree 20"); BondPublicVerifier::load_bytes().expect("Failed to load bond_public verifier"); + BondValidatorVerifier::load_bytes().expect("Failed to load bond_validator verifier"); UnbondPublicVerifier::load_bytes().expect("Failed to load unbond_public verifier"); - UnbondDelegatorAsValidatorVerifier::load_bytes() - .expect("Failed to load unbond_delegator_as_validator verifier"); ClaimUnbondPublicVerifier::load_bytes().expect("Failed to load claim_unbond_public verifier"); SetValidatorStateVerifier::load_bytes().expect("Failed to load set_validator_state verifier"); TransferPrivateVerifier::load_bytes().expect("Failed to load transfer_private verifier"); TransferPublicVerifier::load_bytes().expect("Failed to load transfer_public verifier"); + TransferPublicAsSignerVerifier::load_bytes().expect("Failed to load transfer_public_as_signer verifier"); TransferPrivateToPublicVerifier::load_bytes().expect("Failed to load transfer_private_to_public verifier"); TransferPublicToPrivateVerifier::load_bytes().expect("Failed to load transfer_public_to_private verifier"); FeePrivateProver::load_bytes().expect("Failed to load fee_private prover"); diff --git a/parameters/src/testnet3/powers.rs b/parameters/src/mainnet/powers.rs similarity index 99% rename from parameters/src/testnet3/powers.rs rename to parameters/src/mainnet/powers.rs index 577c8dc01d..c12245f07c 100644 --- a/parameters/src/testnet3/powers.rs +++ b/parameters/src/mainnet/powers.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -27,7 +28,7 @@ use snarkvm_utilities::{ Write, }; -use anyhow::{anyhow, bail, ensure, Result}; +use anyhow::{Result, anyhow, bail, ensure}; use parking_lot::RwLock; use std::{collections::BTreeMap, ops::Range, sync::Arc}; diff --git a/parameters/src/testnet3/resources/beta-h.metadata b/parameters/src/mainnet/resources/beta-h.metadata similarity index 100% rename from parameters/src/testnet3/resources/beta-h.metadata rename to parameters/src/mainnet/resources/beta-h.metadata diff --git a/parameters/src/testnet3/resources/beta-h.usrs b/parameters/src/mainnet/resources/beta-h.usrs similarity index 100% rename from parameters/src/testnet3/resources/beta-h.usrs rename to parameters/src/mainnet/resources/beta-h.usrs diff --git a/parameters/src/mainnet/resources/block.genesis b/parameters/src/mainnet/resources/block.genesis new file mode 100644 index 0000000000..9af822fdc8 Binary files /dev/null and b/parameters/src/mainnet/resources/block.genesis differ diff --git a/parameters/src/mainnet/resources/bond_public.metadata b/parameters/src/mainnet/resources/bond_public.metadata new file mode 100644 index 0000000000..ebe89c1a76 --- /dev/null +++ b/parameters/src/mainnet/resources/bond_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "82b85725d9b83cb28847bc41e6b43f50f53398cd59f112162ae28c6140c61c54", + "prover_size": 29352706, + "verifier_checksum": "a3fec37214b59fa92a21fe99fee899d7b1f3fa6a17e77a2c96035e692cefe66e", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/bond_public.verifier b/parameters/src/mainnet/resources/bond_public.verifier new file mode 100644 index 0000000000..231ea2c54c Binary files /dev/null and b/parameters/src/mainnet/resources/bond_public.verifier differ diff --git a/parameters/src/mainnet/resources/bond_validator.metadata b/parameters/src/mainnet/resources/bond_validator.metadata new file mode 100644 index 0000000000..6a1b62ddae --- /dev/null +++ b/parameters/src/mainnet/resources/bond_validator.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "fead68223b70cb5160b110c45c8a7717c4700ad2b076f575e54699076a2e6e03", + "prover_size": 29188482, + "verifier_checksum": "3f0b8d99e81e917a1d441498adcc2f91fe7bdbd84fffd86340d91819b7168558", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/bond_validator.verifier b/parameters/src/mainnet/resources/bond_validator.verifier new file mode 100644 index 0000000000..0525f90703 Binary files /dev/null and b/parameters/src/mainnet/resources/bond_validator.verifier differ diff --git a/parameters/src/mainnet/resources/claim_unbond_public.metadata b/parameters/src/mainnet/resources/claim_unbond_public.metadata new file mode 100644 index 0000000000..89f1cf0b09 --- /dev/null +++ b/parameters/src/mainnet/resources/claim_unbond_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "40562194dde5d29d10657a7ae8f2d4cee309e5031b88368fecf881297f000dfa", + "prover_size": 26927162, + "verifier_checksum": "33e4b325b87edc47b2620f51260d0048e6da636f63ea10edf6c54069901b79a0", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/claim_unbond_public.verifier b/parameters/src/mainnet/resources/claim_unbond_public.verifier new file mode 100644 index 0000000000..5e25f2584c Binary files /dev/null and b/parameters/src/mainnet/resources/claim_unbond_public.verifier differ diff --git a/parameters/src/mainnet/resources/fee_private.metadata b/parameters/src/mainnet/resources/fee_private.metadata new file mode 100644 index 0000000000..6793d31901 --- /dev/null +++ b/parameters/src/mainnet/resources/fee_private.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "27b72ed5e8086127f8cfcfc94b8c63543e5901a368a3f782aedcb51f9ace738e", + "prover_size": 66297972, + "verifier_checksum": "a9951e76ba3738840f472d38b7c0d496c6d26f6bc58a9035ef7f7f68c353a89b", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/fee_private.verifier b/parameters/src/mainnet/resources/fee_private.verifier new file mode 100644 index 0000000000..11be848dd3 Binary files /dev/null and b/parameters/src/mainnet/resources/fee_private.verifier differ diff --git a/parameters/src/mainnet/resources/fee_public.metadata b/parameters/src/mainnet/resources/fee_public.metadata new file mode 100644 index 0000000000..76dacefc4c --- /dev/null +++ b/parameters/src/mainnet/resources/fee_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "d967fc683af43a0a01817283af05181f9f8277c49351ca664a642b0eb9ec9363", + "prover_size": 29174402, + "verifier_checksum": "ccf30fa4ce688f93ef3a985057684fe9e32585fb8e93f2c472169e506da6cdb0", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/fee_public.verifier b/parameters/src/mainnet/resources/fee_public.verifier new file mode 100644 index 0000000000..8939a796b7 Binary files /dev/null and b/parameters/src/mainnet/resources/fee_public.verifier differ diff --git a/parameters/src/testnet3/resources/genesis.metadata b/parameters/src/mainnet/resources/genesis.metadata similarity index 100% rename from parameters/src/testnet3/resources/genesis.metadata rename to parameters/src/mainnet/resources/genesis.metadata diff --git a/parameters/src/mainnet/resources/genesis_delegations.json b/parameters/src/mainnet/resources/genesis_delegations.json new file mode 100644 index 0000000000..3b26598733 --- /dev/null +++ b/parameters/src/mainnet/resources/genesis_delegations.json @@ -0,0 +1,467 @@ +{ + "aleo1m6qdhgcgej0f898nmm99kc42qd2edtx8yz7p9tk09d8gzffsp59qz5rvn8": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1m6qdhgcgej0f898nmm99kc42qd2edtx8yz7p9tk09d8gzffsp59qz5rvn8", + 460000000000 + ], + "aleo15ekkuj8vw3jr7y587w2y23ywd0fycqz0p2el8s9d28n8uem0uvxq49esed": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo15ekkuj8vw3jr7y587w2y23ywd0fycqz0p2el8s9d28n8uem0uvxq49esed", + 137136000000 + ], + "aleo1w7xxm56sckhy60umt2vt0qddt0uepm48zuulfrrcrsvxmpghdypsuuzhyz": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1w7xxm56sckhy60umt2vt0qddt0uepm48zuulfrrcrsvxmpghdypsuuzhyz", + 100000000000 + ], + "aleo1yur28awsesnzxhusd59k4sh5e0j3ykrsjr2y3p8keua5wmrt8s8qp0w6k3": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1yur28awsesnzxhusd59k4sh5e0j3ykrsjr2y3p8keua5wmrt8s8qp0w6k3", + 1400000000000 + ], + "aleo1h0yhs9gv3y6at6h9jrxlgxtxz4zadtz8a890s36ef85dkgujpvxsaw6lpq": [ + "aleo1hdtsgk52nsualvrt4t676m9sydp6zllwe0mr4w5mzknxj3rkzs8slhszhs", + "aleo1h0yhs9gv3y6at6h9jrxlgxtxz4zadtz8a890s36ef85dkgujpvxsaw6lpq", + 3000000000000 + ], + "aleo1h8htd9wycst5fygy7l3llk0gperlfnxczvvquylqrnewm3gyhgqsu9ad9c": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1h8htd9wycst5fygy7l3llk0gperlfnxczvvquylqrnewm3gyhgqsu9ad9c", + 577500000000 + ], + "aleo16hlmhhacvz60amg4fvderydgh7j7204ehl2zxha5al45k6lu35ysw7f7j6": [ + "aleo1n6c5ugxk6tp09vkrjegcpcprssdfcf7283agcdtt8gu9qex2c5xs9c28ay", + "aleo16hlmhhacvz60amg4fvderydgh7j7204ehl2zxha5al45k6lu35ysw7f7j6", + 14064200000000 + ], + "aleo1lxzg8el3yjfx6umsea5aawyy4l335yjvusrkgtu7lzyrf72w55qq70wrxr": [ + "aleo1n6c5ugxk6tp09vkrjegcpcprssdfcf7283agcdtt8gu9qex2c5xs9c28ay", + "aleo1lxzg8el3yjfx6umsea5aawyy4l335yjvusrkgtu7lzyrf72w55qq70wrxr", + 14064200000000 + ], + "aleo10vhwhc0jwrzqfjlu8htpas8jdaazsgzwve93yqdzx08kgsk9mv8qjc28e7": [ + "aleo1n6c5ugxk6tp09vkrjegcpcprssdfcf7283agcdtt8gu9qex2c5xs9c28ay", + "aleo10vhwhc0jwrzqfjlu8htpas8jdaazsgzwve93yqdzx08kgsk9mv8qjc28e7", + 100000000000000 + ], + "aleo18ry8mc3ms8psrn67uw52tfsrp9z9ex6ackpw2s4khsqkee9xfsrsj7d7st": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo18ry8mc3ms8psrn67uw52tfsrp9z9ex6ackpw2s4khsqkee9xfsrsj7d7st", + 998679000000 + ], + "aleo1a73ftefplhp6wtfn6fm6337cs3rc3y5gcyeeazwtpgsunj4w4vqqkrunrx": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo1a73ftefplhp6wtfn6fm6337cs3rc3y5gcyeeazwtpgsunj4w4vqqkrunrx", + 14382827000000 + ], + "aleo1pl393a8m6ft9k59shx43lsqwxuf5mzr5w3shqkrrz8kn2fzj0cqq4n4pl4": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo1pl393a8m6ft9k59shx43lsqwxuf5mzr5w3shqkrrz8kn2fzj0cqq4n4pl4", + 13743589000000 + ], + "aleo1zf6mf9slaeg8u2th885tm6a3mdfw6kkv4u7wyuzl7tzmy2x49v8sp6a6yc": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo1zf6mf9slaeg8u2th885tm6a3mdfw6kkv4u7wyuzl7tzmy2x49v8sp6a6yc", + 13679666000000 + ], + "aleo1ygnmyaryeylyu387fydh6stz8rhjf4jldl68ney76dj0krq8lq9qy2vw52": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo1ygnmyaryeylyu387fydh6stz8rhjf4jldl68ney76dj0krq8lq9qy2vw52", + 13168277000000 + ], + "aleo19v3kdvxeqvl3k6dea8mvkkkgg0rfu4umy0eup5hp5eu52ly6vggq9g6wkk": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo19v3kdvxeqvl3k6dea8mvkkkgg0rfu4umy0eup5hp5eu52ly6vggq9g6wkk", + 13104353000000 + ], + "aleo1fxpy4s8trl05v0nxjk5e9plj075txuhjymcnws2s9kfmtf3v4qrs8ydgew": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo1fxpy4s8trl05v0nxjk5e9plj075txuhjymcnws2s9kfmtf3v4qrs8ydgew", + 12465116000000 + ], + "aleo18ruf9e6wcjgkd66ncxtgtqupn73xvcumuakpa568d307heh0gurs28ksvf": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo18ruf9e6wcjgkd66ncxtgtqupn73xvcumuakpa568d307heh0gurs28ksvf", + 12401192000000 + ], + "aleo16xc9d7lyu5sawrkt0nnweeqy7fq6ythy822dp60gkweumru6ggyqpkhk5f": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo16xc9d7lyu5sawrkt0nnweeqy7fq6ythy822dp60gkweumru6ggyqpkhk5f", + 11889802000000 + ], + "aleo1sghf70z3ppmvs2j6pqah5wkxsz2ny0rtcgeq7eyyagh7gztm8c9sttywpy": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo1sghf70z3ppmvs2j6pqah5wkxsz2ny0rtcgeq7eyyagh7gztm8c9sttywpy", + 11825878000000 + ], + "aleo1u5y6nhfl7ez47kerpu0rqam4jxc93nhpng29nmt3gmcmvfattgzsnrrh29": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo1u5y6nhfl7ez47kerpu0rqam4jxc93nhpng29nmt3gmcmvfattgzsnrrh29", + 11186642000000 + ], + "aleo1866k0fpa8ncsfwhsl49smxztxrvhwr0n4kx4ep9p5596ulz9wcqqzmas60": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo1866k0fpa8ncsfwhsl49smxztxrvhwr0n4kx4ep9p5596ulz9wcqqzmas60", + 2811069000000 + ], + "aleo1d25g09mvypl76sadtfhgcpdm3vnnffrallft8g3uu07p03ju5grqglxdkl": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo1d25g09mvypl76sadtfhgcpdm3vnnffrallft8g3uu07p03ju5grqglxdkl", + 2683292000000 + ], + "aleo198z79wdr3rxtmlw3c7qud2hx7luug6a39wg5awzevq3208p0cq8sxeshl4": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo198z79wdr3rxtmlw3c7qud2hx7luug6a39wg5awzevq3208p0cq8sxeshl4", + 2555517000000 + ], + "aleo1lfsxyrpcfcuzw6839jcuw2csta68uuuedvu4nj0rj07l0fd3ks9qrpxatx": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo1lfsxyrpcfcuzw6839jcuw2csta68uuuedvu4nj0rj07l0fd3ks9qrpxatx", + 2427741000000 + ], + "aleo1hwj60wec8c4ml8wh53kjz5ejwc02e0gyrccs2wsuen6cxe54gvxskmycfn": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo1hwj60wec8c4ml8wh53kjz5ejwc02e0gyrccs2wsuen6cxe54gvxskmycfn", + 2299965000000 + ], + "aleo1kftx8hkw0kz88cxp3nwuqmrrxy42xncxvaxk6pt8vl2ftehddcgsenlkse": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1kftx8hkw0kz88cxp3nwuqmrrxy42xncxvaxk6pt8vl2ftehddcgsenlkse", + 249671000000 + ], + "aleo137l47p4t8zt68da9lc89tg3dcq56g6yn708txnr2c3flckra8vqq4spc8e": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo137l47p4t8zt68da9lc89tg3dcq56g6yn708txnr2c3flckra8vqq4spc8e", + 7031250000000 + ], + "aleo1m25x36qt5x27v2qptlypj8ky3puf8nl0vvtfazx5e4zlf6qkwuzsgrz80s": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1m25x36qt5x27v2qptlypj8ky3puf8nl0vvtfazx5e4zlf6qkwuzsgrz80s", + 149802000000 + ], + "aleo19x0cjqghg0thspr3ddzza2ved2ewqnfmtcudm2s595uu5lpjsy8sycv3x7": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo19x0cjqghg0thspr3ddzza2ved2ewqnfmtcudm2s595uu5lpjsy8sycv3x7", + 249671000000 + ], + "aleo1ptsfk0nt96qa5tpr0uun4tesaywhf8gu4vjq2pxnw4cxev764vgs8eu7xl": [ + "aleo1hdtsgk52nsualvrt4t676m9sydp6zllwe0mr4w5mzknxj3rkzs8slhszhs", + "aleo1ptsfk0nt96qa5tpr0uun4tesaywhf8gu4vjq2pxnw4cxev764vgs8eu7xl", + 998683000000 + ], + "aleo1r3y7p79la2gv50y09f6zem9nme7ue5my03px79f7m00sfk4klcqsyvacqt": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1r3y7p79la2gv50y09f6zem9nme7ue5my03px79f7m00sfk4klcqsyvacqt", + 2496708000000 + ], + "aleo1t72uc4md9q8clf2g2a5sa7e68ulztqtkusd0sle7y53qzy8nnsqqq6ddkn": [ + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t", + "aleo1t72uc4md9q8clf2g2a5sa7e68ulztqtkusd0sle7y53qzy8nnsqqq6ddkn", + 4993416000000 + ], + "aleo1277fs8zmx602nrk5ywjc2ntcxgq9pk0yga6hyq079xmtn8etz5rs9rky5m": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1277fs8zmx602nrk5ywjc2ntcxgq9pk0yga6hyq079xmtn8etz5rs9rky5m", + 140625000000 + ], + "aleo1qd6e3scnppeu323x8n3k59v9pgw098e5nvgj8e6q9dv5apzufvqshyfre7": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1qd6e3scnppeu323x8n3k59v9pgw098e5nvgj8e6q9dv5apzufvqshyfre7", + 140625000000 + ], + "aleo1qy4qufq03wcph05fdf5aj09ez67vcmmlrzqf0zza352qwaq43gyqt3wdf6": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1qy4qufq03wcph05fdf5aj09ez67vcmmlrzqf0zza352qwaq43gyqt3wdf6", + 140625000000 + ], + "aleo1r50sqzn9areyc94t2ec4myy5t5x59pk5qwaxay6l29t0maq9m5xs9995ru": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1r50sqzn9areyc94t2ec4myy5t5x59pk5qwaxay6l29t0maq9m5xs9995ru", + 140625000000 + ], + "aleo1y46cysmnq9fevcs68qm0enp7u3fqmufjaakatjkfz47afp5n9cpq3xxgrx": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1y46cysmnq9fevcs68qm0enp7u3fqmufjaakatjkfz47afp5n9cpq3xxgrx", + 140625000000 + ], + "aleo1jly336exw8e64jtd4qqfhp6wc7wyxs58yyn9pw8l2tqz4ejm0vzszq0cgu": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1jly336exw8e64jtd4qqfhp6wc7wyxs58yyn9pw8l2tqz4ejm0vzszq0cgu", + 1171875000000 + ], + "aleo124mepz78ln5fl4awr8kaagyka6deyvr6pa0r9cfkk2jtwrqk5vfqttzypj": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo124mepz78ln5fl4awr8kaagyka6deyvr6pa0r9cfkk2jtwrqk5vfqttzypj", + 1171875000000 + ], + "aleo133vg3mmqths45lw7q8knfx04zeuvgrafy3lf59kl6k3nee2arsqqswlnfk": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo133vg3mmqths45lw7q8knfx04zeuvgrafy3lf59kl6k3nee2arsqqswlnfk", + 2343750000000 + ], + "aleo1f7clvaznwnceh2hx30akl0660pm9lk3p4j84j0p95ajk2w7zgc8s8gmau3": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1f7clvaznwnceh2hx30akl0660pm9lk3p4j84j0p95ajk2w7zgc8s8gmau3", + 2343750000000 + ], + "aleo1kldd35w0tcu82e202ksy9s83a8fznwer4z5datw7fxknd6jtusyqm3j7uk": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1kldd35w0tcu82e202ksy9s83a8fznwer4z5datw7fxknd6jtusyqm3j7uk", + 2343750000000 + ], + "aleo1t8j28tpac402nx0dpr4fjqaghxn766kvnde00hzkffzkvh0cycfqt5zxha": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1t8j28tpac402nx0dpr4fjqaghxn766kvnde00hzkffzkvh0cycfqt5zxha", + 2343750000000 + ], + "aleo1uzl5szknaq05z5s2y86058kxs5kme5ermmaeghutsfw9eta54uxqsn34tw": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1uzl5szknaq05z5s2y86058kxs5kme5ermmaeghutsfw9eta54uxqsn34tw", + 2343750000000 + ], + "aleo17d6q3kj8laxwr374hhu64hma4punap9n7gs7c5n54qljqar4sszsfqlk9y": [ + "aleo1hdtsgk52nsualvrt4t676m9sydp6zllwe0mr4w5mzknxj3rkzs8slhszhs", + "aleo17d6q3kj8laxwr374hhu64hma4punap9n7gs7c5n54qljqar4sszsfqlk9y", + 17578125000000 + ], + "aleo17vzf9r3drx4uu9876pr4mquewec4w6esc2l7cqfmvjhr4sj63uyqfhdfj6": [ + "aleo1hdtsgk52nsualvrt4t676m9sydp6zllwe0mr4w5mzknxj3rkzs8slhszhs", + "aleo17vzf9r3drx4uu9876pr4mquewec4w6esc2l7cqfmvjhr4sj63uyqfhdfj6", + 17578125000000 + ], + "aleo1w8gqamthnnht4eql06tjdpa0d4al79d4gpkdlqcevk7ud6hy9yrqcg6yhx": [ + "aleo1hdtsgk52nsualvrt4t676m9sydp6zllwe0mr4w5mzknxj3rkzs8slhszhs", + "aleo1w8gqamthnnht4eql06tjdpa0d4al79d4gpkdlqcevk7ud6hy9yrqcg6yhx", + 17578125000000 + ], + "aleo1yqer6549yt6033kxy65w6mgg3p006a6dkgh835rgltd46sgsesqs8cpnd0": [ + "aleo1hdtsgk52nsualvrt4t676m9sydp6zllwe0mr4w5mzknxj3rkzs8slhszhs", + "aleo1yqer6549yt6033kxy65w6mgg3p006a6dkgh835rgltd46sgsesqs8cpnd0", + 17578125000000 + ], + "aleo1yfy6rxj0mkv8mm0vnl48mk7lnlm4cgnlwvgwsyp3uxm7eya23gzsjvwue8": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1yfy6rxj0mkv8mm0vnl48mk7lnlm4cgnlwvgwsyp3uxm7eya23gzsjvwue8", + 4687500000000 + ], + "aleo16jndj42zwa2c4u3dlfewl2sw9s9pyy5s5ylya4sj8xe30jz345qqvzy7s3": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo16jndj42zwa2c4u3dlfewl2sw9s9pyy5s5ylya4sj8xe30jz345qqvzy7s3", + 46875000000000 + ], + "aleo1v66szkdedglappxhay6fe73nplh74dtxffupsx56h037rp4t5cps5e68re": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1v66szkdedglappxhay6fe73nplh74dtxffupsx56h037rp4t5cps5e68re", + 12351639000000 + ], + "aleo1xvyd220wmgq60xwtfn45pfszduwrupqf0ueuudtyu0zc9zhg3qys7g59g2": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1xvyd220wmgq60xwtfn45pfszduwrupqf0ueuudtyu0zc9zhg3qys7g59g2", + 3940000000000 + ], + "aleo1sk34qecfpx4u8tv5l39adw5hm2sfft83m6zdca3nmxjkzxptfuqs6j067a": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1sk34qecfpx4u8tv5l39adw5hm2sfft83m6zdca3nmxjkzxptfuqs6j067a", + 10341794000000 + ], + "aleo12hyw67830mgx7gw8mhh5myk7267xmtemvf9h9w7nwdgwl3kepcyqwzczwq": [ + "aleo1wu56llc4eaw08t63944fx7r69f9syneh30zjaykzna8z2wekl5rqem0nad", + "aleo12hyw67830mgx7gw8mhh5myk7267xmtemvf9h9w7nwdgwl3kepcyqwzczwq", + 15000000000000 + ], + "aleo19enxmhjpxejaa2zdt3k27g07nzksucsh0cyjx20dp5ve9ngxqyrs32lccl": [ + "aleo1wu56llc4eaw08t63944fx7r69f9syneh30zjaykzna8z2wekl5rqem0nad", + "aleo19enxmhjpxejaa2zdt3k27g07nzksucsh0cyjx20dp5ve9ngxqyrs32lccl", + 15000000000000 + ], + "aleo1yjtfucvv2s9aszgxd49sw330knunaua3ummz802dazmnz9w7gcxqq4p08a": [ + "aleo1af5kqnf4xt8tm8wdj4hwawq08tr583x0rhyrwcnf8y0jaedw4upswaefgw", + "aleo1yjtfucvv2s9aszgxd49sw330knunaua3ummz802dazmnz9w7gcxqq4p08a", + 20000000000000 + ], + "aleo10jmw3scav45qszlr79tsstwualnltwpu57gk0l7d4wz7xuq0c58swpm0a8": [ + "aleo1dsrv0z6wu9mgzl5l7wh62rwmrd4yt3zva7n4ayhvg02luvtqkqgq5tw209", + "aleo10jmw3scav45qszlr79tsstwualnltwpu57gk0l7d4wz7xuq0c58swpm0a8", + 20000000000000 + ], + "aleo167ync87ysjr9qdmpc8n4mvh8hfe7xlv95gua7eknkqka5y6v9qqskhujn7": [ + "aleo1q3gtqtd03fs7chhjdr8c4hf8vkwt96pf3vw28uytsdrnwt4hrs9sg7c62j", + "aleo167ync87ysjr9qdmpc8n4mvh8hfe7xlv95gua7eknkqka5y6v9qqskhujn7", + 10000000000000 + ], + "aleo1glulvw24c9u62qq50dtl37mursp0mgz8jhru45xz4rxn6054xv8sx3q9yp": [ + "aleo1q3gtqtd03fs7chhjdr8c4hf8vkwt96pf3vw28uytsdrnwt4hrs9sg7c62j", + "aleo1glulvw24c9u62qq50dtl37mursp0mgz8jhru45xz4rxn6054xv8sx3q9yp", + 10000000000000 + ], + "aleo1px3ace30tu6v90n0f47ythpqkdt84dh4c2qn4vjz2wyq2c5a7s8q3y67fd": [ + "aleo18xwgkgzwvzpw6yz8cdhrvrv6ztpd26zll46kd4kfcd79c9x90grsah3jug", + "aleo1px3ace30tu6v90n0f47ythpqkdt84dh4c2qn4vjz2wyq2c5a7s8q3y67fd", + 20000000000000 + ], + "aleo1ec50yxa676p6ymzd5qv7m9zmeh2cdwh48ws8pquw8zjyn6eu95gqhfa8xl": [ + "aleo1d37xxnms3sq5qxcnnh3dtvzr35xemjzas4jcytjr8uvymfetnu9salav5n", + "aleo1ec50yxa676p6ymzd5qv7m9zmeh2cdwh48ws8pquw8zjyn6eu95gqhfa8xl", + 20000000000000 + ], + "aleo17gq4vh96zp72jffqde6urc7ccvarz7p7yg8un7mpcjfjhlampqgsgzp4we": [ + "aleo1q3vx8pet0h7739hx5xlekfxh9kus6qdlxhx9qdkxhh9rnva8q5gsskve3t", + "aleo17gq4vh96zp72jffqde6urc7ccvarz7p7yg8un7mpcjfjhlampqgsgzp4we", + 20000000000000 + ], + "aleo1ur7lkcxdx6nwm8l8uq77tfy8ufxhcfu3sk9xxl7vrf05k9xyhgpqqxm9rs": [ + "aleo19t9f8nla683mzeaz5q2gv5u90zkx9v6azwvya7fswgfkfddaucxqxr0scu", + "aleo1ur7lkcxdx6nwm8l8uq77tfy8ufxhcfu3sk9xxl7vrf05k9xyhgpqqxm9rs", + 15000000000000 + ], + "aleo1xaafkw5szspu59rzy2nnnc6thhy8skrvgyhfqeh9vtzk3dafcsqq8dhssp": [ + "aleo19t9f8nla683mzeaz5q2gv5u90zkx9v6azwvya7fswgfkfddaucxqxr0scu", + "aleo1xaafkw5szspu59rzy2nnnc6thhy8skrvgyhfqeh9vtzk3dafcsqq8dhssp", + 15000000000000 + ], + "aleo1tsp2n8crlnk4zq70k466pe33jkd9ff4845ct473zjg8ec4ndtqpq8cq6xd": [ + "aleo12tf856xd9we5ay090zkep0s3q5e8srzwqr37ds0ppvv5kkzad5fqvwndmx", + "aleo1tsp2n8crlnk4zq70k466pe33jkd9ff4845ct473zjg8ec4ndtqpq8cq6xd", + 10000000000000 + ], + "aleo1yeeaxjtlevc8pq24emxuazrgngaxx8m3hqtgx4d9nevw3c72eyyqtwekc6": [ + "aleo12tf856xd9we5ay090zkep0s3q5e8srzwqr37ds0ppvv5kkzad5fqvwndmx", + "aleo1yeeaxjtlevc8pq24emxuazrgngaxx8m3hqtgx4d9nevw3c72eyyqtwekc6", + 10000000000000 + ], + "aleo1vsee8e9277wt2cz9k7tuz3dlnrt8xcflx5vxhwcwq3ctucveaqqqgmy8nc": [ + "aleo1anfvarnm27e2s5j6mzx3kzakx5eryc69re96x6grzkm9nkapkgpq4vyy5t", + "aleo1vsee8e9277wt2cz9k7tuz3dlnrt8xcflx5vxhwcwq3ctucveaqqqgmy8nc", + 20000000000000 + ], + "aleo1u7ze7cn030ddhcpk58kgh99u9vdwjg2zrda93tatd23sjmvh7ugsfjgp6y": [ + "aleo1anfvarnm27e2s5j6mzx3kzakx5eryc69re96x6grzkm9nkapkgpq4vyy5t", + "aleo1u7ze7cn030ddhcpk58kgh99u9vdwjg2zrda93tatd23sjmvh7ugsfjgp6y", + 20000000000000 + ], + "aleo1qhgarp578ev29ta877f6y79nj3m3upyzf49t4qqfrkan467lyuqqcu802c": [ + "aleo1anfvarnm27e2s5j6mzx3kzakx5eryc69re96x6grzkm9nkapkgpq4vyy5t", + "aleo1qhgarp578ev29ta877f6y79nj3m3upyzf49t4qqfrkan467lyuqqcu802c", + 20000000000000 + ], + "aleo1zuh5kdysktqr4g0a9z3py2npdqe4hd0v4rk4vzy6xvrzserpmsrqu8677r": [ + "aleo1anfvarnm27e2s5j6mzx3kzakx5eryc69re96x6grzkm9nkapkgpq4vyy5t", + "aleo1zuh5kdysktqr4g0a9z3py2npdqe4hd0v4rk4vzy6xvrzserpmsrqu8677r", + 20000000000000 + ], + "aleo1fveelav4mze9568cdyktjjgakylng62h3us9cvrnjkfmfy62rszs8czanu": [ + "aleo1anfvarnm27e2s5j6mzx3kzakx5eryc69re96x6grzkm9nkapkgpq4vyy5t", + "aleo1fveelav4mze9568cdyktjjgakylng62h3us9cvrnjkfmfy62rszs8czanu", + 10000000000000 + ], + "aleo13eq882hjvr3elj7us305l0ft9zpxq2ltl7kh9apjtya4rywmhygsltaumx": [ + "aleo1anfvarnm27e2s5j6mzx3kzakx5eryc69re96x6grzkm9nkapkgpq4vyy5t", + "aleo13eq882hjvr3elj7us305l0ft9zpxq2ltl7kh9apjtya4rywmhygsltaumx", + 10000000000000 + ], + "aleo10ta8rju94rme6nsu65pwvtylk0e3z9mrtnx2l0z5r8ykccra6c8symuw5f": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo10ta8rju94rme6nsu65pwvtylk0e3z9mrtnx2l0z5r8ykccra6c8symuw5f", + 10784163000000 + ], + "aleo13m4rqnnt07wps6ceqskk93mnq2hjysyw996gx597utcchkvm6ups84uqw7": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo13m4rqnnt07wps6ceqskk93mnq2hjysyw996gx597utcchkvm6ups84uqw7", + 10784163000000 + ], + "aleo1wsjk67j9djsg7utwr429umz2lrqwg6u94tu0sazf9k59yp0hyczszvw8n8": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1wsjk67j9djsg7utwr429umz2lrqwg6u94tu0sazf9k59yp0hyczszvw8n8", + 10784163000000 + ], + "aleo1pclpavgqrlh6pnn47zvg4qzemntzme7ghcn48jckqsqdxm8zavpqn0px6w": [ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls", + "aleo1pclpavgqrlh6pnn47zvg4qzemntzme7ghcn48jckqsqdxm8zavpqn0px6w", + 10784163000000 + ], + "aleo155hljz7d52mym5j7qrgkkkwmkeyruaerp94c25wyh3kqxvutasysvw66s4": [ + "aleo1hdtsgk52nsualvrt4t676m9sydp6zllwe0mr4w5mzknxj3rkzs8slhszhs", + "aleo155hljz7d52mym5j7qrgkkkwmkeyruaerp94c25wyh3kqxvutasysvw66s4", + 10784163000000 + ], + "aleo1xlta2uzdg6xuxx2gm2msadqnnqhzumdf748nmeu7e3u5jnu32cxsgtnz0h": [ + "aleo1hdtsgk52nsualvrt4t676m9sydp6zllwe0mr4w5mzknxj3rkzs8slhszhs", + "aleo1xlta2uzdg6xuxx2gm2msadqnnqhzumdf748nmeu7e3u5jnu32cxsgtnz0h", + 10784163000000 + ], + "aleo1q4k7lknx22kwteh5fs5kekgqt2k9z285h3snnsa80csrznml358qf36nen": [ + "aleo1hdtsgk52nsualvrt4t676m9sydp6zllwe0mr4w5mzknxj3rkzs8slhszhs", + "aleo1q4k7lknx22kwteh5fs5kekgqt2k9z285h3snnsa80csrznml358qf36nen", + 10784163000000 + ], + "aleo16aw5kz3caf3rm5h3fwmh7xna999ge3evmuta3djze89t64q26srswdar4r": [ + "aleo1m5vc6da037erge36scdmefk0dcnrjk9tu04zyedfvxunwcwd3vxqtcy7ln", + "aleo16aw5kz3caf3rm5h3fwmh7xna999ge3evmuta3djze89t64q26srswdar4r", + 10784163000000 + ], + "aleo1823a9jru5q2rappstljx5srs6ukd2l4e9akajezafmf7v6ykuy9qn7elzc": [ + "aleo1m5vc6da037erge36scdmefk0dcnrjk9tu04zyedfvxunwcwd3vxqtcy7ln", + "aleo1823a9jru5q2rappstljx5srs6ukd2l4e9akajezafmf7v6ykuy9qn7elzc", + 10784163000000 + ], + "aleo19y87xmlm45sqga59wns5952nfycplrw0u0l75ylmk4w6vam59uqq0wewpz": [ + "aleo1m5vc6da037erge36scdmefk0dcnrjk9tu04zyedfvxunwcwd3vxqtcy7ln", + "aleo19y87xmlm45sqga59wns5952nfycplrw0u0l75ylmk4w6vam59uqq0wewpz", + 10784163000000 + ], + "aleo1ecwf0cjxemlv7uw6j08tepqnwr4f8eczcr9vmkvvks5wj5wcfygq220akt": [ + "aleo1m5vc6da037erge36scdmefk0dcnrjk9tu04zyedfvxunwcwd3vxqtcy7ln", + "aleo1ecwf0cjxemlv7uw6j08tepqnwr4f8eczcr9vmkvvks5wj5wcfygq220akt", + 10784163000000 + ], + "aleo1h67mr9cd345zft7qyu2c352h09ukuaspa6l646cya2ssaje96qxqrjfhfm": [ + "aleo1m5vc6da037erge36scdmefk0dcnrjk9tu04zyedfvxunwcwd3vxqtcy7ln", + "aleo1h67mr9cd345zft7qyu2c352h09ukuaspa6l646cya2ssaje96qxqrjfhfm", + 10784163000000 + ], + "aleo1ma7nk8e85f0usgwt6vtm02779zw67gh329h2e0jdzcpsyhwhvgpsm4m8s6": [ + "aleo1m5vc6da037erge36scdmefk0dcnrjk9tu04zyedfvxunwcwd3vxqtcy7ln", + "aleo1ma7nk8e85f0usgwt6vtm02779zw67gh329h2e0jdzcpsyhwhvgpsm4m8s6", + 10784163000000 + ], + "aleo1n6snqf78c23c44vnynhkc7umujut7rwhnvznmukp2txta0fpzsfqpjfxje": [ + "aleo1m5vc6da037erge36scdmefk0dcnrjk9tu04zyedfvxunwcwd3vxqtcy7ln", + "aleo1n6snqf78c23c44vnynhkc7umujut7rwhnvznmukp2txta0fpzsfqpjfxje", + 10784163000000 + ], + "aleo1rdraw65s8xpm6gzupumdpyr63nxsg0evnuwt7fdal0apcan57yrs39ms28": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1rdraw65s8xpm6gzupumdpyr63nxsg0evnuwt7fdal0apcan57yrs39ms28", + 10784163000000 + ], + "aleo1s3g5nmwd349mf8csu305av9xgq36a5vrkcjw79lg836zf8pvm58se4942q": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1s3g5nmwd349mf8csu305av9xgq36a5vrkcjw79lg836zf8pvm58se4942q", + 10784163000000 + ], + "aleo1swhwd4gjkmkfnsusul502l68mp0v3972qep8klr5sxqf6d65dy9qftvtyy": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1swhwd4gjkmkfnsusul502l68mp0v3972qep8klr5sxqf6d65dy9qftvtyy", + 10784163000000 + ], + "aleo1uyhkz5q6e0px3csltv0rdlv4n4yzmrft5cgvx8e2mc8au8eu0ygsxea3cc": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1uyhkz5q6e0px3csltv0rdlv4n4yzmrft5cgvx8e2mc8au8eu0ygsxea3cc", + 10784163000000 + ], + "aleo1w6jkccdy07mvp2ncuw92hcf6qww80lcw4df9khrth8kqtv22xgzquv4rsj": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1w6jkccdy07mvp2ncuw92hcf6qww80lcw4df9khrth8kqtv22xgzquv4rsj", + 10784163000000 + ], + "aleo1wdyzn9wcadwyjn9fz5mqrnm0gcwxef7xzuycz874r8d2t54r8spscq8n0z": [ + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52", + "aleo1wdyzn9wcadwyjn9fz5mqrnm0gcwxef7xzuycz874r8d2t54r8spscq8n0z", + 10784163000000 + ], + "aleo15wpy0ptmfp3asg9pmlwce3w65g5e4mkxr4yn3jglmekef23ktsfq8l979q": [ + "aleo1m5vc6da037erge36scdmefk0dcnrjk9tu04zyedfvxunwcwd3vxqtcy7ln", + "aleo15wpy0ptmfp3asg9pmlwce3w65g5e4mkxr4yn3jglmekef23ktsfq8l979q", + 10000000000 + ] +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/genesis_public_balances.json b/parameters/src/mainnet/resources/genesis_public_balances.json new file mode 100644 index 0000000000..dec6c32e59 --- /dev/null +++ b/parameters/src/mainnet/resources/genesis_public_balances.json @@ -0,0 +1,138 @@ +{ + "aleo133y0hmcvcrtc8h8sarg2q8u2wd80y832as33yjvwt24gnrpawcgqv35f73": 323340000000, + "aleo1lsqkt6hv23sgtc0dm85asmu94gtsg9nwh3fsfx0jfvaveaw9hcgqjvjlgh": 100000000000, + "aleo1xhj70rqqrge2ma8s9enhxxafzc7ca4fmy7xw8v3txt8fusjt0yzqy0jrhl": 58750000000, + "aleo1r4u8nkxqfrauq8wt50ft86c8jrvrz3rsvwdljpmwkmsrwzg7gupst4g2q0": 35624626000000, + "aleo1nevs44gr0g5dqw6hv9auvn9sd4xxwt5fhhmg6apkdkx8zxvymqpsagk9hr": 2343261000000, + "aleo10vcxw744ptk6p4mfhdq6aunz54k0metd8ynvn9k35uf8dmvktgysx2656e": 577500000000, + "aleo1zv2m0y6rl5z729vf2gnt04rlnfp8qwzvm2tas9cgfr3z29p5mugqchjqqy": 228593000000, + "aleo16zwv878wskhamf43jt7mvexqv3efl7dpx0s94xts7f7kg24v9g8q4hwj70": 1180000000000, + "aleo1r2tgdetqyn62ydr322adr7v8x7n0n0xm22u3hwnjez52wh7x7vqq6dekek": 75000000000, + "aleo1grh73zs6enlz697vr5r67mvdrj780y9qf26sq8p47xu9z0du2urqulwp3s": 70000000000, + "aleo1jljdp9jch23pm0p7f5ndhdyx2er3ff7epnly60hq76uwureu5u9sr3faaa": 70000000000, + "aleo14egtjeerasckcjz5e2h5pmudehz2feckudf4qus8kf0dyu79fyxq8x800g": 60000000000, + "aleo1rdc9gkf92ahqaahas4efcny0f9edqthuaqycjm2cj7xq2u69aqzs8xh0qm": 48360571000000, + "aleo1fgc5ku80v7eyjkm9579pyx976ew25my0d6n2rtxklc72266plggqfl3ndr": 25000000000000, + "aleo1dx2war20thpyem2nmj3nzeupn03vpau07nka7kjcl0em7f40cuxqfrl3zg": 25000000000000, + "aleo1lh07t92lssveqtc8zrn6dse67cfxt7a5tlhscwpscr96phk3lcpq0fk8j9": 25000000000000, + "aleo1zd8lqxk7mlcmwm6crrae4vcpw4ydqff0knw77ap2zrlvutq3ecrqf3gdup": 25000000000000, + "aleo1jfsw7fwd8njh8zlum8uvp7xrmw5tha3tvwlr9wrftk72msss8s9s0z6uqx": 1000000000000, + "aleo1juqqx2zpt7297ksdqkswjqgsw3xaxhmpgqlwntk2gzlzcd2dd5zsgedkkv": 6102240000000, + "aleo1y0f7nkk2gn4fpd876pl54dmgatz0luz6w38h26la5lhhxt4jzyfqe5tgsc": 6102240000000, + "aleo1l7w0qyzftwqxvydz0tjxv2nfd0wpp2ncq35mecg97f37taawr5xssdhz6m": 3514891000000, + "aleo14t63us2r8jr9dyld6psd5g93npz3wantf4a9x27chfzdfkassqyqy08myt": 3514891000000, + "aleo1p2jus7cukq7tgt5ta7r3t0vm6g28nwg8jf22t56q05sg7q00purq5pecms": 2643857000000, + "aleo1fnpz5r0rkzggtyhyla749aafnqxms70lyrz2puqc24p3sdkllgxqda8urv": 1562174000000, + "aleo1j84267aflalhler05yxw5j45sxzv87zlyzv2e6f58jmfl262zyqqnl7662": 640735000000, + "aleo18ek3r92ufc84je97rd4rkwh04vqc7ucvg4sha52m49keph8uryzsqtkt40": 517635000000, + "aleo1d0dv0xfr327ydwe0hwrwemt94h89v0msa67htq0fseufmf92yvrs6pykmk": 117636000000, + "aleo1vevurpd8pp8djvemwvdxg8wmy4lj64zwwj5ju5q36djkxterrurstqxydm": 100000000000, + "aleo19ef6ew7y4nx2pflquqnrv9c3dgzfn52akjd9uj2mnrpmmklzns8sc4fwhj": 97636000000, + "aleo10egca5endeu6dkewyjppfzfmrs69udfk99akrq8rgfk2wjmr5qpqt6lzg3": 81363000000, + "aleo1j6u4k6ey3fys26hgtscee3jgmf2luf967nglx028c69mlc9y7vyqz5802x": 78804000000, + "aleo1w39rxmemeuj0gcfq2nxrfjvt2zz940nsf6gmudcnv4mdx2m9vggsmanvyf": 69158000000, + "aleo1uj24ty3q74sffxn9uufesxhg3md4uw0em4055aztdwd9pfpxlsxqddfrhp": 69158000000, + "aleo144rrzh2g6v2mkkn0talsfehf038cmkphxxgjt032z60n3qkk5c9quyaakj": 63646000000, + "aleo19c3tc2cz4hkunnyfw25g7z29tthax9jr7lhwn6mh7dl00pcdpgrshhnz8x": 54920000000, + "aleo1yp8m4wq7ak6wm5zj47le7544hexczzsapg6gfmha8vns6d2mccgslv6hzz": 50000000000, + "aleo1fl5g8y9rdkxmk7rgnw9c6st9vhgek7fgaky8enp3adx53sfezq9q29nt4t": 50000000000, + "aleo1sqj54qjahcuwuesjs7dk25gt8zah8hwtl8n8eh94hnzslde9j5zsn90lty": 48818000000, + "aleo1n09623m4z39wudrd9rpn96jns64t292umwccrg0uxqf0rfyr7crq0hcltu": 45000000000, + "aleo1p4qk93g2wrmvrg7ax59eqgueg3x66cyfl80n0kw66t3l048nryysq0devq": 42715000000, + "aleo199z6wl2rnh242f89gylzegt3adnktsjqzelvmxzfea80lx6z4ypqte97gt": 38647000000, + "aleo1v5yzrwdhfsyx70sfdw020fzu9glu33629dcj7ymnwcfk3lu95q8sjxl3kw": 30000000000, + "aleo189004ka24e4j3226nred9nleupcctytmvvgydnnv05az5lwz4yrq9yyxpx": 30000000000, + "aleo17u0x9xd7wp9zypp6vtcs9jrhhj8ae8rrc2yzh4xr0qgkan27rugs3a3e3k": 30000000000, + "aleo1388tzd4uzasjgcdrkt2e3tu4c4chgyuhvjc9f29dju7ccz5jdgxqgkykfw": 26443000000, + "aleo1atzmysxdmywln7s875qdeu4h0anpclrvffrsgw4rmvdwnkd5mvys0ghv3l": 12187000000, + "aleo1amj7rm5gl5d053a6mfl9zzae3dflclwg9cy86l9gr9xepplj7gps5suwqc": 12187000000, + "aleo1d67hf3qa35xxjxf3sl4wdh900rv4r58lzsreqmlrt8flrk5rfc8svllhmk": 9750000000, + "aleo197ndkeg2ve52m83kuljhwm9qmp9nld2nq72dw490hrtgjvd9ss8qx85drr": 4875000000, + "aleo18ry8mc3ms8psrn67uw52tfsrp9z9ex6ackpw2s4khsqkee9xfsrsj7d7st": 4000000, + "aleo1a73ftefplhp6wtfn6fm6337cs3rc3y5gcyeeazwtpgsunj4w4vqqkrunrx": 5000000, + "aleo1pl393a8m6ft9k59shx43lsqwxuf5mzr5w3shqkrrz8kn2fzj0cqq4n4pl4": 5000000, + "aleo1zf6mf9slaeg8u2th885tm6a3mdfw6kkv4u7wyuzl7tzmy2x49v8sp6a6yc": 5000000, + "aleo1ygnmyaryeylyu387fydh6stz8rhjf4jldl68ney76dj0krq8lq9qy2vw52": 5000000, + "aleo19v3kdvxeqvl3k6dea8mvkkkgg0rfu4umy0eup5hp5eu52ly6vggq9g6wkk": 5000000, + "aleo1fxpy4s8trl05v0nxjk5e9plj075txuhjymcnws2s9kfmtf3v4qrs8ydgew": 5000000, + "aleo18ruf9e6wcjgkd66ncxtgtqupn73xvcumuakpa568d307heh0gurs28ksvf": 5000000, + "aleo16xc9d7lyu5sawrkt0nnweeqy7fq6ythy822dp60gkweumru6ggyqpkhk5f": 5000000, + "aleo1sghf70z3ppmvs2j6pqah5wkxsz2ny0rtcgeq7eyyagh7gztm8c9sttywpy": 5000000, + "aleo1u5y6nhfl7ez47kerpu0rqam4jxc93nhpng29nmt3gmcmvfattgzsnrrh29": 5000000, + "aleo1866k0fpa8ncsfwhsl49smxztxrvhwr0n4kx4ep9p5596ulz9wcqqzmas60": 5000000, + "aleo1d25g09mvypl76sadtfhgcpdm3vnnffrallft8g3uu07p03ju5grqglxdkl": 5000000, + "aleo198z79wdr3rxtmlw3c7qud2hx7luug6a39wg5awzevq3208p0cq8sxeshl4": 5000000, + "aleo1lfsxyrpcfcuzw6839jcuw2csta68uuuedvu4nj0rj07l0fd3ks9qrpxatx": 5000000, + "aleo1hwj60wec8c4ml8wh53kjz5ejwc02e0gyrccs2wsuen6cxe54gvxskmycfn": 5000000, + "aleo14ajlf9segep8rgspe8ruqg0eyvssqrjevzlafy74x647sedm0cxs5gp509": 7989466000000, + "aleo18ct0pg4607uy89lfkw4m7fgw2guwy7p56rrgs67avp99q2zc25rq9zmvu4": 13762990000000, + "aleo1tet9q8h2gg63j4yxrldsa67y5kdugv87q4dc4je5nvku0c3vugrqzfyjgm": 11500000000000, + "aleo1y563rzw0amux87ucuh9gugjv6tlmaxm2ge7l33fkt0lre0k3zvqqxc7fhu": 15300000000000, + "aleo15dmq34aqvh4wnd5dve6q4g35pfd47hpz6hsfgxfmmdqfqyl9vcrsqqd27p": 12800000000000, + "aleo1rv3e3pldrsvajh8wt7lmdgegr68pmzh56sphn5h8zhyjuvh7mcpsgpfv5t": 11400000000000, + "aleo1p7sa3uqdwcxkz4ah05rpwaklqlh68z5w5jnfjw9la89vpmspdsysug9j4g": 12400000000000, + "aleo1jcs4qfrth590e8p7mpq97zsv0nje3c3ku5xnjk8we62qks69av9qdrtlg6": 12500000000000, + "aleo1p8t3sge7glx99hr4nk7x09jfurnlxmu4turnurjv39r2fxqydqys06ku6e": 17300000000000, + "aleo1pnu2xmx5xjsfq6up4mgejasvasf7l93aykkqarejzhd9n99pd5yskkfzw0": 17500000000000, + "aleo16yh4un57d8cs6gxavdp4h93clz0gs9xwcmjyglvczm9earjy9qrqezv22c": 12300000000000, + "aleo1tq34lq20vezx25amwm5kg7dxtjyets574cx099fx22hsfqawncrqmclvur": 19800000000000, + "aleo1qglgcl4elyrhayl8xzzvutxrqhyu7zv8zxhtluzprzkmrmgw0spq7ecf84": 11800000000000, + "aleo1gz67w2dw73p0csm6xrswl9yfz865an56exhec5x5ucgplj85rq9sxdjlxk": 11400000000000, + "aleo1z26qdnklknxyesvk74e23ef00y8pt0szy9j0vz7fa32knx46fsqsg5euq7": 7989467000000, + "aleo14aknju3kv8phldntax7v2gea7zz03j7w8ve0e04e9yur5l5kqc8sczrjg9": 7989466000000, + "aleo1t38e6jr5atvgwydngy9pu3qak4qr2ygvwthkutngqzvuk4rk2u8sd46pdj": 7989466000000, + "aleo1tl043gmmth70sdvzr8xk55lpgqv7q6raa7nq37tuwqer8jmdevpqc2papu": 7916667000000, + "aleo1nrkg28vduc9ckhf8nt0kww60p25zeuutj5tj6w49smd4mehsaurq590m4r": 1750000000000, + "aleo1zyrw7m47kc0atxwrtpwg08v0mqr393nfz9es2ehag0rnuxfvrvqsfd5e7u": 1750000000000, + "aleo15jvycc8yaasuau6jv4gfjdnfv2frm3c2t5h6z3c0hu2sm5qj85gq79emsx": 778750000000, + "aleo1nre9xv8kyuunztqjsjztha522pss63e80285ccd7x26g84rm8u8scrvhdp": 610544000000, + "aleo1xgdy3hln7uk402hquqs0updr607fq7eeyktdw2sc0ez4jqlfnvyqj272e2": 661700000000, + "aleo1zvrqzksewrpz4zcc3utveskm3fu8s7r3m2gf64d8dy30amsh5ursppdpa6": 600000000000, + "aleo145e9z8ln7lswnmljynflg42n37ey68xf905hjz9a78y6dtry5vxseu9jc0": 315272000000, + "aleo1nje4x5lwmnfynuvclxxqqaljda83y6w5hj0drgqpwh3ueszdzcfqg8egda": 266803000000, + "aleo13cra8uq8l5uwvzfedpq7mj75hc3fw6ff9s5kan6pxl5ljx0j5vrqsp3lu3": 807830000000, + "aleo1ty4xmu9kpl6vkxq3g4u9yv0w7d200cylkp4gkwfqp6xl64y82gyqcpklmn": 436386000000, + "aleo1f6n9kfwwqu5j5x7tq9y4hdd7pk9rjkfvlv4qwpm6vzvdx7ushv8q7quk86": 193125000000, + "aleo19dzp3cqnr5ll32upth830fs5grd9ru5ehkql8vpenh3sarcy9sfqsnjhaw": 150833000000, + "aleo1dfgdw2ayc7uzhfnu60s89ay84v4hxpj5uk80u7jjp6hdqzu9esxqmzru0a": 110000000000, + "aleo123pwwjq79uzrclwg4lc93e9w5v0sz4gmncuqnt76l20dyxscdcqquvurjd": 93125000000, + "aleo1fau627e9009ef3j0dxnpj5kmks7kdnt0ljyz0pl43w2gyfz4vqxs5ace3m": 93125000000, + "aleo1qmf6nlhcn27vdrttf8rsfegv4l6hp4wceqjppmplu056qsce7u9sunmrgf": 200000000000, + "aleo1ptl6tjq6r7afu7vp0qt9azrzmdukw502590jtk49htv658cuhv9sh9hhkj": 360000000000, + "aleo1sf9hdt4nfkmtgnhq3cak2jhhxxgz2yw2esnj3j534e9y9wzwxvqsh6q5cf": 64583000000, + "aleo1f0gumcfg6acx2vwhl4r655fhxrxtz9fr46tnr68wf2ryv2tqlc9qunwjka": 135000000000, + "aleo134sjx6mrrqxsxvj3gwsvdk5g458xn9v9d47lwp46kfc0fvxjlsrs9jtutr": 30000000000, + "aleo174wuzssxqul4qv6fu607e9yplmzu4449nwuc8m6zqlfzqc0u4qpq5mvj8w": 30000000000, + "aleo1gzgfmwdumvvqq67m7x0xgxj4mem0ftaxjtw76l3qxa5m4v9axsysuylulf": 29750000000, + "aleo10vhsexf0hx46kkm5p5s7hud42l4z5lt3fna3khxxxkjzwuzklvpqfapqnu": 85000000000, + "aleo1mtxd2xwymchujaumzmms7jxp8u29gjqkalyggxfjcfyzvzmcv5pszpsq9h": 50000000000, + "aleo1jz48svzjm670m83v8ru08l5eanapxx9f9r93t5xx7jpr399jdvgs6ckd4w": 3000000000000, + "aleo1sdwqg3072zm4twn76n2xe8c5exxfg9qd3lq0mwh929h93whju5gqy2050w": 200000000000, + "aleo1tj5daaewxezjgaly9r2zmkj5ryf5c5yuxewzx6tk2nuaks9v2sfqvw32gy": 5000000000, + "aleo157fuufe54qgz0samll3lekq2hqhc9aahfrddkyfny28dzmeg4crs4q7mgh": 600000000000, + "aleo105qxh7mynwks2vqfpn27a6caqwpj0mk5jg2c95e8tstn79awcqzsuhgr9h": 66667000000, + "aleo1njctsewqjx9e29260kkqf2alyd0rnak38tf230c59hcjckq7gcqqrxlznv": 59324424000000, + "aleo1j2xkasy3pawvet7n0jr3wnhfcchw6dqnheewx83gt7g8ynj6zugqcgl4tm": 7903750000000, + "aleo12wc902nfw60ky7srgtagc072aewpkh83wr84vh5568wtrm7xxcyqe0l0gk": 10000000000000, + "aleo1h9c0frgllm2fmtfkfe9wd6lusfkuw44prekc220cr2hdzfxzfq8qzrzmfn": 3000000000000, + "aleo1ykzj6ukmxxxvd3xe5j9j8vtfdmruyte3a6rvxpwu798dyqvm2qgqk4fwtp": 2500000000, + "aleo18l9m0u4ndxe9w8fyjw67y6ae7ydmkegjhfeqx2clkw8dq3963sgq0yntqd": 10000000, + "aleo1ss8jsght7ey2ul3wjsrccf2m2dguzakz03a5fszzznt32zzefszqxqnj0k": 10000000, + "aleo1st8x7ng74nde3x753u5y9c4cvgcpcp668ndcagucvuqltp3tgv9shqltkn": 10000000, + "aleo10yvuu6svtfskgxnxuznh86gksewl743jkfxw3yshcaxyuqgpcq9qesevgw": 10000000, + "aleo1lxs2fe32fv084gavgeq8yh3h4f8778c3vskcn5dd8a0mqde365zs7m0nad": 10000000, + "aleo18rxfnwymru2j3prsuk070u4atf2zdnk3yp99x6s948a2q0ldsuyscu9t42": 10000000, + "aleo1dzwkf82y93q54gj6kaydexexkde8kp84mx0qhj4es6arqcjxkuxsd0dsrv": 10000000, + "aleo1k3w8l8kmwjxcs5rsnnqp9p2z65s68ltk6kn559fw7per4mzgzvxsmsp8rz": 10000000, + "aleo13kxtmlp3u37m9np4zf465rapd2h8gxhxv5wmp8q852hxhnnfac8s9769tn": 10000000, + "aleo1mj07es0ar580s9sdqk036jzpxxaewpuwylw53hyvjtlj4vaknvxsmm0ux2": 10000000, + "aleo1g5wrxvgyvckgtuceg36eg6pf024x3p6nex05lcefz0h6576rmgrs22dr4w": 10000000, + "aleo1xx0fqugtrm0kv872dj5ujhyx3kjfrdtz5vj23hmq4p9cqwtvfs8se6ct93": 10000000, + "aleo1t0tjdmwfz89s6d50xrzapp8f6aks5pqm0lf46xvz2y200s9rasps9g0scu": 10000000, + "aleo1mjql67fre85nu92mjyf6024ua2zwg60l7udwtn27qdnlsx2qxvzq08vdmx": 260010000000, + "aleo1celn0jtuurc5s2k2v697e3nuuf3nrlhaymrmwljqqkhnlnt3kvpqdz62dd": 10000000, + "aleo1xzspdh569aajes9gm6w9pt535zdtj9tc3npf3245gasl76t03ypqu63k38": 10000000, + "aleo15jklh2w7964apw5cpqax4hddadpy9tx5n9lz8879twcajazdwspqjds0jr": 50000000, + "aleo1uc970xpa7w98enygh3lc5s6twvad9fmm8j3yvdyjxxfll0wfeqrs0lwcjz": 5000000, + "aleo176kj4y74n3ls24erc848e8wf3kf3vhwh6yp64qcuw93z469payqs38anfg": 10000000 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/genesis_validators.json b/parameters/src/mainnet/resources/genesis_validators.json new file mode 100644 index 0000000000..d83c52603c --- /dev/null +++ b/parameters/src/mainnet/resources/genesis_validators.json @@ -0,0 +1,98 @@ +{ + "aleo1vfukg8ky2mhfprw63s0k0hl4vvd8573s6fkn8cv9y0ca6q27eq8qwdnxls": [ + "aleo18l9m0u4ndxe9w8fyjw67y6ae7ydmkegjhfeqx2clkw8dq3963sgq0yntqd", + 100000000, + true, + 10 + ], + "aleo1hdtsgk52nsualvrt4t676m9sydp6zllwe0mr4w5mzknxj3rkzs8slhszhs": [ + "aleo1ss8jsght7ey2ul3wjsrccf2m2dguzakz03a5fszzznt32zzefszqxqnj0k", + 100000000, + true, + 10 + ], + "aleo1m5vc6da037erge36scdmefk0dcnrjk9tu04zyedfvxunwcwd3vxqtcy7ln": [ + "aleo1st8x7ng74nde3x753u5y9c4cvgcpcp668ndcagucvuqltp3tgv9shqltkn", + 100000000, + true, + 10 + ], + "aleo1qc46ca98xxjy34v37ge75yydyt36mgatqup7zrjra6gp9huatsqsjv6p52": [ + "aleo10yvuu6svtfskgxnxuznh86gksewl743jkfxw3yshcaxyuqgpcq9qesevgw", + 100000000, + true, + 10 + ], + "aleo1wu56llc4eaw08t63944fx7r69f9syneh30zjaykzna8z2wekl5rqem0nad": [ + "aleo1lxs2fe32fv084gavgeq8yh3h4f8778c3vskcn5dd8a0mqde365zs7m0nad", + 100000000, + true, + 10 + ], + "aleo1af5kqnf4xt8tm8wdj4hwawq08tr583x0rhyrwcnf8y0jaedw4upswaefgw": [ + "aleo18rxfnwymru2j3prsuk070u4atf2zdnk3yp99x6s948a2q0ldsuyscu9t42", + 100000000, + true, + 10 + ], + "aleo1dsrv0z6wu9mgzl5l7wh62rwmrd4yt3zva7n4ayhvg02luvtqkqgq5tw209": [ + "aleo1dzwkf82y93q54gj6kaydexexkde8kp84mx0qhj4es6arqcjxkuxsd0dsrv", + 100000000, + true, + 10 + ], + "aleo107mzqjf3w2mw70wz0uy9r3u95y4s7af27jzxdyemz3sf9ase7v9ss6nr8t": [ + "aleo1k3w8l8kmwjxcs5rsnnqp9p2z65s68ltk6kn559fw7per4mzgzvxsmsp8rz", + 100000000, + true, + 20 + ], + "aleo1q3gtqtd03fs7chhjdr8c4hf8vkwt96pf3vw28uytsdrnwt4hrs9sg7c62j": [ + "aleo13kxtmlp3u37m9np4zf465rapd2h8gxhxv5wmp8q852hxhnnfac8s9769tn", + 100000000, + true, + 10 + ], + "aleo18xwgkgzwvzpw6yz8cdhrvrv6ztpd26zll46kd4kfcd79c9x90grsah3jug": [ + "aleo1mj07es0ar580s9sdqk036jzpxxaewpuwylw53hyvjtlj4vaknvxsmm0ux2", + 100000000, + true, + 10 + ], + "aleo1d37xxnms3sq5qxcnnh3dtvzr35xemjzas4jcytjr8uvymfetnu9salav5n": [ + "aleo1g5wrxvgyvckgtuceg36eg6pf024x3p6nex05lcefz0h6576rmgrs22dr4w", + 100000000, + true, + 10 + ], + "aleo1q3vx8pet0h7739hx5xlekfxh9kus6qdlxhx9qdkxhh9rnva8q5gsskve3t": [ + "aleo1xx0fqugtrm0kv872dj5ujhyx3kjfrdtz5vj23hmq4p9cqwtvfs8se6ct93", + 100000000, + true, + 10 + ], + "aleo19t9f8nla683mzeaz5q2gv5u90zkx9v6azwvya7fswgfkfddaucxqxr0scu": [ + "aleo1t0tjdmwfz89s6d50xrzapp8f6aks5pqm0lf46xvz2y200s9rasps9g0scu", + 100000000, + true, + 10 + ], + "aleo12tf856xd9we5ay090zkep0s3q5e8srzwqr37ds0ppvv5kkzad5fqvwndmx": [ + "aleo1mjql67fre85nu92mjyf6024ua2zwg60l7udwtn27qdnlsx2qxvzq08vdmx", + 100000000, + true, + 10 + ], + "aleo1n6c5ugxk6tp09vkrjegcpcprssdfcf7283agcdtt8gu9qex2c5xs9c28ay": [ + "aleo1celn0jtuurc5s2k2v697e3nuuf3nrlhaymrmwljqqkhnlnt3kvpqdz62dd", + 100000000, + true, + 0 + ], + "aleo1anfvarnm27e2s5j6mzx3kzakx5eryc69re96x6grzkm9nkapkgpq4vyy5t": [ + "aleo1xzspdh569aajes9gm6w9pt535zdtj9tc3npf3245gasl76t03ypqu63k38", + 100000000, + true, + 100 + ] +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/inclusion.metadata b/parameters/src/mainnet/resources/inclusion.metadata new file mode 100644 index 0000000000..76f795f99c --- /dev/null +++ b/parameters/src/mainnet/resources/inclusion.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "8faa4d3aaaa5e786d20b61f825e50901f9dcf470455d1d2994e091eefcc66a4e", + "prover_size": 233812212, + "verifier_checksum": "2b6fdf5a869db365620a44fc3991e3f807a4e670bb976277ad327f3179866553", + "verifier_size": 665 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/inclusion.verifier b/parameters/src/mainnet/resources/inclusion.verifier new file mode 100644 index 0000000000..f317f07efa Binary files /dev/null and b/parameters/src/mainnet/resources/inclusion.verifier differ diff --git a/parameters/src/mainnet/resources/join.metadata b/parameters/src/mainnet/resources/join.metadata new file mode 100644 index 0000000000..f7e256ba13 --- /dev/null +++ b/parameters/src/mainnet/resources/join.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "b609cd8cd51eb0870e87b31db05b45768a77daed7a2b0b3c8f5a570e12044112", + "prover_size": 74722164, + "verifier_checksum": "3a441d336ddd9cdc80dce07d161eb435d0cd21afd2463b0de9fc6fdf867f4f6a", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/join.verifier b/parameters/src/mainnet/resources/join.verifier new file mode 100644 index 0000000000..a7afbb3672 Binary files /dev/null and b/parameters/src/mainnet/resources/join.verifier differ diff --git a/parameters/src/testnet3/resources/mint.metadata b/parameters/src/mainnet/resources/mint.metadata similarity index 100% rename from parameters/src/testnet3/resources/mint.metadata rename to parameters/src/mainnet/resources/mint.metadata diff --git a/parameters/src/testnet3/resources/neg-powers-of-beta.metadata b/parameters/src/mainnet/resources/neg-powers-of-beta.metadata similarity index 100% rename from parameters/src/testnet3/resources/neg-powers-of-beta.metadata rename to parameters/src/mainnet/resources/neg-powers-of-beta.metadata diff --git a/parameters/src/testnet3/resources/neg-powers-of-beta.usrs b/parameters/src/mainnet/resources/neg-powers-of-beta.usrs similarity index 100% rename from parameters/src/testnet3/resources/neg-powers-of-beta.usrs rename to parameters/src/mainnet/resources/neg-powers-of-beta.usrs diff --git a/parameters/src/testnet3/resources/powers-of-beta-15.metadata b/parameters/src/mainnet/resources/powers-of-beta-15.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-15.metadata rename to parameters/src/mainnet/resources/powers-of-beta-15.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-15.usrs b/parameters/src/mainnet/resources/powers-of-beta-15.usrs similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-15.usrs rename to parameters/src/mainnet/resources/powers-of-beta-15.usrs diff --git a/parameters/src/testnet3/resources/powers-of-beta-16.metadata b/parameters/src/mainnet/resources/powers-of-beta-16.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-16.metadata rename to parameters/src/mainnet/resources/powers-of-beta-16.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-17.metadata b/parameters/src/mainnet/resources/powers-of-beta-17.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-17.metadata rename to parameters/src/mainnet/resources/powers-of-beta-17.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-18.metadata b/parameters/src/mainnet/resources/powers-of-beta-18.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-18.metadata rename to parameters/src/mainnet/resources/powers-of-beta-18.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-19.metadata b/parameters/src/mainnet/resources/powers-of-beta-19.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-19.metadata rename to parameters/src/mainnet/resources/powers-of-beta-19.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-20.metadata b/parameters/src/mainnet/resources/powers-of-beta-20.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-20.metadata rename to parameters/src/mainnet/resources/powers-of-beta-20.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-21.metadata b/parameters/src/mainnet/resources/powers-of-beta-21.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-21.metadata rename to parameters/src/mainnet/resources/powers-of-beta-21.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-22.metadata b/parameters/src/mainnet/resources/powers-of-beta-22.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-22.metadata rename to parameters/src/mainnet/resources/powers-of-beta-22.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-23.metadata b/parameters/src/mainnet/resources/powers-of-beta-23.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-23.metadata rename to parameters/src/mainnet/resources/powers-of-beta-23.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-24.metadata b/parameters/src/mainnet/resources/powers-of-beta-24.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-24.metadata rename to parameters/src/mainnet/resources/powers-of-beta-24.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-25.metadata b/parameters/src/mainnet/resources/powers-of-beta-25.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-25.metadata rename to parameters/src/mainnet/resources/powers-of-beta-25.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-26.metadata b/parameters/src/mainnet/resources/powers-of-beta-26.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-26.metadata rename to parameters/src/mainnet/resources/powers-of-beta-26.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-27.metadata b/parameters/src/mainnet/resources/powers-of-beta-27.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-27.metadata rename to parameters/src/mainnet/resources/powers-of-beta-27.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-28.metadata b/parameters/src/mainnet/resources/powers-of-beta-28.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-28.metadata rename to parameters/src/mainnet/resources/powers-of-beta-28.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-gamma.metadata b/parameters/src/mainnet/resources/powers-of-beta-gamma.metadata similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-gamma.metadata rename to parameters/src/mainnet/resources/powers-of-beta-gamma.metadata diff --git a/parameters/src/testnet3/resources/powers-of-beta-gamma.usrs b/parameters/src/mainnet/resources/powers-of-beta-gamma.usrs similarity index 100% rename from parameters/src/testnet3/resources/powers-of-beta-gamma.usrs rename to parameters/src/mainnet/resources/powers-of-beta-gamma.usrs diff --git a/parameters/src/mainnet/resources/restrictions.json b/parameters/src/mainnet/resources/restrictions.json new file mode 100644 index 0000000000..0a49b4071f --- /dev/null +++ b/parameters/src/mainnet/resources/restrictions.json @@ -0,0 +1,6 @@ +{ + "restrictions_id": "7562506206353711030068167991213732850758501012603348777370400520506564970105field", + "programs": {}, + "functions": {}, + "arguments": {} +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/set_validator_state.metadata b/parameters/src/mainnet/resources/set_validator_state.metadata new file mode 100644 index 0000000000..f21df09817 --- /dev/null +++ b/parameters/src/mainnet/resources/set_validator_state.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "f782f04cf9f46464f307b4ae6418f2b8bec375e341e5a02a51c9d6b8b38e4f7f", + "prover_size": 17390188, + "verifier_checksum": "294517ffa497c173e0097090c09e33f2c0888c97126c3b74a17731ce3d2f6dd9", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/set_validator_state.verifier b/parameters/src/mainnet/resources/set_validator_state.verifier new file mode 100644 index 0000000000..c1cde948e9 Binary files /dev/null and b/parameters/src/mainnet/resources/set_validator_state.verifier differ diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-15.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-15.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-15.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-15.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-15.usrs b/parameters/src/mainnet/resources/shifted-powers-of-beta-15.usrs similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-15.usrs rename to parameters/src/mainnet/resources/shifted-powers-of-beta-15.usrs diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-16.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-16.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-16.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-16.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-16.usrs b/parameters/src/mainnet/resources/shifted-powers-of-beta-16.usrs similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-16.usrs rename to parameters/src/mainnet/resources/shifted-powers-of-beta-16.usrs diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-17.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-17.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-17.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-17.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-18.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-18.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-18.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-18.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-19.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-19.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-19.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-19.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-20.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-20.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-20.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-20.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-21.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-21.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-21.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-21.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-22.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-22.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-22.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-22.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-23.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-23.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-23.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-23.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-24.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-24.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-24.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-24.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-25.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-25.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-25.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-25.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-26.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-26.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-26.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-26.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-27.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-27.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-27.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-27.metadata diff --git a/parameters/src/testnet3/resources/shifted-powers-of-beta-28.metadata b/parameters/src/mainnet/resources/shifted-powers-of-beta-28.metadata similarity index 100% rename from parameters/src/testnet3/resources/shifted-powers-of-beta-28.metadata rename to parameters/src/mainnet/resources/shifted-powers-of-beta-28.metadata diff --git a/parameters/src/mainnet/resources/split.metadata b/parameters/src/mainnet/resources/split.metadata new file mode 100644 index 0000000000..dc16dfa777 --- /dev/null +++ b/parameters/src/mainnet/resources/split.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "9a6198f6bf0f9b0516feab70779eaaf91082b8b081ca79d7ddadbca44b58e85a", + "prover_size": 75161428, + "verifier_checksum": "1d6bfd787cc09dd6fac674f566dd5fb22acf4c47efca7763bd18bb75d3afce34", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/split.verifier b/parameters/src/mainnet/resources/split.verifier new file mode 100644 index 0000000000..37335cd176 Binary files /dev/null and b/parameters/src/mainnet/resources/split.verifier differ diff --git a/parameters/src/mainnet/resources/transfer_private.metadata b/parameters/src/mainnet/resources/transfer_private.metadata new file mode 100644 index 0000000000..cdf533c246 --- /dev/null +++ b/parameters/src/mainnet/resources/transfer_private.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "d6c6d61a87f38905468c7e479e30a9899535635450cadf3de69eae4b490621db", + "prover_size": 75949172, + "verifier_checksum": "d17b5954edcea8c9f97ebbe267f569a5faca6168e51832fa62e77a0017c25700", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/transfer_private.verifier b/parameters/src/mainnet/resources/transfer_private.verifier new file mode 100644 index 0000000000..5fb4efc72e Binary files /dev/null and b/parameters/src/mainnet/resources/transfer_private.verifier differ diff --git a/parameters/src/mainnet/resources/transfer_private_to_public.metadata b/parameters/src/mainnet/resources/transfer_private_to_public.metadata new file mode 100644 index 0000000000..56d62693ee --- /dev/null +++ b/parameters/src/mainnet/resources/transfer_private_to_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "4c0561cf4342c601ccd49eee4c039711c2e2cf92a01b0b3a58b7f1242e902ceb", + "prover_size": 66299476, + "verifier_checksum": "ffdad62683ba31580632cdadb2bc5e5d7bb4c293774579c9571eb6c0e349a50f", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/transfer_private_to_public.verifier b/parameters/src/mainnet/resources/transfer_private_to_public.verifier new file mode 100644 index 0000000000..de62d2a1d8 Binary files /dev/null and b/parameters/src/mainnet/resources/transfer_private_to_public.verifier differ diff --git a/parameters/src/mainnet/resources/transfer_public.metadata b/parameters/src/mainnet/resources/transfer_public.metadata new file mode 100644 index 0000000000..e43c4a3925 --- /dev/null +++ b/parameters/src/mainnet/resources/transfer_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "f8e5f6437b945174b62313ece8a1c9dcbeac5dfff5b0fef2e968c9b92f86da06", + "prover_size": 28913482, + "verifier_checksum": "ea77f42a35b3f891e7753c7333df365f356883550c4602df11f270237bef340d", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/transfer_public.verifier b/parameters/src/mainnet/resources/transfer_public.verifier new file mode 100644 index 0000000000..0b59130e9a Binary files /dev/null and b/parameters/src/mainnet/resources/transfer_public.verifier differ diff --git a/parameters/src/mainnet/resources/transfer_public_as_signer.metadata b/parameters/src/mainnet/resources/transfer_public_as_signer.metadata new file mode 100644 index 0000000000..bb2a05d311 --- /dev/null +++ b/parameters/src/mainnet/resources/transfer_public_as_signer.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "7cfc669dd92593e052a8a37d6b3a7c40d09f191c754b41230f69e19e9d0f9c76", + "prover_size": 28915282, + "verifier_checksum": "7d869b875c2beaecba4f7c78e2fdc3a2adc01d5eca53ac72d81d2f8f90b7b606", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/transfer_public_as_signer.verifier b/parameters/src/mainnet/resources/transfer_public_as_signer.verifier new file mode 100644 index 0000000000..4c2f0444e9 Binary files /dev/null and b/parameters/src/mainnet/resources/transfer_public_as_signer.verifier differ diff --git a/parameters/src/mainnet/resources/transfer_public_to_private.metadata b/parameters/src/mainnet/resources/transfer_public_to_private.metadata new file mode 100644 index 0000000000..5cedf109a0 --- /dev/null +++ b/parameters/src/mainnet/resources/transfer_public_to_private.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "cf0916dc5debc8b894a856540e1525254214367af3d58b53d1472d5d95af5a95", + "prover_size": 38413316, + "verifier_checksum": "fd11e1bb7e49c405e30a78ac1659ab338a3345c7982079f05a6a189bf86c0d48", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/transfer_public_to_private.verifier b/parameters/src/mainnet/resources/transfer_public_to_private.verifier new file mode 100644 index 0000000000..e6d12bbae9 Binary files /dev/null and b/parameters/src/mainnet/resources/transfer_public_to_private.verifier differ diff --git a/parameters/src/mainnet/resources/unbond_delegator_as_validator.metadata b/parameters/src/mainnet/resources/unbond_delegator_as_validator.metadata new file mode 100644 index 0000000000..d1e5ca6e66 --- /dev/null +++ b/parameters/src/mainnet/resources/unbond_delegator_as_validator.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "785f2318f0c12b883b99ff1649cf401d2f1d024fe2dd30916a276cd8c199f757", + "prover_size": 27062250, + "verifier_checksum": "34f8fb353c7c1a4e590b52000d78bf28100328f6250eb6c9ef11c9dc0a2bb066", + "verifier_size": 665 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/unbond_delegator_as_validator.verifier b/parameters/src/mainnet/resources/unbond_delegator_as_validator.verifier new file mode 100644 index 0000000000..2f245c62d3 Binary files /dev/null and b/parameters/src/mainnet/resources/unbond_delegator_as_validator.verifier differ diff --git a/parameters/src/mainnet/resources/unbond_public.metadata b/parameters/src/mainnet/resources/unbond_public.metadata new file mode 100644 index 0000000000..1d800cd947 --- /dev/null +++ b/parameters/src/mainnet/resources/unbond_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "a924e83180f0cd79e4d24d16651751ea317b333300bf364bfd24e9590b5e7b7f", + "prover_size": 28913482, + "verifier_checksum": "24ed9bef877039772d36ac96ff65a43b550bbdbc0dadc1f58ccf746bc504dc59", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/mainnet/resources/unbond_public.verifier b/parameters/src/mainnet/resources/unbond_public.verifier new file mode 100644 index 0000000000..3e1555aabf Binary files /dev/null and b/parameters/src/mainnet/resources/unbond_public.verifier differ diff --git a/parameters/src/testnet/genesis.rs b/parameters/src/testnet/genesis.rs new file mode 100644 index 0000000000..68ba304a83 --- /dev/null +++ b/parameters/src/testnet/genesis.rs @@ -0,0 +1,33 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +pub struct GenesisBytes; + +impl GenesisBytes { + pub const fn load_bytes() -> &'static [u8] { + include_bytes!("./resources/block.genesis") + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_genesis_block() { + let bytes = GenesisBytes::load_bytes(); + assert_eq!(20929, bytes.len() as u64, "Update me if serialization has changed"); + } +} diff --git a/parameters/src/testnet/mod.rs b/parameters/src/testnet/mod.rs new file mode 100644 index 0000000000..84f3c76531 --- /dev/null +++ b/parameters/src/testnet/mod.rs @@ -0,0 +1,141 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +pub mod genesis; +pub use genesis::*; + +/// The restrictions list as a JSON-compatible string. +pub const RESTRICTIONS_LIST: &str = include_str!("./resources/restrictions.json"); + +const REMOTE_URL: &str = "https://parameters.aleo.org/testnet"; + +// BondPublic +impl_remote!(BondPublicProver, REMOTE_URL, "resources/", "bond_public", "prover"); +impl_local!(BondPublicVerifier, "resources/", "bond_public", "verifier"); +// BondValidator +impl_remote!(BondValidatorProver, REMOTE_URL, "resources/", "bond_validator", "prover"); +impl_local!(BondValidatorVerifier, "resources/", "bond_validator", "verifier"); +// UnbondPublic +impl_remote!(UnbondPublicProver, REMOTE_URL, "resources/", "unbond_public", "prover"); +impl_local!(UnbondPublicVerifier, "resources/", "unbond_public", "verifier"); +// ClaimUnbondPublic +impl_remote!(ClaimUnbondPublicProver, REMOTE_URL, "resources/", "claim_unbond_public", "prover"); +impl_local!(ClaimUnbondPublicVerifier, "resources/", "claim_unbond_public", "verifier"); +// SetValidatorState +impl_remote!(SetValidatorStateProver, REMOTE_URL, "resources/", "set_validator_state", "prover"); +impl_local!(SetValidatorStateVerifier, "resources/", "set_validator_state", "verifier"); +// TransferPrivate +impl_remote!(TransferPrivateProver, REMOTE_URL, "resources/", "transfer_private", "prover"); +impl_local!(TransferPrivateVerifier, "resources/", "transfer_private", "verifier"); +// TransferPublic +impl_remote!(TransferPublicProver, REMOTE_URL, "resources/", "transfer_public", "prover"); +impl_local!(TransferPublicVerifier, "resources/", "transfer_public", "verifier"); +// TransferPublicAsSigner +impl_remote!(TransferPublicAsSignerProver, REMOTE_URL, "resources/", "transfer_public_as_signer", "prover"); +impl_local!(TransferPublicAsSignerVerifier, "resources/", "transfer_public_as_signer", "verifier"); +// TransferPrivateToPublic +impl_remote!(TransferPrivateToPublicProver, REMOTE_URL, "resources/", "transfer_private_to_public", "prover"); +impl_local!(TransferPrivateToPublicVerifier, "resources/", "transfer_private_to_public", "verifier"); +// TransferPublicToPrivate +impl_remote!(TransferPublicToPrivateProver, REMOTE_URL, "resources/", "transfer_public_to_private", "prover"); +impl_local!(TransferPublicToPrivateVerifier, "resources/", "transfer_public_to_private", "verifier"); +// Join +impl_remote!(JoinProver, REMOTE_URL, "resources/", "join", "prover"); +impl_local!(JoinVerifier, "resources/", "join", "verifier"); +// Split +impl_remote!(SplitProver, REMOTE_URL, "resources/", "split", "prover"); +impl_local!(SplitVerifier, "resources/", "split", "verifier"); +// FeePrivate +impl_remote!(FeePrivateProver, REMOTE_URL, "resources/", "fee_private", "prover"); +impl_local!(FeePrivateVerifier, "resources/", "fee_private", "verifier"); +// FeePublic +impl_remote!(FeePublicProver, REMOTE_URL, "resources/", "fee_public", "prover"); +impl_local!(FeePublicVerifier, "resources/", "fee_public", "verifier"); + +#[macro_export] +macro_rules! insert_testnet_credit_keys { + ($map:ident, $type:ident<$network:ident>, $variant:ident) => {{ + paste::paste! { + let string = stringify!([<$variant:lower>]); + $crate::insert_testnet_key!($map, string, $type<$network>, ("bond_public", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("bond_validator", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("unbond_public", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("claim_unbond_public", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("set_validator_state", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("transfer_private", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("transfer_public", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("transfer_public_as_signer", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("transfer_private_to_public", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("transfer_public_to_private", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("join", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("split", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("fee_private", $crate::testnet::[]::load_bytes())); + $crate::insert_testnet_key!($map, string, $type<$network>, ("fee_public", $crate::testnet::[]::load_bytes())); + } + }}; +} + +#[macro_export] +macro_rules! insert_testnet_key { + ($map:ident, $string:tt, $type:ident<$network:ident>, ($name:tt, $circuit_key:expr)) => {{ + // Load the circuit key bytes. + let key_bytes: Vec = $circuit_key.expect(&format!("Failed to load {} bytes", $string)); + // Recover the circuit key. + let key = $type::<$network>::from_bytes_le(&key_bytes[1..]).expect(&format!("Failed to recover {}", $string)); + // Insert the circuit key. + $map.insert($name.to_string(), std::sync::Arc::new(key)); + }}; +} + +// Inclusion +impl_remote!(InclusionProver, REMOTE_URL, "resources/", "inclusion", "prover"); +impl_local!(InclusionVerifier, "resources/", "inclusion", "verifier"); + +/// The function name for the inclusion circuit. +pub const NETWORK_INCLUSION_FUNCTION_NAME: &str = "inclusion"; + +lazy_static! { + pub static ref INCLUSION_PROVING_KEY: Vec = + InclusionProver::load_bytes().expect("Failed to load inclusion proving key"); + pub static ref INCLUSION_VERIFYING_KEY: Vec = + InclusionVerifier::load_bytes().expect("Failed to load inclusion verifying key"); +} + +#[cfg(test)] +mod tests { + use super::*; + use wasm_bindgen_test::*; + wasm_bindgen_test_configure!(run_in_browser); + + #[wasm_bindgen_test] + fn test_load_bytes() { + BondPublicVerifier::load_bytes().expect("Failed to load bond_public verifier"); + BondValidatorVerifier::load_bytes().expect("Failed to load bond_validator verifier"); + UnbondPublicVerifier::load_bytes().expect("Failed to load unbond_public verifier"); + ClaimUnbondPublicVerifier::load_bytes().expect("Failed to load claim_unbond_public verifier"); + SetValidatorStateVerifier::load_bytes().expect("Failed to load set_validator_state verifier"); + TransferPrivateVerifier::load_bytes().expect("Failed to load transfer_private verifier"); + TransferPublicVerifier::load_bytes().expect("Failed to load transfer_public verifier"); + TransferPublicAsSignerVerifier::load_bytes().expect("Failed to load transfer_public_as_signer verifier"); + TransferPrivateToPublicVerifier::load_bytes().expect("Failed to load transfer_private_to_public verifier"); + TransferPublicToPrivateVerifier::load_bytes().expect("Failed to load transfer_public_to_private verifier"); + FeePrivateProver::load_bytes().expect("Failed to load fee_private prover"); + FeePrivateVerifier::load_bytes().expect("Failed to load fee_private verifier"); + FeePublicProver::load_bytes().expect("Failed to load fee_public prover"); + FeePublicVerifier::load_bytes().expect("Failed to load fee_public verifier"); + InclusionProver::load_bytes().expect("Failed to load inclusion prover"); + InclusionVerifier::load_bytes().expect("Failed to load inclusion verifier"); + } +} diff --git a/parameters/src/testnet/resources/block.genesis b/parameters/src/testnet/resources/block.genesis new file mode 100644 index 0000000000..8566c73f14 Binary files /dev/null and b/parameters/src/testnet/resources/block.genesis differ diff --git a/parameters/src/testnet/resources/bond_public.metadata b/parameters/src/testnet/resources/bond_public.metadata new file mode 100644 index 0000000000..2150056b56 --- /dev/null +++ b/parameters/src/testnet/resources/bond_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "f92451e15be6eb13796ef8ed3cfa68b513dd9ec721244c6f990a9daa9c0413fc", + "prover_size": 29352706, + "verifier_checksum": "48f9e455539cbc6518a21d56009111a8db929bcdc0ef2eff438ece8440895415", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/bond_public.verifier b/parameters/src/testnet/resources/bond_public.verifier new file mode 100644 index 0000000000..38af4c5b8e Binary files /dev/null and b/parameters/src/testnet/resources/bond_public.verifier differ diff --git a/parameters/src/testnet/resources/bond_validator.metadata b/parameters/src/testnet/resources/bond_validator.metadata new file mode 100644 index 0000000000..f180e092c9 --- /dev/null +++ b/parameters/src/testnet/resources/bond_validator.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "dab3eba4764e7833db38db742b12177ef70ad1627f21ca283ca829af60076966", + "prover_size": 29188482, + "verifier_checksum": "620fa7cfccb4e95d928d711396dc5dda37a4ac7352547951618044f2a20fc8b6", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/bond_validator.verifier b/parameters/src/testnet/resources/bond_validator.verifier new file mode 100644 index 0000000000..0b6fcd3b26 Binary files /dev/null and b/parameters/src/testnet/resources/bond_validator.verifier differ diff --git a/parameters/src/testnet/resources/claim_unbond_public.metadata b/parameters/src/testnet/resources/claim_unbond_public.metadata new file mode 100644 index 0000000000..b5cc2eb2cf --- /dev/null +++ b/parameters/src/testnet/resources/claim_unbond_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "73b8d8227b5d4b81028c5500ce40d0be33bc892782bb9df63e9c335aa3e74de5", + "prover_size": 26927162, + "verifier_checksum": "ba3259437c81f964cc2d7a9fb4fa403ba814342ce05e1762e91bad9efb3b3098", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/claim_unbond_public.verifier b/parameters/src/testnet/resources/claim_unbond_public.verifier new file mode 100644 index 0000000000..15eaee1d3e Binary files /dev/null and b/parameters/src/testnet/resources/claim_unbond_public.verifier differ diff --git a/parameters/src/testnet/resources/fee_private.metadata b/parameters/src/testnet/resources/fee_private.metadata new file mode 100644 index 0000000000..59428d3b8e --- /dev/null +++ b/parameters/src/testnet/resources/fee_private.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "e00171b5ce1b7f6629dda2ad571c2b8acf28042997801114fcfd3659e7bd130b", + "prover_size": 66297972, + "verifier_checksum": "f210de1bf1dbfd9cd291b2a2569157124700a92800c9cbe428bfc9cf26c57a54", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/fee_private.verifier b/parameters/src/testnet/resources/fee_private.verifier new file mode 100644 index 0000000000..290209615c Binary files /dev/null and b/parameters/src/testnet/resources/fee_private.verifier differ diff --git a/parameters/src/testnet/resources/fee_public.metadata b/parameters/src/testnet/resources/fee_public.metadata new file mode 100644 index 0000000000..c907fd9416 --- /dev/null +++ b/parameters/src/testnet/resources/fee_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "f72b6ff291415fb17a3653f447dbf95a5fe48480f7bbd6cf1dfb33963ff6ad58", + "prover_size": 29174402, + "verifier_checksum": "6fb9bb7a84f117d93af2e6bf63450252bd2b73ab5b8eee3b9fa509bada23aa79", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/fee_public.verifier b/parameters/src/testnet/resources/fee_public.verifier new file mode 100644 index 0000000000..c0c6ced42c Binary files /dev/null and b/parameters/src/testnet/resources/fee_public.verifier differ diff --git a/parameters/src/testnet/resources/genesis_delegations.json b/parameters/src/testnet/resources/genesis_delegations.json new file mode 100644 index 0000000000..4bf2807f90 --- /dev/null +++ b/parameters/src/testnet/resources/genesis_delegations.json @@ -0,0 +1,23 @@ +{ + "aleo1anfdyecj5fss40m7jh7t7g5rsncyqcd9ys74dssc62p0fldq8v9qlyaelk": ["aleo1vcyhz3cwu45js0sndl8hf7zzfg0slg20x8wjsv2r9q3havgzgupqxm0nad", "aleo1anfwa8pvsztk6plad3a3pp3vy6aevf7vm0pvfhwxrat6wl2q4qps22ff8r", 30000000000000], + "aleo1anfdn92msrk78sm8ckuylx036vteg9m349wvdlr7jp0qpc9p8qzqpgcvgf": ["aleo1ekqgrpvru7demjrp92sxkdr2cqetr8qrkkcmmvkr8kqem9r5t59qwa780g", "aleo1anfwnv3ke0sm0h4yumnvmjyge7c5e440t5hp2jwy3spd87dtdqzqdp3nsx", 20000000000000], + "aleo1anfd3kl7t8jnvft75ka9lr2xgtvyljhgfjj4jxtm44hs6xl575rsgp7whd": ["aleo1fpee4gzwuehvxh3gknygf4n3g76tqwsgxu4mxn7rsgfe8rklmsxqlu68e2", "aleo1anfw9k8x9kxu5zxuf9u6z9prhh8e50lg79nty4g82cj58x38mvqq9feerh", 20000000000000], + "aleo1anfdtnukn9h9eev5nky63ddkkdf6uqnlxc0tl05lcpzenp78jgys2du699": ["aleo1u4hqhsukjqkm6q02kc5cjm470srwt77x9yt0fa2j263wtqzrevyqmdccy3", "aleo1anfw0agea55ym2kde9vmpwemz7jpunyvlg0u74x3ew0rqs3rnuqs89gpyd", 150000000000000], + "aleo1anfd65qdrnnszpkq3vdgrk0ckemlryfhq5s9cpyjyxfs9ra49c8quaqnld": ["aleo1zdzzxfrhgzlhh89vqpf4384ewqs0g32wqzvdeltzlynq25hkju8s38953f", "aleo1anfwukg3njd76zlx2x4jxg07fdgj4jnq9hq7vjwvpx9400jlsygss8kpyv", 20000000000000], + "aleo1anfdmczmdpazr4x4a5d7avqjuamn538vjkl2u8purhz7x0744crsn6leh6": ["aleo1uhd3qew7kgs8zmcm2w23xk7j4fjrf448zdjjslcngl9h3u3rs5zsltfmez", "aleo1anfw340j4x3vyypqprwxuzzcxjaka4x250nskf0p50km4dzhwg9sfpgqms", 20000000000000], + "aleo1anfdlp0r63vl8nl360t585meda0rh7zwq26nce5ztzlevcnyuugsjlutyd": ["aleo1dxf42pkgv5fcsnanhw2h4lvzcaxxcfwajtsghvqljugnpwfc5vxq0ulav5", "aleo1anfwlxd3lsdp9uuvt2z85q572ffjr8yln8x0r5ns2czp266pqgys8tr724", 20000000000000], + "aleo1anfd7qwlrhzvl9natecefcjdgmkrfcffu3r02jsd3y2ac62spyqsneyrap": ["aleo1l7avejc23yv6e8nx4udjwz89dw6mg95dzsp936hf77yuhnjywv9syl0ywc", "aleo1anfwwfur5mdngretzlfqw8tusj03dgzmxfutl00t3953s4993crqjmwj5l", 20000000000000], + "aleo1anfd04w4ea4daw4nc8mpzjerr3he86k3rh8w7eajtyw89k2lvg8s3g2ufm": ["aleo19dpf763gtj9h34wwk9a45ccfmd07r2kckqu7y9av3d5lly0asygss2scur", "aleo1anfw8l6yz3j4all3gu0afh46dyr6as78ue60uw655uwq4jl37qys5gmjpl", 30000000000000], + "aleo1anfdz0d8urvhdxdnjr0cdt5wuzuqvyplf0vu998l6xmkxgf705yqkxaxfn": ["aleo105eppvclpq20dv0282yft3m2njn9j4znrz087uj3r92gcpttagpsedem0x", "aleo1anfwpfzgk2gly3fn8zdw62nw3uj7adr6ly40z8rlhjc2fhfphy9q7evvpz", 20000000000000], + "aleo1anfdek5g46da7stdmyflgzn9vlpjszt9gj9ayr993fx666x37uqq55x3j4": ["aleo17mp7lz72e7zhvzyj8u2szrts2r98vz37sd6z9w500s99aaq4sq8s34vgv9", "aleo1anfw8t4mael397wmy0x3w2kukey85394vu5vhfhtvals0ga6yspq8sk2w9", 150000000000000], + "aleo1anfd83alxygns6rnrjn2d73zrmr26f8ml2rvmqvvtl065rlqts8q4sajqs": ["aleo17m3l8a4hmf3wypzkf5lsausfdwq9etzyujd0vmqh35ledn2sgvqqzqkqal", "aleo1anfwzpgythyrtxzhj7xs22mhsq6nz7440ws66hcfmz5xeaw8s58q20a5uc", 150000000000000], + "aleo1anfd6854hl76d4046p82246glxgyjy9klkgcjwpcmue65auntvxshuc5ck": ["aleo1czp8gure8caqnpqgxsacc2kv2zhggz4ujp065wwfa76qwxggrups6ap3jg", "aleo1anfw2fyyy3dl55n5kmus65spw5mle47xqjdeldtxx9ppsjs83vpsd4fpjh", 150000000000000], + "aleo1anfda0mfnvd4yrkjxym3epqg2q3cpl9nche59qwedc6ptpcjpy9qq8arzf": ["aleo1anfvuep47h0r9q349gu76d8twga8w98p0z2ggrktupcj450d5g8q7w3e2p", "aleo1anfwl4af93p67jva5k2r506yx2lw7jr0t9tltpgh8vullmry8c8q3sp7yu", 150000000000000], + "aleo17avqttd2jmxq3wrcmds2tc4ypcp2f85d29dqmqsmqlzr42c8vcrscpch26": ["aleo1l2a3lakq9pz9w9hyre7rk9zmk64wzr62z0q26wglr8tmf8w5cyqqxtt364", "aleo1pstqsdc3wazvcmj2dcxdarw63c84zkefqqv57669a37p8wt3nsrq2fcm0l", 25000000000000], + "aleo109kemfaxa7flf89jup6qrnkn6ml6t9zsp7ynegss45kywqh6fcrq0z0qst": ["aleo1l2a3lakq9pz9w9hyre7rk9zmk64wzr62z0q26wglr8tmf8w5cyqqxtt364", "aleo1gdhhvtpdqg8qsargayxfaj3s4tl482lster3e9rt384jxnszrsfqnhvpye", 25000000000000], + "aleo1y0vd8pxz5d2l67u8hflvs3vh2zvv7wcsxj2paxfdmr2tqftkhczq8rpq3q": ["aleo1l2a3lakq9pz9w9hyre7rk9zmk64wzr62z0q26wglr8tmf8w5cyqqxtt364", "aleo1gnrgczjq80wkrezsxux9qeve2r68q36kt8y20ndyldwg25tzfurqps2f06", 25000000000000], + "aleo1aem42tpjdgy4j5h9m2938mrewg67r2t7chzzlk0mkstwymtl3gzq6uf2lw": ["aleo1l2a3lakq9pz9w9hyre7rk9zmk64wzr62z0q26wglr8tmf8w5cyqqxtt364", "aleo12m6n25wl29fcrwnkc0sd75guguwtsrs48lknunpdkrcmpcdw4v8svkrfne", 25000000000000], + "aleo1qcxl6uzsex7es556gcpxsr3fzm9sh3j9r0xqzxqjkvl6wmaa459qze2x6w": ["aleo1l2a3lakq9pz9w9hyre7rk9zmk64wzr62z0q26wglr8tmf8w5cyqqxtt364", "aleo1u3nmst8zqh20xg7t8u8nd4zuc5z4uehnrj7yx05dun4salwru5gqrf75sq", 25000000000000], + "aleo1ep4pya77hjjlutqu80g6ezdcplztvykj5xzd5v730z3muc2qf5zqak3qkx": ["aleo17mp7lz72e7zhvzyj8u2szrts2r98vz37sd6z9w500s99aaq4sq8s34vgv9", "aleo1ep4pya77hjjlutqu80g6ezdcplztvykj5xzd5v730z3muc2qf5zqak3qkx", 10000000000], + "aleo130kkf4meuvznrn3g69tqhxyvrllneys0vmh3dtn4p9hp5ntn2vqqjfgp5p": ["aleo17m3l8a4hmf3wypzkf5lsausfdwq9etzyujd0vmqh35ledn2sgvqqzqkqal", "aleo130kkf4meuvznrn3g69tqhxyvrllneys0vmh3dtn4p9hp5ntn2vqqjfgp5p", 20000000000] +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/genesis_public_balances.json b/parameters/src/testnet/resources/genesis_public_balances.json new file mode 100644 index 0000000000..945bf1916a --- /dev/null +++ b/parameters/src/testnet/resources/genesis_public_balances.json @@ -0,0 +1,75 @@ +{ + "aleo1anfx9xxgsvjpg6gqjnm7m3eyycthz3y0k0h5659suhejws3td5rq28r6fd": 167000000000000, + "aleo1anfx7d2986jmrxs37ldqrz3nlus7u3grrluluhulrvj883d3ps8s9r7q9u": 135000000000000, + "aleo1anfxe06adre90ppk9seh2zr8jqe7f5atlsppqcnq6dga35t4dy8qd3u4hr": 74888497000000, + "aleo1anfwl4af93p67jva5k2r506yx2lw7jr0t9tltpgh8vullmry8c8q3sp7yu": 100000000, + "aleo1vxwv3alrx660hyxxefjvwm3psd9f20r9qz0xe7qfp0dtr86pus8qxm0nad": 100000000, + "aleo1gajgumpgqhh8wvntew2rp0dpux8eh6cv7930yp3w9evz2vg65qqqfl00z0": 100000000, + "aleo18knt96enlk6zhfr8kx2vr0hatnwwsej8q2u8tpmzxxdfvyu9cg9sju2a8l": 100000000, + "aleo1kuefcn9ae7k8qfp932ehkjjdlh0jc8dpsknh9vksr7xncunsj5yqmsdraw": 100000000, + "aleo1vkwsehmedq883434ggtrc35rpr6p3fuqcemsz8l9qn98pdfryursdxhk29": 100000000, + "aleo1h67qa2avqcla9el22ul6qkyl57xmq3tsmk937umx52klemj5zcfq92xm0x": 100000000, + "aleo19g99vj20nq6d6v33kvnaw5dfjakdhdmu2a7swyaxe5q654l8pyqqy397g6": 100000000, + "aleo147vv6vxe97l6v6ur0re0prpy4d2yhsn959fha0fwtec2vp300cfq98c08q": 100000000, + "aleo1ywykurcvjfqy5a9untn0gjayz3smp4x2ft62sn38u7f6x225aurqh3scur": 100000000, + "aleo1f6lgcvfah830dq24r9dmhdhyu9ajt8kkxcdxpnl6jwk3z0k83ygq5dem0x": 100000000, + "aleo1hz8gju8jvxycdw8m826s88aszwws4lpew5v2wd8x7k77zl3vxgrstal05v": 100000000, + "aleo1glzpk8x34kl0c3ucerj3dfzeu74g4mqfp3tp60uc9fwyl7y9wyzsqxswjs": 100000000, + "aleo1mrckw3x7ye4yhw6hspyyj87rd0dngwuhww7u6lqjrw29260t4qfqcjy5mf": 100000000, + "aleo1pstqsdc3wazvcmj2dcxdarw63c84zkefqqv57669a37p8wt3nsrq2fcm0l": 100000000, + "aleo1gdhhvtpdqg8qsargayxfaj3s4tl482lster3e9rt384jxnszrsfqnhvpye": 100000000, + "aleo1gnrgczjq80wkrezsxux9qeve2r68q36kt8y20ndyldwg25tzfurqps2f06": 100000000, + "aleo12m6n25wl29fcrwnkc0sd75guguwtsrs48lknunpdkrcmpcdw4v8svkrfne": 100000000, + "aleo1u3nmst8zqh20xg7t8u8nd4zuc5z4uehnrj7yx05dun4salwru5gqrf75sq": 100000000, + "aleo1anfwa8pvsztk6plad3a3pp3vy6aevf7vm0pvfhwxrat6wl2q4qps22ff8r": 100000000, + "aleo1anfwnv3ke0sm0h4yumnvmjyge7c5e440t5hp2jwy3spd87dtdqzqdp3nsx": 100000000, + "aleo1anfw9k8x9kxu5zxuf9u6z9prhh8e50lg79nty4g82cj58x38mvqq9feerh": 100000000, + "aleo1anfw0agea55ym2kde9vmpwemz7jpunyvlg0u74x3ew0rqs3rnuqs89gpyd": 100000000, + "aleo1anfwukg3njd76zlx2x4jxg07fdgj4jnq9hq7vjwvpx9400jlsygss8kpyv": 100000000, + "aleo1anfw340j4x3vyypqprwxuzzcxjaka4x250nskf0p50km4dzhwg9sfpgqms": 100000000, + "aleo1anfwlxd3lsdp9uuvt2z85q572ffjr8yln8x0r5ns2czp266pqgys8tr724": 100000000, + "aleo1anfwwfur5mdngretzlfqw8tusj03dgzmxfutl00t3953s4993crqjmwj5l": 100000000, + "aleo1anfw8l6yz3j4all3gu0afh46dyr6as78ue60uw655uwq4jl37qys5gmjpl": 100000000, + "aleo1anfwpfzgk2gly3fn8zdw62nw3uj7adr6ly40z8rlhjc2fhfphy9q7evvpz": 100000000, + "aleo1anfw8t4mael397wmy0x3w2kukey85394vu5vhfhtvals0ga6yspq8sk2w9": 100000000, + "aleo1anfwzpgythyrtxzhj7xs22mhsq6nz7440ws66hcfmz5xeaw8s58q20a5uc": 100000000, + "aleo1anfw2fyyy3dl55n5kmus65spw5mle47xqjdeldtxx9ppsjs83vpsd4fpjh": 100000000, + "aleo1susaqk8fup7z2w6uff8djfdrr0dp27r70jp8a3s8edfc966e2ggs066frm": 10000000, + "aleo183jdycqrs0aj88r467jejf7g28nuque2gc35yujnztsawryawspq70lajp": 2000000000, + "aleo1v9fgx2f4thvwpdkxy2fxmqsep8hdrh2t34eahx095g8wwp5h25psrz365c": 1000000000, + "aleo1n2tkexkg5av4vhc72kldmf7j8jnku9tnu38ee7gx6avj8yuhpqzqczylvk": 50000000000, + "aleo1ep4pya77hjjlutqu80g6ezdcplztvykj5xzd5v730z3muc2qf5zqak3qkx": 100000000, + "aleo130kkf4meuvznrn3g69tqhxyvrllneys0vmh3dtn4p9hp5ntn2vqqjfgp5p": 100000000, + "aleo13kkl4as4ukc56p7yv2hnxhh8ske3flnkly6lu33hn8j3pvnlrgyqynks2p": 12351639000000, + "aleo1scle92gyxa8llt85g7nqrjtjvfpshxg5gfk2wnrfe0xdjsmpuygq0puzx7": 7916667000000, + "aleo1szf38fgd9y5060ehlh4qcfz92ep9qqnfvjlffx8wz9pv6qaj7vxs8jtdct": 12091794000000, + "aleo1eddeq40v8zh6gamjxq3tdt57dce2kc4yh8jykfdvz9tuqxkaa59s8dvx8m": 3877500000000, + "aleo164nw8gxszevyp804l3vh4lg2y7ktcn4ky0nzxsj7fn53sauwhyyqv6sxfw": 1812500000000, + "aleo1497953lt4r3ukh7zwg2xvl8xrfw9d9ae67vyu48js37aaqx59qxs8yket6": 778750000000, + "aleo14zpcgdf8t3zfqlxteqmmsw5e45vk6j3arlh6lwmjha329k7q7s9q6697r0": 610544000000, + "aleo1xj9rymlaedxdm0hyllaacnlcllj33j330k20vvxur3t4l0ud5ypsr8lcwm": 661700000000, + "aleo1njxwejjs89plp9g09euyv7dj93hndzjklkdrvsha88qnvuxkx5ys4s7rnm": 600000000000, + "aleo15nytfjn839zyya5efdhlutvla5j3mns4s2n44wahs63ql62j058sptuy4s": 315272000000, + "aleo16xhz496vugkptnjr92a9kgu8ffrlxxgda8smn4secnqlq3l9dvzsye4lc7": 266803000000, + "aleo1sukeek2srpa9garykfjtx5my68eenhwu55tfdhh0zqe9qlk05y9qexmgas": 807830000000, + "aleo15dlgj63t88r2c5eh5uch8m7ccl083rxxupa5jskuh6mxh63pfsrspudg29": 436386000000, + "aleo1j2k8ygmuql6fc0z4x9zzpsv6j4esa3tq6adgffrkzsf34garp5xsgs6g6j": 193125000000, + "aleo1le90msflp97t8rj9jkd2e56wempp4frtp7xyzzv0ulcg676kzuysnusqg9": 150833000000, + "aleo1283fl0rcewv7gh745zv7fzdn9usjayql7eurkshvsf709wkevugqnpr6pu": 110000000000, + "aleo14dhggffhjxggznhy2kktclw3pdeu669h5pgx58a6yp4u33gpac8qjufuxu": 93125000000, + "aleo1anmccvfxn2gmtju2s7mu96tpwvg6laj4kdfudtyye6suqd8ecqqqn8mc9l": 93125000000, + "aleo1ju2s9hej92nx5ugu7dn0xrvwcnpd0h6u4k2rfkvvrh05u59ruyxq6qyfxf": 200000000000, + "aleo1fdshagcdgrw4gt3mn8c2mquuvkvtkv878xkypz6t9ly3p5cues8qwqcqzr": 360000000000, + "aleo17ct5zfa8y9lf0v0euvu9y40s3w6nja4mhqyqcx2gfvk9ykx9kugqjl72w4": 64583000000, + "aleo1ck3ptgls640fj8uvcw6xscp35l4luzramf9njps036f2xvu0aqxq8f5xpw": 135000000000, + "aleo1xf3gw4rw6yrc2mq3a6d4efjzqv0lum6tj58dj7qegrl0q7vzfyyq26m4sw": 30000000000, + "aleo1623wl27e3564spz4a3qusg57yyfzjstrv36ceklqu56r6lq7sqqsjnjwsn": 30000000000, + "aleo1h9rlvd3fgcn5mc8we6qqazdjfnhqmp2nfvcfgpkkg2k6m52fdvrqperxxz": 29750000000, + "aleo1sps4zsqt57ftmh8c8s204hhhp4f9c39ueeyjukc4rsshzpsklvys298y86": 85000000000, + "aleo1gylwdcdl2cpln3y03wrsmsxczg6esusm6hly3svyvsusurn7nc8qcdlqy2": 50000000000, + "aleo1hlc2477tvp3msak49jww9rhh96clw8z628987dqjrnpvheesfuxq0cmghl": 3000000000000, + "aleo1uasll0afwe5xrn4lkfrqfv40rk66k5vaevvmwkaq5j5awedpzg8qu85a6n": 200000000000, + "aleo1vnkmlgjctu2wemm4uv0vwp4h4keqk3jdjtu7f4tfyzt84l78tuzqlsy9q4": 5000000000, + "aleo1y3ukjtcklkfyamfgvmkrlj856jdvlxt5ymajy2mg07rcnm5r3yzqen9frx": 600000000000, + "aleo139nt5wqsnrg524s3scr09yz0u6gx7vf4fp8uvn2x0d5cl6k4durs2t29sf": 66667000000 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/genesis_validators.json b/parameters/src/testnet/resources/genesis_validators.json new file mode 100644 index 0000000000..df0787d920 --- /dev/null +++ b/parameters/src/testnet/resources/genesis_validators.json @@ -0,0 +1,17 @@ +{ + "aleo1vcyhz3cwu45js0sndl8hf7zzfg0slg20x8wjsv2r9q3havgzgupqxm0nad": ["aleo1vxwv3alrx660hyxxefjvwm3psd9f20r9qz0xe7qfp0dtr86pus8qxm0nad", 100000000, true, 10], + "aleo1ekqgrpvru7demjrp92sxkdr2cqetr8qrkkcmmvkr8kqem9r5t59qwa780g": ["aleo1gajgumpgqhh8wvntew2rp0dpux8eh6cv7930yp3w9evz2vg65qqqfl00z0", 100000000, true, 10], + "aleo1fpee4gzwuehvxh3gknygf4n3g76tqwsgxu4mxn7rsgfe8rklmsxqlu68e2": ["aleo18knt96enlk6zhfr8kx2vr0hatnwwsej8q2u8tpmzxxdfvyu9cg9sju2a8l", 100000000, true, 10], + "aleo1u4hqhsukjqkm6q02kc5cjm470srwt77x9yt0fa2j263wtqzrevyqmdccy3": ["aleo1kuefcn9ae7k8qfp932ehkjjdlh0jc8dpsknh9vksr7xncunsj5yqmsdraw", 100000000, true, 10], + "aleo1zdzzxfrhgzlhh89vqpf4384ewqs0g32wqzvdeltzlynq25hkju8s38953f": ["aleo1vkwsehmedq883434ggtrc35rpr6p3fuqcemsz8l9qn98pdfryursdxhk29", 100000000, true, 10], + "aleo1uhd3qew7kgs8zmcm2w23xk7j4fjrf448zdjjslcngl9h3u3rs5zsltfmez": ["aleo1h67qa2avqcla9el22ul6qkyl57xmq3tsmk937umx52klemj5zcfq92xm0x", 100000000, true, 10], + "aleo1dxf42pkgv5fcsnanhw2h4lvzcaxxcfwajtsghvqljugnpwfc5vxq0ulav5": ["aleo19g99vj20nq6d6v33kvnaw5dfjakdhdmu2a7swyaxe5q654l8pyqqy397g6", 100000000, true, 10], + "aleo1l7avejc23yv6e8nx4udjwz89dw6mg95dzsp936hf77yuhnjywv9syl0ywc": ["aleo147vv6vxe97l6v6ur0re0prpy4d2yhsn959fha0fwtec2vp300cfq98c08q", 100000000, true, 10], + "aleo19dpf763gtj9h34wwk9a45ccfmd07r2kckqu7y9av3d5lly0asygss2scur": ["aleo1ywykurcvjfqy5a9untn0gjayz3smp4x2ft62sn38u7f6x225aurqh3scur", 100000000, true, 10], + "aleo105eppvclpq20dv0282yft3m2njn9j4znrz087uj3r92gcpttagpsedem0x": ["aleo1f6lgcvfah830dq24r9dmhdhyu9ajt8kkxcdxpnl6jwk3z0k83ygq5dem0x", 100000000, true, 10], + "aleo17mp7lz72e7zhvzyj8u2szrts2r98vz37sd6z9w500s99aaq4sq8s34vgv9": ["aleo1hz8gju8jvxycdw8m826s88aszwws4lpew5v2wd8x7k77zl3vxgrstal05v", 100000000, true, 10], + "aleo17m3l8a4hmf3wypzkf5lsausfdwq9etzyujd0vmqh35ledn2sgvqqzqkqal": ["aleo1glzpk8x34kl0c3ucerj3dfzeu74g4mqfp3tp60uc9fwyl7y9wyzsqxswjs", 100000000, true, 10], + "aleo1czp8gure8caqnpqgxsacc2kv2zhggz4ujp065wwfa76qwxggrups6ap3jg": ["aleo1mrckw3x7ye4yhw6hspyyj87rd0dngwuhww7u6lqjrw29260t4qfqcjy5mf", 100000000, true, 10], + "aleo1l2a3lakq9pz9w9hyre7rk9zmk64wzr62z0q26wglr8tmf8w5cyqqxtt364": ["aleo1pzuc98fpz8xrvdjtx9umtcdu720v5zt2u79h49e39tqc3qhgayzqnn47js", 100000000, true, 0], + "aleo1anfvuep47h0r9q349gu76d8twga8w98p0z2ggrktupcj450d5g8q7w3e2p": ["aleo1anfwx4rryfndsd22kdt6fr7uvm9ldqh2jhfurlqn6rpa5v0n7yzs6pt5qz", 100000000, true, 100] +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/inclusion.metadata b/parameters/src/testnet/resources/inclusion.metadata new file mode 100644 index 0000000000..76f795f99c --- /dev/null +++ b/parameters/src/testnet/resources/inclusion.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "8faa4d3aaaa5e786d20b61f825e50901f9dcf470455d1d2994e091eefcc66a4e", + "prover_size": 233812212, + "verifier_checksum": "2b6fdf5a869db365620a44fc3991e3f807a4e670bb976277ad327f3179866553", + "verifier_size": 665 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/inclusion.verifier b/parameters/src/testnet/resources/inclusion.verifier new file mode 100644 index 0000000000..f317f07efa Binary files /dev/null and b/parameters/src/testnet/resources/inclusion.verifier differ diff --git a/parameters/src/testnet/resources/join.metadata b/parameters/src/testnet/resources/join.metadata new file mode 100644 index 0000000000..e342e900fc --- /dev/null +++ b/parameters/src/testnet/resources/join.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "267f60cc100c6c9fc024be16c5d48a383e0122b8b06ebd3612de298b8baafe1b", + "prover_size": 74722164, + "verifier_checksum": "be5c34ac7365ce7489fdfe202b5d62a96d11ccad4943927682145c54086fbac7", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/join.verifier b/parameters/src/testnet/resources/join.verifier new file mode 100644 index 0000000000..f9a5047baa Binary files /dev/null and b/parameters/src/testnet/resources/join.verifier differ diff --git a/parameters/src/testnet/resources/restrictions.json b/parameters/src/testnet/resources/restrictions.json new file mode 100644 index 0000000000..0a49b4071f --- /dev/null +++ b/parameters/src/testnet/resources/restrictions.json @@ -0,0 +1,6 @@ +{ + "restrictions_id": "7562506206353711030068167991213732850758501012603348777370400520506564970105field", + "programs": {}, + "functions": {}, + "arguments": {} +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/set_validator_state.metadata b/parameters/src/testnet/resources/set_validator_state.metadata new file mode 100644 index 0000000000..6767abb421 --- /dev/null +++ b/parameters/src/testnet/resources/set_validator_state.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "34421c854adfff6a5b3c5671f9d1a169835b63328d570d64f1302444af0ea75d", + "prover_size": 17390188, + "verifier_checksum": "65c8aa0d579e1c71992febd049ad71bbb8ba34f72d47296e7ad1cd208875ff66", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/set_validator_state.verifier b/parameters/src/testnet/resources/set_validator_state.verifier new file mode 100644 index 0000000000..2c38196753 Binary files /dev/null and b/parameters/src/testnet/resources/set_validator_state.verifier differ diff --git a/parameters/src/testnet/resources/split.metadata b/parameters/src/testnet/resources/split.metadata new file mode 100644 index 0000000000..f41c254397 --- /dev/null +++ b/parameters/src/testnet/resources/split.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "9af46afb8a0b340b8649d19b5039450699bed5617b661c9bd1176f4547cae258", + "prover_size": 75161428, + "verifier_checksum": "cec38390ab075e70977a48aac81fea95dac6f7be1a5115ff36aa966feb1562f4", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/split.verifier b/parameters/src/testnet/resources/split.verifier new file mode 100644 index 0000000000..5dd471f11e Binary files /dev/null and b/parameters/src/testnet/resources/split.verifier differ diff --git a/parameters/src/testnet/resources/transfer_private.metadata b/parameters/src/testnet/resources/transfer_private.metadata new file mode 100644 index 0000000000..5f6e330ad9 --- /dev/null +++ b/parameters/src/testnet/resources/transfer_private.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "6733de36be3291a1a6f95ed7b986ccb29fc69707788582fa672395abe3446e80", + "prover_size": 75949172, + "verifier_checksum": "86e2667e415b0e6266e0e9f3edb99746837debca70e9e82fd7d55f732ff7d995", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/transfer_private.verifier b/parameters/src/testnet/resources/transfer_private.verifier new file mode 100644 index 0000000000..087378ad3e Binary files /dev/null and b/parameters/src/testnet/resources/transfer_private.verifier differ diff --git a/parameters/src/testnet/resources/transfer_private_to_public.metadata b/parameters/src/testnet/resources/transfer_private_to_public.metadata new file mode 100644 index 0000000000..08c9973ad9 --- /dev/null +++ b/parameters/src/testnet/resources/transfer_private_to_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "d066d733d57185272acb449769163a9fe9409f5bacf02ba584751233d1e91810", + "prover_size": 66299476, + "verifier_checksum": "a656a128c7037878e2228e5e72f0a081152f9abe78d7fe1a6bb86b87f3462924", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/transfer_private_to_public.verifier b/parameters/src/testnet/resources/transfer_private_to_public.verifier new file mode 100644 index 0000000000..cc50ebc585 Binary files /dev/null and b/parameters/src/testnet/resources/transfer_private_to_public.verifier differ diff --git a/parameters/src/testnet/resources/transfer_public.metadata b/parameters/src/testnet/resources/transfer_public.metadata new file mode 100644 index 0000000000..0f56a39c3a --- /dev/null +++ b/parameters/src/testnet/resources/transfer_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "846f86cabf9fa50e5abe347e559a8e9f3018459b5af9fdf52f1c44892b05f7e5", + "prover_size": 28913482, + "verifier_checksum": "1b5109468e7992c39bbbc299dd1f94f18e49928e253e60ed68c7d9f02e73fe8d", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/transfer_public.verifier b/parameters/src/testnet/resources/transfer_public.verifier new file mode 100644 index 0000000000..ba3722e193 Binary files /dev/null and b/parameters/src/testnet/resources/transfer_public.verifier differ diff --git a/parameters/src/testnet/resources/transfer_public_as_signer.metadata b/parameters/src/testnet/resources/transfer_public_as_signer.metadata new file mode 100644 index 0000000000..391566edec --- /dev/null +++ b/parameters/src/testnet/resources/transfer_public_as_signer.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "12b5a7b02df59352833512c1dbebc9ce3849a81b0d3e9f1a1e447bb9e1e07277", + "prover_size": 28915282, + "verifier_checksum": "54d28a9f8d562ce2654d91463a2a879e21d5943b939044b1d92fc556b694b138", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/transfer_public_as_signer.verifier b/parameters/src/testnet/resources/transfer_public_as_signer.verifier new file mode 100644 index 0000000000..47c6a95c54 Binary files /dev/null and b/parameters/src/testnet/resources/transfer_public_as_signer.verifier differ diff --git a/parameters/src/testnet/resources/transfer_public_to_private.metadata b/parameters/src/testnet/resources/transfer_public_to_private.metadata new file mode 100644 index 0000000000..4e8b2d6f4a --- /dev/null +++ b/parameters/src/testnet/resources/transfer_public_to_private.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "8b120ab11dadbf8e051963fba135a099667ab857eaaeb602d8d268c1b2babb8d", + "prover_size": 38413316, + "verifier_checksum": "481aa28c8a948fd0651acee10178d02bb3a1840c0f22f223b5433b9df60431e2", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/transfer_public_to_private.verifier b/parameters/src/testnet/resources/transfer_public_to_private.verifier new file mode 100644 index 0000000000..b5f7ecefb3 Binary files /dev/null and b/parameters/src/testnet/resources/transfer_public_to_private.verifier differ diff --git a/parameters/src/testnet/resources/unbond_delegator_as_validator.metadata b/parameters/src/testnet/resources/unbond_delegator_as_validator.metadata new file mode 100644 index 0000000000..6457c08e5b --- /dev/null +++ b/parameters/src/testnet/resources/unbond_delegator_as_validator.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "cd98e97c4c79add134e9ba42d1f5114189da518d162c0d3ccb7383d2a8e38933", + "prover_size": 27062250, + "verifier_checksum": "bb883d677bc912d6cc83eaf08bac4cc6882fe3cb08e77259af8ea1985b2df3be", + "verifier_size": 665 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/unbond_delegator_as_validator.verifier b/parameters/src/testnet/resources/unbond_delegator_as_validator.verifier new file mode 100644 index 0000000000..149c622ccc Binary files /dev/null and b/parameters/src/testnet/resources/unbond_delegator_as_validator.verifier differ diff --git a/parameters/src/testnet/resources/unbond_public.metadata b/parameters/src/testnet/resources/unbond_public.metadata new file mode 100644 index 0000000000..15c7791c0a --- /dev/null +++ b/parameters/src/testnet/resources/unbond_public.metadata @@ -0,0 +1,6 @@ +{ + "prover_checksum": "ddfffce2be31b4377d5b4f9114450fd747a161d892308fc2706c7e3050751120", + "prover_size": 28913482, + "verifier_checksum": "36f6ffe622f91bf9f534840297b65d783f9dba1e9e072e67d06e5e27f4fc6a65", + "verifier_size": 673 +} \ No newline at end of file diff --git a/parameters/src/testnet/resources/unbond_public.verifier b/parameters/src/testnet/resources/unbond_public.verifier new file mode 100644 index 0000000000..e83af5e9b6 Binary files /dev/null and b/parameters/src/testnet/resources/unbond_public.verifier differ diff --git a/parameters/src/testnet3/resources/block.genesis b/parameters/src/testnet3/resources/block.genesis deleted file mode 100644 index c33b0398b6..0000000000 Binary files a/parameters/src/testnet3/resources/block.genesis and /dev/null differ diff --git a/parameters/src/testnet3/resources/bond_public.metadata b/parameters/src/testnet3/resources/bond_public.metadata deleted file mode 100644 index 09c21d773d..0000000000 --- a/parameters/src/testnet3/resources/bond_public.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "9c3547df0e580953f75e42f30e97c5f1eea7ca40d244aeb8054ff6b25a65bd53", - "prover_size": 28802978, - "verifier_checksum": "10315aeb75b3e933292d6493629634eda93bfc85e8d16caf86127015c56734fd", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/bond_public.verifier b/parameters/src/testnet3/resources/bond_public.verifier deleted file mode 100644 index ec9e26dd70..0000000000 Binary files a/parameters/src/testnet3/resources/bond_public.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/claim_unbond_public.metadata b/parameters/src/testnet3/resources/claim_unbond_public.metadata deleted file mode 100644 index 22c1a5cf42..0000000000 --- a/parameters/src/testnet3/resources/claim_unbond_public.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "f8b64aa87fe94f44c566a3e1ab7fb0b6be4b3da0ac1b1038ba26bff6363ada5e", - "prover_size": 16734260, - "verifier_checksum": "8fd74456a2c8714d70b575ccdbcc180d3a882eb14bd2cbea944265f53c9a7ab4", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/claim_unbond_public.verifier b/parameters/src/testnet3/resources/claim_unbond_public.verifier deleted file mode 100644 index c50f7dd3a4..0000000000 Binary files a/parameters/src/testnet3/resources/claim_unbond_public.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/fee_private.metadata b/parameters/src/testnet3/resources/fee_private.metadata deleted file mode 100644 index 0a39342dd6..0000000000 --- a/parameters/src/testnet3/resources/fee_private.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "43fab9849bfab3aca5c890622bd75ade9b2921cd7a8e74e71cadeba1e247af7f", - "prover_size": 66172740, - "verifier_checksum": "f3dfefcb9e6a691eb0168d547551fc4637c8703ee737c1795d335906b441548d", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/fee_private.verifier b/parameters/src/testnet3/resources/fee_private.verifier deleted file mode 100644 index df7b543fb0..0000000000 Binary files a/parameters/src/testnet3/resources/fee_private.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/fee_public.metadata b/parameters/src/testnet3/resources/fee_public.metadata deleted file mode 100644 index 8606958f1a..0000000000 --- a/parameters/src/testnet3/resources/fee_public.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "634f153fe46f16dc1fe69a8fb01fe0d635ae5b1bda2ccc738187b6d71c97079d", - "prover_size": 29049130, - "verifier_checksum": "09eeb4f23ee22f3cc4d2878ba698e38e8f3b1b8755a55f00e4f237a69825de9d", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/fee_public.verifier b/parameters/src/testnet3/resources/fee_public.verifier deleted file mode 100644 index 3432de13a7..0000000000 Binary files a/parameters/src/testnet3/resources/fee_public.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/inclusion.metadata b/parameters/src/testnet3/resources/inclusion.metadata deleted file mode 100644 index 3532ae5ea8..0000000000 --- a/parameters/src/testnet3/resources/inclusion.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "cd85cc53639becf39b9fc927643abda23f9d385ff2cb890f5df809e7a338bff8", - "prover_size": 232051458, - "verifier_checksum": "e6f3add8fb9f911e02e1aa08b761f24cc8ae5fb70df4da47a36a5bbb83b189ec", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/inclusion.verifier b/parameters/src/testnet3/resources/inclusion.verifier deleted file mode 100644 index 845a9beed7..0000000000 Binary files a/parameters/src/testnet3/resources/inclusion.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/join.metadata b/parameters/src/testnet3/resources/join.metadata deleted file mode 100644 index f8a1f72945..0000000000 --- a/parameters/src/testnet3/resources/join.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "1a76fe88fe132b46af0e3053cf4509cc02346705ecf592483a3775cd465eee40", - "prover_size": 74596892, - "verifier_checksum": "4f1701b27513a630ba70d9a83bf4b611cfe3c566e7c339ea7151923a6728f240", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/join.verifier b/parameters/src/testnet3/resources/join.verifier deleted file mode 100644 index 4a483fca1b..0000000000 Binary files a/parameters/src/testnet3/resources/join.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/powers-of-beta-16.usrs b/parameters/src/testnet3/resources/powers-of-beta-16.usrs deleted file mode 100644 index eb015eb960..0000000000 Binary files a/parameters/src/testnet3/resources/powers-of-beta-16.usrs and /dev/null differ diff --git a/parameters/src/testnet3/resources/set_validator_state.metadata b/parameters/src/testnet3/resources/set_validator_state.metadata deleted file mode 100644 index f48bd71a94..0000000000 --- a/parameters/src/testnet3/resources/set_validator_state.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "5ce19becc2e48750214de6538606e9f5ad9188c811b753045eb32ab4cace626a", - "prover_size": 16990236, - "verifier_checksum": "730d95b5c75918f018e16be47288e372736865b953b29883af552ccf7d63752d", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/set_validator_state.verifier b/parameters/src/testnet3/resources/set_validator_state.verifier deleted file mode 100644 index a4c4868902..0000000000 Binary files a/parameters/src/testnet3/resources/set_validator_state.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/split.metadata b/parameters/src/testnet3/resources/split.metadata deleted file mode 100644 index d57ce0a226..0000000000 --- a/parameters/src/testnet3/resources/split.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "e6d12b9f6578fcae9a805296a6e1f7d282b352457ccf34baceba29e618c79ca2", - "prover_size": 75036196, - "verifier_checksum": "2f9733dbd5a671499a8c8e97a0e043a74b97ed1fecf7834f49d0cd39c9ed171c", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/split.verifier b/parameters/src/testnet3/resources/split.verifier deleted file mode 100644 index c1bf758ed5..0000000000 Binary files a/parameters/src/testnet3/resources/split.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/transfer_private.metadata b/parameters/src/testnet3/resources/transfer_private.metadata deleted file mode 100644 index 594bef3696..0000000000 --- a/parameters/src/testnet3/resources/transfer_private.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "2b487c0b05c5997a7405bbdcd9583cba17da8adf192d6b314dfa95fd70db18ea", - "prover_size": 75823940, - "verifier_checksum": "3a3cbba0e1e038eb15acba228157885b63a779e5c5cb061466948f408fab8439", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/transfer_private.verifier b/parameters/src/testnet3/resources/transfer_private.verifier deleted file mode 100644 index d351e3219c..0000000000 Binary files a/parameters/src/testnet3/resources/transfer_private.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/transfer_private_to_public.metadata b/parameters/src/testnet3/resources/transfer_private_to_public.metadata deleted file mode 100644 index de95819682..0000000000 --- a/parameters/src/testnet3/resources/transfer_private_to_public.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "1ff64cb9cefbbed3416bfb67a0477327446ab5eccc9f725b27df195b948e956f", - "prover_size": 66174244, - "verifier_checksum": "d5b60dec01f95a92b305d914578657d35e1d390ae63e86f0665324b05f0f742d", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/transfer_private_to_public.verifier b/parameters/src/testnet3/resources/transfer_private_to_public.verifier deleted file mode 100644 index 23a4ad33eb..0000000000 Binary files a/parameters/src/testnet3/resources/transfer_private_to_public.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/transfer_public.metadata b/parameters/src/testnet3/resources/transfer_public.metadata deleted file mode 100644 index d1cc764212..0000000000 --- a/parameters/src/testnet3/resources/transfer_public.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "a74565e4fd408a90b2d04b0e6c0dea6bf0ab6a27926ef28049da62d18727f6c6", - "prover_size": 28788210, - "verifier_checksum": "a4c2906a95b2f8bdcc6f192a0c71fb0a1c1aa3830feb54454627cf552674932a", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/transfer_public.verifier b/parameters/src/testnet3/resources/transfer_public.verifier deleted file mode 100644 index d2cd596b91..0000000000 Binary files a/parameters/src/testnet3/resources/transfer_public.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/transfer_public_to_private.metadata b/parameters/src/testnet3/resources/transfer_public_to_private.metadata deleted file mode 100644 index 999ada83f5..0000000000 --- a/parameters/src/testnet3/resources/transfer_public_to_private.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "1bcddf96204302f7a5eb371c3b482f3a8cc102ff222d8bb85328121d927322e1", - "prover_size": 38288044, - "verifier_checksum": "b094554656f1716b5212a98e9c55e544f87f69575fdcc4a8783b5cb4ed6de54b", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/transfer_public_to_private.verifier b/parameters/src/testnet3/resources/transfer_public_to_private.verifier deleted file mode 100644 index 9937585a09..0000000000 Binary files a/parameters/src/testnet3/resources/transfer_public_to_private.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/unbond_delegator_as_validator.metadata b/parameters/src/testnet3/resources/unbond_delegator_as_validator.metadata deleted file mode 100644 index 26d1165177..0000000000 --- a/parameters/src/testnet3/resources/unbond_delegator_as_validator.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "115a86bcc00299fed1f64277fb9688160c425981ce0f62a79cf52515931d9098", - "prover_size": 17159372, - "verifier_checksum": "9585609c87768bf6ebd87cf6b43a4ddfa921a24773feae45e5688685abe36df5", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/unbond_delegator_as_validator.verifier b/parameters/src/testnet3/resources/unbond_delegator_as_validator.verifier deleted file mode 100644 index 8506f2216b..0000000000 Binary files a/parameters/src/testnet3/resources/unbond_delegator_as_validator.verifier and /dev/null differ diff --git a/parameters/src/testnet3/resources/unbond_public.metadata b/parameters/src/testnet3/resources/unbond_public.metadata deleted file mode 100644 index 458b639921..0000000000 --- a/parameters/src/testnet3/resources/unbond_public.metadata +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prover_checksum": "9547c05b4fad4bb957c1b50b5fa15407cc7996b358fc6154240078a5547d4497", - "prover_size": 17014428, - "verifier_checksum": "09873cdd4edccecc576ed77501a6af9276e4952a3c02e20cded951b27105266a", - "verifier_size": 665 -} \ No newline at end of file diff --git a/parameters/src/testnet3/resources/unbond_public.verifier b/parameters/src/testnet3/resources/unbond_public.verifier deleted file mode 100644 index aaf88c581c..0000000000 Binary files a/parameters/src/testnet3/resources/unbond_public.verifier and /dev/null differ diff --git a/rust-toolchain b/rust-toolchain index 22d6771a47..dbd41264aa 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.72.1 +1.81.0 diff --git a/synthesizer/Cargo.toml b/synthesizer/Cargo.toml index 7e9b95e809..d100b6d540 100644 --- a/synthesizer/Cargo.toml +++ b/synthesizer/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-synthesizer" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Synthesizer for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -31,11 +31,11 @@ snark = [ "synthesizer-snark" ] aleo-cli = [ ] async = [ "ledger-query/async", "synthesizer-process/async" ] cuda = [ "algorithms/cuda" ] +history = [ "serde" ] rocks = [ "ledger-store/rocks" ] serial = [ "console/serial", "ledger-block/serial", - "ledger-coinbase/serial", "ledger-committee/serial", "ledger-query/serial", "ledger-store/serial", @@ -44,7 +44,7 @@ serial = [ "synthesizer-snark/serial" ] setup = [ ] -test = [ ] +test = [ "console/test" ] timer = [ "aleo-std/timer" ] wasm = [ "process", @@ -53,7 +53,6 @@ wasm = [ "snark", "console/wasm", "ledger-block/wasm", - "ledger-coinbase/wasm", "ledger-committee/wasm", "ledger-query/wasm", "ledger-store/wasm", @@ -70,63 +69,79 @@ harness = false [dependencies.algorithms] package = "snarkvm-algorithms" path = "../algorithms" -version = "=0.16.19" +version = "=1.1.0" [dependencies.circuit] package = "snarkvm-circuit" path = "../circuit" -version = "=0.16.19" +version = "=1.1.0" [dependencies.console] package = "snarkvm-console" path = "../console" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-block] package = "snarkvm-ledger-block" path = "../ledger/block" -version = "=0.16.19" - -[dependencies.ledger-coinbase] -package = "snarkvm-ledger-coinbase" -path = "../ledger/coinbase" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-committee] package = "snarkvm-ledger-committee" path = "../ledger/committee" -version = "=0.16.19" +version = "=1.1.0" + +[dependencies.ledger-narwhal-data] +package = "snarkvm-ledger-narwhal-data" +path = "../ledger/narwhal/data" +version = "=1.1.0" + +[dependencies.ledger-puzzle] +package = "snarkvm-ledger-puzzle" +path = "../ledger/puzzle" +version = "=1.1.0" + +[dependencies.ledger-puzzle-epoch] +package = "snarkvm-ledger-puzzle-epoch" +path = "../ledger/puzzle/epoch" +version = "=1.1.0" +features = [ "synthesis" ] [dependencies.ledger-query] package = "snarkvm-ledger-query" path = "../ledger/query" -version = "=0.16.19" +version = "=1.1.0" default-features = false features = [ "query" ] [dependencies.ledger-store] package = "snarkvm-ledger-store" path = "../ledger/store" -version = "=0.16.19" +version = "=1.1.0" [dependencies.synthesizer-process] package = "snarkvm-synthesizer-process" path = "./process" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.synthesizer-program] package = "snarkvm-synthesizer-program" path = "./program" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.synthesizer-snark] package = "snarkvm-synthesizer-snark" path = "./snark" -version = "=0.16.19" +version = "=1.1.0" optional = true +[dependencies.utilities] +package = "snarkvm-utilities" +path = "../utilities" +version = "=1.1.0" + [dependencies.aleo-std] version = "0.1.24" default-features = false @@ -138,6 +153,9 @@ version = "1.0" version = "2.0" features = [ "serde", "rayon" ] +[dependencies.itertools] +version = "0.11.0" + [dependencies.lru] version = "0.12" @@ -151,23 +169,36 @@ version = "0.8" version = "1" optional = true +[dependencies.serde] +version = "1.0" +optional = true + +[dependencies.serde_json] +version = "1.0" +features = [ "preserve_order" ] + [dependencies.tracing] version = "0.1" [dev-dependencies.anyhow] version = "1.0.73" +[dev-dependencies.bincode] +version = "1.3.3" + [dev-dependencies.criterion] version = "0.5" -[dev-dependencies.itertools] -version = "0.11.0" - [dev-dependencies.ledger-committee] package = "snarkvm-ledger-committee" path = "../ledger/committee" features = [ "test-helpers" ] +[dev-dependencies.ledger-narwhal-batch-header] +package = "snarkvm-ledger-narwhal-batch-header" +path = "../ledger/narwhal/batch-header" +features = [ "test-helpers" ] + [dev-dependencies.ledger-test-helpers] package = "snarkvm-ledger-test-helpers" path = "../ledger/test-helpers" @@ -178,12 +209,11 @@ version = "1.18" [dev-dependencies.rayon] version = "1" -[dev-dependencies.serde_json] -version = "1.0" -features = [ "preserve_order" ] - [dev-dependencies.serde_yaml] version = "0.9" +[dev-dependencies.tempfile] +version = "3" + [dev-dependencies.walkdir] version = "2" diff --git a/synthesizer/benches/kary_merkle_tree.rs b/synthesizer/benches/kary_merkle_tree.rs index 17e7f8eebc..612709b21a 100644 --- a/synthesizer/benches/kary_merkle_tree.rs +++ b/synthesizer/benches/kary_merkle_tree.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,13 +16,13 @@ #[macro_use] extern crate criterion; -use circuit::{collections::kary_merkle_tree::*, AleoV0, Eject, Environment, Inject, Mode}; +use circuit::{AleoV0, Eject, Environment, Inject, Mode, collections::kary_merkle_tree::*}; use console::{ algorithms::Sha3_256, collections::kary_merkle_tree::KaryMerkleTree, network::{ + MainnetV0, prelude::{TestRng, ToBits, Uniform}, - Testnet3, }, types::Field, }; @@ -29,7 +30,7 @@ use synthesizer_snark::{ProvingKey, UniversalSRS}; use criterion::Criterion; -type CurrentNetwork = Testnet3; +type CurrentNetwork = MainnetV0; type CurrentAleo = AleoV0; type NativePathHasher = Sha3_256; @@ -42,7 +43,7 @@ const ARITY: u8 = 8; /// Generates the specified number of random Merkle tree leaves. macro_rules! generate_leaves { - ($num_leaves:expr, $rng:expr) => {{ (0..$num_leaves).map(|_| Field::::rand($rng).to_bits_le()).collect::>() }}; + ($num_leaves:expr, $rng:expr) => {{ (0..$num_leaves).map(|_| Field::::rand($rng).to_bits_le()).collect::>() }}; } fn batch_prove(c: &mut Criterion) { @@ -74,14 +75,12 @@ fn batch_prove(c: &mut Criterion) { CurrentAleo::reset(); // Initialize the Merkle path circuit. - let path = KaryMerklePath::, DEPTH, ARITY>::new( - Mode::Private, - merkle_path.clone(), - ); + let path = + KaryMerklePath::, DEPTH, ARITY>::new(Mode::Private, merkle_path); // Initialize the Merkle root. let root = >::Hash::new(Mode::Private, *merkle_tree.root()); // Initialize the Merkle leaf. - let leaf: Vec<_> = Inject::new(Mode::Private, merkle_leaf.clone()); + let leaf: Vec<_> = Inject::new(Mode::Private, merkle_leaf); // Verify the merkle path. let candidate = path.verify(&circuit_leaf_hasher, &circuit_path_hasher, &root, &leaf); diff --git a/synthesizer/process/Cargo.toml b/synthesizer/process/Cargo.toml index 86336cae5d..56c8de65b6 100644 --- a/synthesizer/process/Cargo.toml +++ b/synthesizer/process/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-synthesizer-process" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "A process for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -45,48 +45,53 @@ wasm = [ ] timer = [ "aleo-std/timer" ] +[[bench]] +name = "stack_operations" +path = "benches/stack_operations.rs" +harness = false + [dependencies.console] package = "snarkvm-console" path = "../../console" -version = "=0.16.19" +version = "=1.1.0" default-features = false features = [ "network", "program", "types" ] [dependencies.circuit] package = "snarkvm-circuit" path = "../../circuit" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-block] package = "snarkvm-ledger-block" path = "../../ledger/block" -version = "=0.16.19" +version = "=1.1.0" [dependencies.ledger-query] package = "snarkvm-ledger-query" path = "../../ledger/query" -version = "=0.16.19" +version = "=1.1.0" default-features = false [dependencies.ledger-store] package = "snarkvm-ledger-store" path = "../../ledger/store" -version = "=0.16.19" +version = "=1.1.0" [dependencies.synthesizer-program] package = "snarkvm-synthesizer-program" path = "../../synthesizer/program" -version = "=0.16.19" +version = "=1.1.0" [dependencies.synthesizer-snark] package = "snarkvm-synthesizer-snark" path = "../../synthesizer/snark" -version = "=0.16.19" +version = "=1.1.0" [dependencies.utilities] package = "snarkvm-utilities" path = "../../utilities" -version = "=0.16.19" +version = "=1.1.0" [dependencies.aleo-std] version = "0.1.24" @@ -108,6 +113,9 @@ version = "0.12" [dependencies.rand] version = "0.8" +[dependencies.rand_chacha] +version = "0.3" + [dependencies.rayon] version = "1" optional = true @@ -119,6 +127,9 @@ features = [ "preserve_order" ] [dev-dependencies.bincode] version = "1.3" +[dev-dependencies.criterion] +version = "0.5" + [dev-dependencies.ledger-committee] package = "snarkvm-ledger-committee" path = "../../ledger/committee" diff --git a/synthesizer/process/benches/stack_operations.rs b/synthesizer/process/benches/stack_operations.rs new file mode 100644 index 0000000000..353eb569e7 --- /dev/null +++ b/synthesizer/process/benches/stack_operations.rs @@ -0,0 +1,179 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +#[macro_use] +extern crate criterion; + +use console::{ + network::MainnetV0, + program::{Identifier, ProgramID}, + types::Field, +}; +use snarkvm_synthesizer_process::{Process, Stack}; +use synthesizer_program::{Program, StackProgram}; + +use circuit::prelude::bail; +use console::{network::Network, prelude::SizeInDataBits}; +use criterion::{BatchSize, Criterion}; +use rand::{Rng, distributions::Alphanumeric}; +use std::str::FromStr; +use utilities::TestRng; + +type CurrentNetwork = MainnetV0; + +fn bench_stack_new(c: &mut Criterion) { + // The depths to benchmark. + const DEPTHS: [usize; 6] = [1, 2, 4, 8, 16, 31]; + + // Initialize an RNG. + let mut rng = TestRng::default(); + + // Initialize a process. + let mut process = Process::load().unwrap(); + + // Benchmark the base case. + c.bench_function("Depth 0 | Stack::new", |b| { + b.iter_batched_ref( + || { + // Sample a random identifier. + let identifier = sample_identifier_as_string::(&mut rng).unwrap(); + // Construct the program. + Program::from_str(&format!("program {identifier}.aleo; function foo:")).unwrap() + }, + |program| Stack::::new(&process, program), + BatchSize::PerIteration, + ) + }); + + // Add the 0th program to the process. + add_program_at_depth(&mut process, 0); + + // Track the depth. + let mut depth = 1; + + for i in DEPTHS { + // Add programs up to the current depth. + while depth < i { + // Add the program to the process. + add_program_at_depth(&mut process, depth); + // Increment the depth. + depth += 1; + } + + // Benchmark at each depth. + c.bench_function(&format!("Depth {i} | Stack::new"), |b| { + b.iter_batched_ref( + || { + // Sample a random identifier. + let identifier = sample_identifier_as_string::(&mut rng).unwrap(); + // Construct the program. + Program::from_str(&format!( + "program {identifier}.aleo; function foo: call test_{i}.aleo/foo;", + identifier = identifier, + i = i - 1 + )) + .unwrap() + }, + |program| Stack::::new(&process, program), + BatchSize::PerIteration, + ) + }); + } +} + +fn bench_stack_get_number_of_calls(c: &mut Criterion) { + // The depths to benchmark. + const DEPTHS: [usize; 6] = [1, 2, 4, 8, 16, 30]; + + // Initialize a process. + let mut process = Process::load().unwrap(); + + // Add the 0th program to the process. + add_program_at_depth(&mut process, 0); + + // Benchmark the `get_number_of_calls` method for the base case. + c.bench_function("Depth 0 | Stack::get_number_of_calls", |b| { + b.iter(|| { + // Get the `Stack` for the 0th program. + let stack = process.get_stack(ProgramID::from_str("test_0.aleo").unwrap()).unwrap(); + // Benchmark the `get_number_of_calls` method. + stack.get_number_of_calls(&Identifier::from_str("foo").unwrap()) + }) + }); + + // Track the depth. + let mut depth = 1; + + for i in DEPTHS { + // Add programs up to the current depth. + while depth <= i { + // Add the program to the process. + add_program_at_depth(&mut process, depth); + // Increment the depth. + depth += 1; + } + + // Get the `Stack` for the current test program. + let stack = process.get_stack(ProgramID::from_str(&format!("test_{}.aleo", i)).unwrap()).unwrap(); + + // Benchmark the `get_number_of_calls` method. + c.bench_function(&format!("Depth {i} | Stack::get_number_of_calls"), |b| { + b.iter(|| stack.get_number_of_calls(&Identifier::from_str("foo").unwrap())) + }); + } +} + +// Adds a program with a given call depth to the process. +fn add_program_at_depth(process: &mut Process, depth: usize) { + // Construct the program. + let program = if depth == 0 { + Program::from_str(r"program test_0.aleo; function foo:").unwrap() + } else { + Program::from_str(&format!( + "import test_{import}.aleo; program test_{current}.aleo; function foo: call test_{import}.aleo/foo;", + import = depth - 1, + current = depth + )) + .unwrap() + }; + + // Add the program to the process. + process.add_program(&program).unwrap(); +} + +// Samples a random identifier as a string. +fn sample_identifier_as_string(rng: &mut TestRng) -> console::prelude::Result { + // Sample a random fixed-length alphanumeric string, that always starts with an alphabetic character. + let string = "a".to_string() + + &rng + .sample_iter(&Alphanumeric) + .take(Field::::size_in_data_bits() / (8 * 2)) + .map(char::from) + .collect::(); + // Ensure identifier fits within the data capacity of the base field. + let max_bytes = Field::::size_in_data_bits() / 8; // Note: This intentionally rounds down. + match string.len() <= max_bytes { + // Return the identifier. + true => Ok(string.to_lowercase()), + false => bail!("Identifier exceeds the maximum capacity allowed"), + } +} + +criterion_group! { + name = stack_operations; + config = Criterion::default().sample_size(10); + targets = bench_stack_new, bench_stack_get_number_of_calls +} +criterion_main!(stack_operations); diff --git a/synthesizer/process/src/authorize.rs b/synthesizer/process/src/authorize.rs index da526e7b5b..6f26ae982a 100644 --- a/synthesizer/process/src/authorize.rs +++ b/synthesizer/process/src/authorize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/cost.rs b/synthesizer/process/src/cost.rs new file mode 100644 index 0000000000..4f75e9d2c7 --- /dev/null +++ b/synthesizer/process/src/cost.rs @@ -0,0 +1,550 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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::{Process, Stack, StackProgramTypes}; + +use console::{ + prelude::*, + program::{FinalizeType, Identifier, LiteralType, PlaintextType}, +}; +use ledger_block::{Deployment, Execution}; +use synthesizer_program::{CastType, Command, Finalize, Instruction, Operand, StackProgram}; + +/// Returns the *minimum* cost in microcredits to publish the given deployment (total cost, (storage cost, synthesis cost, namespace cost)). +pub fn deployment_cost(deployment: &Deployment) -> Result<(u64, (u64, u64, u64))> { + // Determine the number of bytes in the deployment. + let size_in_bytes = deployment.size_in_bytes()?; + // Retrieve the program ID. + let program_id = deployment.program_id(); + // Determine the number of characters in the program ID. + let num_characters = u32::try_from(program_id.name().to_string().len())?; + // Compute the number of combined variables in the program. + let num_combined_variables = deployment.num_combined_variables()?; + // Compute the number of combined constraints in the program. + let num_combined_constraints = deployment.num_combined_constraints()?; + + // Compute the storage cost in microcredits. + let storage_cost = size_in_bytes + .checked_mul(N::DEPLOYMENT_FEE_MULTIPLIER) + .ok_or(anyhow!("The storage cost computation overflowed for a deployment"))?; + + // Compute the synthesis cost in microcredits. + let synthesis_cost = num_combined_variables.saturating_add(num_combined_constraints) * N::SYNTHESIS_FEE_MULTIPLIER; + + // Compute the namespace cost in credits: 10^(10 - num_characters). + let namespace_cost = 10u64 + .checked_pow(10u32.saturating_sub(num_characters)) + .ok_or(anyhow!("The namespace cost computation overflowed for a deployment"))? + .saturating_mul(1_000_000); // 1 microcredit = 1e-6 credits. + + // Compute the total cost in microcredits. + let total_cost = storage_cost + .checked_add(synthesis_cost) + .and_then(|x| x.checked_add(namespace_cost)) + .ok_or(anyhow!("The total cost computation overflowed for a deployment"))?; + + Ok((total_cost, (storage_cost, synthesis_cost, namespace_cost))) +} + +/// Returns the *minimum* cost in microcredits to publish the given execution (total cost, (storage cost, finalize cost)). +pub fn execution_cost_v2(process: &Process, execution: &Execution) -> Result<(u64, (u64, u64))> { + // Compute the storage cost in microcredits. + let storage_cost = execution_storage_cost::(execution.size_in_bytes()?); + + // Get the root transition. + let transition = execution.peek()?; + + // Get the finalize cost for the root transition. + let finalize_cost = process.get_stack(transition.program_id())?.get_finalize_cost(transition.function_name())?; + + // Compute the total cost in microcredits. + let total_cost = storage_cost + .checked_add(finalize_cost) + .ok_or(anyhow!("The total cost computation overflowed for an execution"))?; + + Ok((total_cost, (storage_cost, finalize_cost))) +} + +/// Returns the *minimum* cost in microcredits to publish the given execution (total cost, (storage cost, finalize cost)). +pub fn execution_cost_v1(process: &Process, execution: &Execution) -> Result<(u64, (u64, u64))> { + // Compute the storage cost in microcredits. + let storage_cost = execution_storage_cost::(execution.size_in_bytes()?); + + // Get the root transition. + let transition = execution.peek()?; + + // Get the finalize cost for the root transition. + let stack = process.get_stack(transition.program_id())?; + let finalize_cost = cost_in_microcredits_v1(stack, transition.function_name())?; + + // Compute the total cost in microcredits. + let total_cost = storage_cost + .checked_add(finalize_cost) + .ok_or(anyhow!("The total cost computation overflowed for an execution"))?; + + Ok((total_cost, (storage_cost, finalize_cost))) +} + +/// Returns the storage cost in microcredits for a program execution. +fn execution_storage_cost(size_in_bytes: u64) -> u64 { + if size_in_bytes > N::EXECUTION_STORAGE_PENALTY_THRESHOLD { + size_in_bytes.saturating_mul(size_in_bytes).saturating_div(N::EXECUTION_STORAGE_FEE_SCALING_FACTOR) + } else { + size_in_bytes + } +} + +/// Finalize costs for compute heavy operations, derived as: +/// `BASE_COST + (PER_BYTE_COST * SIZE_IN_BYTES)`. + +const CAST_BASE_COST: u64 = 500; +const CAST_PER_BYTE_COST: u64 = 30; + +const HASH_BASE_COST: u64 = 10_000; +const HASH_PER_BYTE_COST: u64 = 30; + +const HASH_BHP_BASE_COST: u64 = 50_000; +const HASH_BHP_PER_BYTE_COST: u64 = 300; + +const HASH_PSD_BASE_COST: u64 = 40_000; +const HASH_PSD_PER_BYTE_COST: u64 = 75; + +pub enum ConsensusFeeVersion { + V1, + V2, +} + +const MAPPING_BASE_COST_V1: u64 = 10_000; +const MAPPING_BASE_COST_V2: u64 = 1_500; +const MAPPING_PER_BYTE_COST: u64 = 10; + +const SET_BASE_COST: u64 = 10_000; +const SET_PER_BYTE_COST: u64 = 100; + +/// A helper function to determine the plaintext type in bytes. +fn plaintext_size_in_bytes(stack: &Stack, plaintext_type: &PlaintextType) -> Result { + match plaintext_type { + PlaintextType::Literal(literal_type) => Ok(literal_type.size_in_bytes::() as u64), + PlaintextType::Struct(struct_name) => { + // Retrieve the struct from the stack. + let struct_ = stack.program().get_struct(struct_name)?; + // Retrieve the size of the struct name. + let size_of_name = struct_.name().to_bytes_le()?.len() as u64; + // Retrieve the size of all the members of the struct. + let size_of_members = struct_.members().iter().try_fold(0u64, |acc, (_, member_type)| { + acc.checked_add(plaintext_size_in_bytes(stack, member_type)?).ok_or(anyhow!( + "Overflowed while computing the size of the struct '{}/{struct_name}' - {member_type}", + stack.program_id() + )) + })?; + // Return the size of the struct. + Ok(size_of_name.saturating_add(size_of_members)) + } + PlaintextType::Array(array_type) => { + // Retrieve the number of elements in the array. + let num_elements = **array_type.length() as u64; + // Compute the size of an array element. + let size_of_element = plaintext_size_in_bytes(stack, array_type.next_element_type())?; + // Return the size of the array. + Ok(num_elements.saturating_mul(size_of_element)) + } + } +} + +/// A helper function to compute the following: base_cost + (byte_multiplier * size_of_operands). +fn cost_in_size<'a, N: Network>( + stack: &Stack, + finalize: &Finalize, + operands: impl IntoIterator>, + byte_multiplier: u64, + base_cost: u64, +) -> Result { + // Retrieve the finalize types. + let finalize_types = stack.get_finalize_types(finalize.name())?; + // Compute the size of the operands. + let size_of_operands = operands.into_iter().try_fold(0u64, |acc, operand| { + // Determine the size of the operand. + let operand_size = match finalize_types.get_type_from_operand(stack, operand)? { + FinalizeType::Plaintext(plaintext_type) => plaintext_size_in_bytes(stack, &plaintext_type)?, + FinalizeType::Future(future) => { + bail!("Future '{future}' is not a valid operand in the finalize scope"); + } + }; + // Safely add the size to the accumulator. + acc.checked_add(operand_size).ok_or(anyhow!( + "Overflowed while computing the size of the operand '{operand}' in '{}/{}' (finalize)", + stack.program_id(), + finalize.name() + )) + })?; + // Return the cost. + Ok(base_cost.saturating_add(byte_multiplier.saturating_mul(size_of_operands))) +} + +/// Returns the the cost of a command in a finalize scope. +pub fn cost_per_command( + stack: &Stack, + finalize: &Finalize, + command: &Command, + consensus_fee_version: ConsensusFeeVersion, +) -> Result { + let mapping_base_cost = match consensus_fee_version { + ConsensusFeeVersion::V1 => MAPPING_BASE_COST_V1, + ConsensusFeeVersion::V2 => MAPPING_BASE_COST_V2, + }; + + match command { + Command::Instruction(Instruction::Abs(_)) => Ok(500), + Command::Instruction(Instruction::AbsWrapped(_)) => Ok(500), + Command::Instruction(Instruction::Add(_)) => Ok(500), + Command::Instruction(Instruction::AddWrapped(_)) => Ok(500), + Command::Instruction(Instruction::And(_)) => Ok(500), + Command::Instruction(Instruction::AssertEq(_)) => Ok(500), + Command::Instruction(Instruction::AssertNeq(_)) => Ok(500), + Command::Instruction(Instruction::Async(_)) => bail!("'async' is not supported in finalize"), + Command::Instruction(Instruction::Call(_)) => bail!("'call' is not supported in finalize"), + Command::Instruction(Instruction::Cast(cast)) => match cast.cast_type() { + CastType::Plaintext(PlaintextType::Literal(_)) => Ok(500), + CastType::Plaintext(plaintext_type) => Ok(plaintext_size_in_bytes(stack, plaintext_type)? + .saturating_mul(CAST_PER_BYTE_COST) + .saturating_add(CAST_BASE_COST)), + CastType::GroupXCoordinate + | CastType::GroupYCoordinate + | CastType::Record(_) + | CastType::ExternalRecord(_) => Ok(500), + }, + Command::Instruction(Instruction::CastLossy(cast_lossy)) => match cast_lossy.cast_type() { + CastType::Plaintext(PlaintextType::Literal(_)) => Ok(500), + CastType::Plaintext(plaintext_type) => Ok(plaintext_size_in_bytes(stack, plaintext_type)? + .saturating_mul(CAST_PER_BYTE_COST) + .saturating_add(CAST_BASE_COST)), + CastType::GroupXCoordinate + | CastType::GroupYCoordinate + | CastType::Record(_) + | CastType::ExternalRecord(_) => Ok(500), + }, + Command::Instruction(Instruction::CommitBHP256(commit)) => { + cost_in_size(stack, finalize, commit.operands(), HASH_BHP_PER_BYTE_COST, HASH_BHP_BASE_COST) + } + Command::Instruction(Instruction::CommitBHP512(commit)) => { + cost_in_size(stack, finalize, commit.operands(), HASH_BHP_PER_BYTE_COST, HASH_BHP_BASE_COST) + } + Command::Instruction(Instruction::CommitBHP768(commit)) => { + cost_in_size(stack, finalize, commit.operands(), HASH_BHP_PER_BYTE_COST, HASH_BHP_BASE_COST) + } + Command::Instruction(Instruction::CommitBHP1024(commit)) => { + cost_in_size(stack, finalize, commit.operands(), HASH_BHP_PER_BYTE_COST, HASH_BHP_BASE_COST) + } + Command::Instruction(Instruction::CommitPED64(commit)) => { + cost_in_size(stack, finalize, commit.operands(), HASH_PER_BYTE_COST, HASH_BASE_COST) + } + Command::Instruction(Instruction::CommitPED128(commit)) => { + cost_in_size(stack, finalize, commit.operands(), HASH_PER_BYTE_COST, HASH_BASE_COST) + } + Command::Instruction(Instruction::Div(div)) => { + // Ensure `div` has exactly two operands. + ensure!(div.operands().len() == 2, "'div' must contain exactly 2 operands"); + // Retrieve the finalize types. + let finalize_types = stack.get_finalize_types(finalize.name())?; + // Retrieve the price by the operand type. + match finalize_types.get_type_from_operand(stack, &div.operands()[0])? { + FinalizeType::Plaintext(PlaintextType::Literal(LiteralType::Field)) => Ok(1_500), + FinalizeType::Plaintext(PlaintextType::Literal(_)) => Ok(500), + FinalizeType::Plaintext(PlaintextType::Array(_)) => bail!("'div' does not support arrays"), + FinalizeType::Plaintext(PlaintextType::Struct(_)) => bail!("'div' does not support structs"), + FinalizeType::Future(_) => bail!("'div' does not support futures"), + } + } + Command::Instruction(Instruction::DivWrapped(_)) => Ok(500), + Command::Instruction(Instruction::Double(_)) => Ok(500), + Command::Instruction(Instruction::GreaterThan(_)) => Ok(500), + Command::Instruction(Instruction::GreaterThanOrEqual(_)) => Ok(500), + Command::Instruction(Instruction::HashBHP256(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_BHP_PER_BYTE_COST, HASH_BHP_BASE_COST) + } + Command::Instruction(Instruction::HashBHP512(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_BHP_PER_BYTE_COST, HASH_BHP_BASE_COST) + } + Command::Instruction(Instruction::HashBHP768(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_BHP_PER_BYTE_COST, HASH_BHP_BASE_COST) + } + Command::Instruction(Instruction::HashBHP1024(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_BHP_PER_BYTE_COST, HASH_BHP_BASE_COST) + } + Command::Instruction(Instruction::HashKeccak256(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_PER_BYTE_COST, HASH_BASE_COST) + } + Command::Instruction(Instruction::HashKeccak384(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_PER_BYTE_COST, HASH_BASE_COST) + } + Command::Instruction(Instruction::HashKeccak512(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_PER_BYTE_COST, HASH_BASE_COST) + } + Command::Instruction(Instruction::HashPED64(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_PER_BYTE_COST, HASH_BASE_COST) + } + Command::Instruction(Instruction::HashPED128(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_PER_BYTE_COST, HASH_BASE_COST) + } + Command::Instruction(Instruction::HashPSD2(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_PSD_PER_BYTE_COST, HASH_PSD_BASE_COST) + } + Command::Instruction(Instruction::HashPSD4(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_PSD_PER_BYTE_COST, HASH_PSD_BASE_COST) + } + Command::Instruction(Instruction::HashPSD8(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_PSD_PER_BYTE_COST, HASH_PSD_BASE_COST) + } + Command::Instruction(Instruction::HashSha3_256(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_PER_BYTE_COST, HASH_BASE_COST) + } + Command::Instruction(Instruction::HashSha3_384(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_PER_BYTE_COST, HASH_BASE_COST) + } + Command::Instruction(Instruction::HashSha3_512(hash)) => { + cost_in_size(stack, finalize, hash.operands(), HASH_PER_BYTE_COST, HASH_BASE_COST) + } + Command::Instruction(Instruction::HashManyPSD2(_)) => { + bail!("`hash_many.psd2` is not supported in finalize") + } + Command::Instruction(Instruction::HashManyPSD4(_)) => { + bail!("`hash_many.psd4` is not supported in finalize") + } + Command::Instruction(Instruction::HashManyPSD8(_)) => { + bail!("`hash_many.psd8` is not supported in finalize") + } + Command::Instruction(Instruction::Inv(_)) => Ok(2_500), + Command::Instruction(Instruction::IsEq(_)) => Ok(500), + Command::Instruction(Instruction::IsNeq(_)) => Ok(500), + Command::Instruction(Instruction::LessThan(_)) => Ok(500), + Command::Instruction(Instruction::LessThanOrEqual(_)) => Ok(500), + Command::Instruction(Instruction::Modulo(_)) => Ok(500), + Command::Instruction(Instruction::Mul(mul)) => { + // Ensure `mul` has exactly two operands. + ensure!(mul.operands().len() == 2, "'mul' must contain exactly 2 operands"); + // Retrieve the finalize types. + let finalize_types = stack.get_finalize_types(finalize.name())?; + // Retrieve the price by operand type. + match finalize_types.get_type_from_operand(stack, &mul.operands()[0])? { + FinalizeType::Plaintext(PlaintextType::Literal(LiteralType::Group)) => Ok(10_000), + FinalizeType::Plaintext(PlaintextType::Literal(LiteralType::Scalar)) => Ok(10_000), + FinalizeType::Plaintext(PlaintextType::Literal(_)) => Ok(500), + FinalizeType::Plaintext(PlaintextType::Array(_)) => bail!("'mul' does not support arrays"), + FinalizeType::Plaintext(PlaintextType::Struct(_)) => bail!("'mul' does not support structs"), + FinalizeType::Future(_) => bail!("'mul' does not support futures"), + } + } + Command::Instruction(Instruction::MulWrapped(_)) => Ok(500), + Command::Instruction(Instruction::Nand(_)) => Ok(500), + Command::Instruction(Instruction::Neg(_)) => Ok(500), + Command::Instruction(Instruction::Nor(_)) => Ok(500), + Command::Instruction(Instruction::Not(_)) => Ok(500), + Command::Instruction(Instruction::Or(_)) => Ok(500), + Command::Instruction(Instruction::Pow(pow)) => { + // Ensure `pow` has at least one operand. + ensure!(!pow.operands().is_empty(), "'pow' must contain at least 1 operand"); + // Retrieve the finalize types. + let finalize_types = stack.get_finalize_types(finalize.name())?; + // Retrieve the price by operand type. + match finalize_types.get_type_from_operand(stack, &pow.operands()[0])? { + FinalizeType::Plaintext(PlaintextType::Literal(LiteralType::Field)) => Ok(1_500), + FinalizeType::Plaintext(PlaintextType::Literal(_)) => Ok(500), + FinalizeType::Plaintext(PlaintextType::Array(_)) => bail!("'pow' does not support arrays"), + FinalizeType::Plaintext(PlaintextType::Struct(_)) => bail!("'pow' does not support structs"), + FinalizeType::Future(_) => bail!("'pow' does not support futures"), + } + } + Command::Instruction(Instruction::PowWrapped(_)) => Ok(500), + Command::Instruction(Instruction::Rem(_)) => Ok(500), + Command::Instruction(Instruction::RemWrapped(_)) => Ok(500), + Command::Instruction(Instruction::SignVerify(sign)) => { + cost_in_size(stack, finalize, sign.operands(), HASH_PSD_PER_BYTE_COST, HASH_PSD_BASE_COST) + } + Command::Instruction(Instruction::Shl(_)) => Ok(500), + Command::Instruction(Instruction::ShlWrapped(_)) => Ok(500), + Command::Instruction(Instruction::Shr(_)) => Ok(500), + Command::Instruction(Instruction::ShrWrapped(_)) => Ok(500), + Command::Instruction(Instruction::Square(_)) => Ok(500), + Command::Instruction(Instruction::SquareRoot(_)) => Ok(2_500), + Command::Instruction(Instruction::Sub(_)) => Ok(500), + Command::Instruction(Instruction::SubWrapped(_)) => Ok(500), + Command::Instruction(Instruction::Ternary(_)) => Ok(500), + Command::Instruction(Instruction::Xor(_)) => Ok(500), + Command::Await(_) => Ok(500), + Command::Contains(command) => { + cost_in_size(stack, finalize, [command.key()], MAPPING_PER_BYTE_COST, mapping_base_cost) + } + Command::Get(command) => { + cost_in_size(stack, finalize, [command.key()], MAPPING_PER_BYTE_COST, mapping_base_cost) + } + Command::GetOrUse(command) => { + cost_in_size(stack, finalize, [command.key()], MAPPING_PER_BYTE_COST, mapping_base_cost) + } + Command::RandChaCha(_) => Ok(25_000), + Command::Remove(_) => Ok(SET_BASE_COST), + Command::Set(command) => { + cost_in_size(stack, finalize, [command.key(), command.value()], SET_PER_BYTE_COST, SET_BASE_COST) + } + Command::BranchEq(_) | Command::BranchNeq(_) => Ok(500), + Command::Position(_) => Ok(100), + } +} + +/// Returns the minimum number of microcredits required to run the finalize. +pub fn cost_in_microcredits_v2(stack: &Stack, function_name: &Identifier) -> Result { + // Retrieve the finalize logic. + let Some(finalize) = stack.get_function_ref(function_name)?.finalize_logic() else { + // Return a finalize cost of 0, if the function does not have a finalize scope. + return Ok(0); + }; + // Get the cost of finalizing all futures. + let mut future_cost = 0u64; + for input in finalize.inputs() { + if let FinalizeType::Future(future) = input.finalize_type() { + // Get the external stack for the future. + let stack = stack.get_external_stack(future.program_id())?; + // Accumulate the finalize cost of the future. + future_cost = future_cost + .checked_add(stack.get_finalize_cost(future.resource())?) + .ok_or(anyhow!("Finalize cost overflowed"))?; + } + } + // Aggregate the cost of all commands in the program. + finalize + .commands() + .iter() + .map(|command| cost_per_command(stack, finalize, command, ConsensusFeeVersion::V2)) + .try_fold(future_cost, |acc, res| { + res.and_then(|x| acc.checked_add(x).ok_or(anyhow!("Finalize cost overflowed"))) + }) +} + +/// Returns the minimum number of microcredits required to run the finalize (depcrated). +pub fn cost_in_microcredits_v1(stack: &Stack, function_name: &Identifier) -> Result { + // Retrieve the finalize logic. + let Some(finalize) = stack.get_function_ref(function_name)?.finalize_logic() else { + // Return a finalize cost of 0, if the function does not have a finalize scope. + return Ok(0); + }; + // Get the cost of finalizing all futures. + let mut future_cost = 0u64; + for input in finalize.inputs() { + if let FinalizeType::Future(future) = input.finalize_type() { + // Get the external stack for the future. + let stack = stack.get_external_stack(future.program_id())?; + // Accumulate the finalize cost of the future. + future_cost = future_cost + .checked_add(cost_in_microcredits_v1(stack, future.resource())?) + .ok_or(anyhow!("Finalize cost overflowed"))?; + } + } + // Aggregate the cost of all commands in the program. + finalize + .commands() + .iter() + .map(|command| cost_per_command(stack, finalize, command, ConsensusFeeVersion::V1)) + .try_fold(future_cost, |acc, res| { + res.and_then(|x| acc.checked_add(x).ok_or(anyhow!("Finalize cost overflowed"))) + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::test_helpers::get_execution; + + use console::network::{CanaryV0, MainnetV0, TestnetV0}; + use synthesizer_program::Program; + + // Test program with two functions just below and above the size threshold. + const SIZE_BOUNDARY_PROGRAM: &str = r#" +program size_boundary.aleo; + +function under_five_thousand: + input r0 as group.public; + cast r0 r0 r0 r0 r0 r0 r0 r0 r0 into r1 as [group; 9u32]; + cast r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 into r2 as [[group; 9u32]; 10u32]; + cast r0 r0 r0 r0 r0 r0 r0 into r3 as [group; 7u32]; + output r2 as [[group; 9u32]; 10u32].public; + output r3 as [group; 7u32].public; + +function over_five_thousand: + input r0 as group.public; + cast r0 r0 r0 r0 r0 r0 r0 r0 r0 into r1 as [group; 9u32]; + cast r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 into r2 as [[group; 9u32]; 10u32]; + cast r0 r0 r0 r0 r0 r0 r0 into r3 as [group; 7u32]; + output r2 as [[group; 9u32]; 10u32].public; + output r3 as [group; 7u32].public; + output 5u64 as u64.public; + "#; + // Cost for a program +1 byte above the threshold. + const STORAGE_COST_ABOVE_THRESHOLD: u64 = 5002; + // Storage cost for an execution transaction at the maximum transaction size. + const STORAGE_COST_MAX: u64 = 3_276_800; + + fn test_storage_cost_bounds() { + // Calculate the bounds directly above and below the size threshold. + let threshold = N::EXECUTION_STORAGE_PENALTY_THRESHOLD; + let threshold_lower_offset = threshold.saturating_sub(1); + let threshold_upper_offset = threshold.saturating_add(1); + + // Test the storage cost bounds. + assert_eq!(execution_storage_cost::(0), 0); + assert_eq!(execution_storage_cost::(1), 1); + assert_eq!(execution_storage_cost::(threshold_lower_offset), threshold_lower_offset); + assert_eq!(execution_storage_cost::(threshold), threshold); + assert_eq!(execution_storage_cost::(threshold_upper_offset), STORAGE_COST_ABOVE_THRESHOLD); + assert_eq!(execution_storage_cost::(N::MAX_TRANSACTION_SIZE as u64), STORAGE_COST_MAX); + } + + #[test] + fn test_storage_cost_bounds_for_all_networks() { + test_storage_cost_bounds::(); + test_storage_cost_bounds::(); + test_storage_cost_bounds::(); + } + + #[test] + fn test_storage_costs_compute_correctly() { + // Test the storage cost of an execution. + let threshold = MainnetV0::EXECUTION_STORAGE_PENALTY_THRESHOLD; + + // Test the cost of an execution. + let mut process = Process::load().unwrap(); + + // Get the program. + let program = Program::from_str(SIZE_BOUNDARY_PROGRAM).unwrap(); + + // Get the program identifiers. + let under_5000 = Identifier::from_str("under_five_thousand").unwrap(); + let over_5000 = Identifier::from_str("over_five_thousand").unwrap(); + + // Get execution and cost data. + let execution_under_5000 = get_execution(&mut process, &program, &under_5000, ["2group"].into_iter()); + let execution_size_under_5000 = execution_under_5000.size_in_bytes().unwrap(); + let (_, (storage_cost_under_5000, _)) = execution_cost_v2(&process, &execution_under_5000).unwrap(); + let execution_over_5000 = get_execution(&mut process, &program, &over_5000, ["2group"].into_iter()); + let execution_size_over_5000 = execution_over_5000.size_in_bytes().unwrap(); + let (_, (storage_cost_over_5000, _)) = execution_cost_v2(&process, &execution_over_5000).unwrap(); + + // Ensure the sizes are below and above the threshold respectively. + assert!(execution_size_under_5000 < threshold); + assert!(execution_size_over_5000 > threshold); + + // Ensure storage costs compute correctly. + assert_eq!(storage_cost_under_5000, execution_storage_cost::(execution_size_under_5000)); + assert_eq!(storage_cost_over_5000, execution_storage_cost::(execution_size_over_5000)); + } +} diff --git a/synthesizer/process/src/deploy.rs b/synthesizer/process/src/deploy.rs index b876a37f0e..88ddb829fd 100644 --- a/synthesizer/process/src/deploy.rs +++ b/synthesizer/process/src/deploy.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/evaluate.rs b/synthesizer/process/src/evaluate.rs index 53ba6000d8..f30c6be866 100644 --- a/synthesizer/process/src/evaluate.rs +++ b/synthesizer/process/src/evaluate.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/execute.rs b/synthesizer/process/src/execute.rs index 7311f018be..ebc4cd7694 100644 --- a/synthesizer/process/src/execute.rs +++ b/synthesizer/process/src/execute.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -32,6 +33,10 @@ impl Process { #[cfg(feature = "aleo-cli")] println!("{}", format!(" • Executing '{locator}'...",).dimmed()); + // This is the root request and does not have a caller. + let caller = None; + // This is the root request and we do not have a root_tvk to pass on. + let root_tvk = None; // Initialize the trace. let trace = Arc::new(RwLock::new(Trace::new())); // Initialize the call stack. @@ -41,7 +46,7 @@ impl Process { // Retrieve the stack. let stack = self.get_stack(request.program_id())?; // Execute the circuit. - let response = stack.execute_function::(call_stack, None, rng)?; + let response = stack.execute_function::(call_stack, caller, root_tvk, rng)?; lap!(timer, "Execute the function"); // Extract the trace. @@ -59,7 +64,7 @@ mod tests { use super::*; use console::types::Address; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; type CurrentAleo = circuit::AleoV0; #[test] diff --git a/synthesizer/process/src/finalize.rs b/synthesizer/process/src/finalize.rs index 974ed1e158..6606d2d152 100644 --- a/synthesizer/process/src/finalize.rs +++ b/synthesizer/process/src/finalize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,9 +14,11 @@ // limitations under the License. use super::*; -use console::program::{Future, Register}; +use console::program::{FinalizeType, Future, Register}; use synthesizer_program::{Await, FinalizeRegistersState, Operand}; -use utilities::handle_halting; +use utilities::try_vm_runtime; + +use std::collections::HashSet; impl Process { /// Finalizes the deployment and fee. @@ -209,13 +212,13 @@ fn finalize_transition>( states.push(initialize_finalize_state(state, future, stack, *transition.id())?); // While there are active finalize states, finalize them. - while let Some(FinalizeState { + 'outer: while let Some(FinalizeState { mut counter, finalize, mut registers, stack, mut call_counter, - mut recent_call_locator, + mut awaited, }) = states.pop() { // Evaluate the commands. @@ -225,9 +228,7 @@ fn finalize_transition>( // Finalize the command. match &command { Command::BranchEq(branch_eq) => { - let result = handle_halting!(panic::AssertUnwindSafe(|| { - branch_to(counter, branch_eq, finalize, stack, ®isters) - })); + let result = try_vm_runtime!(|| branch_to(counter, branch_eq, finalize, stack, ®isters)); match result { Ok(Ok(new_counter)) => { counter = new_counter; @@ -239,9 +240,7 @@ fn finalize_transition>( } } Command::BranchNeq(branch_neq) => { - let result = handle_halting!(panic::AssertUnwindSafe(|| { - branch_to(counter, branch_neq, finalize, stack, ®isters) - })); + let result = try_vm_runtime!(|| branch_to(counter, branch_neq, finalize, stack, ®isters)); match result { Ok(Ok(new_counter)) => { counter = new_counter; @@ -253,18 +252,16 @@ fn finalize_transition>( } } Command::Await(await_) => { - // Check that the `await` register's locator is greater than the last seen call locator. - // This ensures that futures are invoked in the order they are called. - let locator = *match await_.register() { - Register::Locator(locator) => locator, - Register::Access(..) => bail!("The 'await' register must be a locator"), + // Check that the `await` register's is a locator. + if let Register::Access(_, _) = await_.register() { + bail!("The 'await' register must be a locator") }; - if let Some(recent_call_locator) = recent_call_locator { - ensure!( - locator > recent_call_locator, - "Await register's locator '{locator}' must be greater than the last seen call locator '{recent_call_locator}'", - ) - } + // Check that the future has not previously been awaited. + ensure!( + !awaited.contains(await_.register()), + "The future register '{}' has already been awaited", + await_.register() + ); // Get the current transition ID. let transition_id = registers.transition_id(); @@ -277,38 +274,35 @@ fn finalize_transition>( None => bail!("Transition ID '{transition_id}' not found in call graph"), }; - let callee_state = match handle_halting!(panic::AssertUnwindSafe(|| { - // Set up the finalize state for the await. - setup_await(state, await_, stack, ®isters, child_transition_id) - })) { - Ok(Ok(callee_state)) => callee_state, - // If the evaluation fails, bail and return the error. - Ok(Err(error)) => bail!("'finalize' failed to evaluate command ({command}): {error}"), - // If the evaluation fails, bail and return the error. - Err(_) => bail!("'finalize' failed to evaluate command ({command})"), - }; + // Set up the finalize state for the await. + let callee_state = + match try_vm_runtime!(|| setup_await(state, await_, stack, ®isters, child_transition_id)) { + Ok(Ok(callee_state)) => callee_state, + // If the evaluation fails, bail and return the error. + Ok(Err(error)) => bail!("'finalize' failed to evaluate command ({command}): {error}"), + // If the evaluation fails, bail and return the error. + Err(_) => bail!("'finalize' failed to evaluate command ({command})"), + }; - // Set the last seen call locator. - recent_call_locator = Some(locator); // Increment the call counter. call_counter += 1; // Increment the counter. counter += 1; + // Add the awaited register to the tracked set. + awaited.insert(await_.register().clone()); // Aggregate the caller state. - let caller_state = - FinalizeState { counter, finalize, registers, stack, call_counter, recent_call_locator }; + let caller_state = FinalizeState { counter, finalize, registers, stack, call_counter, awaited }; // Push the caller state onto the stack. states.push(caller_state); // Push the callee state onto the stack. states.push(callee_state); - break; + continue 'outer; } _ => { - let result = - handle_halting!(panic::AssertUnwindSafe(|| { command.finalize(stack, store, &mut registers) })); + let result = try_vm_runtime!(|| command.finalize(stack, store, &mut registers)); match result { // If the evaluation succeeds with an operation, add it to the list. Ok(Ok(Some(finalize_operation))) => finalize_operations.push(finalize_operation), @@ -323,6 +317,18 @@ fn finalize_transition>( } }; } + // Check that all future registers have been awaited. + let mut unawaited = Vec::new(); + for input in finalize.inputs() { + if matches!(input.finalize_type(), FinalizeType::Future(_)) && !awaited.contains(input.register()) { + unawaited.push(input.register().clone()); + } + } + ensure!( + unawaited.is_empty(), + "The following future registers have not been awaited: {}", + unawaited.iter().map(|r| r.to_string()).collect::>().join(", ") + ); } // Return the finalize operations. @@ -341,8 +347,8 @@ struct FinalizeState<'a, N: Network> { stack: &'a Stack, // Call counter. call_counter: usize, - // Recent call register. - recent_call_locator: Option, + // Awaited futures. + awaited: HashSet>, } // A helper function to initialize the finalize state. @@ -385,7 +391,7 @@ fn initialize_finalize_state<'a, N: Network>( }, )?; - Ok(FinalizeState { counter: 0, finalize, registers, stack, call_counter: 0, recent_call_locator: None }) + Ok(FinalizeState { counter: 0, finalize, registers, stack, call_counter: 0, awaited: Default::default() }) } // A helper function that sets up the await operation. @@ -444,11 +450,11 @@ mod tests { use crate::tests::test_execute::{sample_fee, sample_finalize_state}; use console::prelude::TestRng; use ledger_store::{ - helpers::memory::{BlockMemory, FinalizeMemory}, BlockStore, + helpers::memory::{BlockMemory, FinalizeMemory}, }; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; type CurrentAleo = circuit::network::AleoV0; #[test] diff --git a/synthesizer/process/src/lib.rs b/synthesizer/process/src/lib.rs index 392574ee2b..85185f39f8 100644 --- a/synthesizer/process/src/lib.rs +++ b/synthesizer/process/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,6 +19,9 @@ // TODO (howardwu): Update the return type on `execute` after stabilizing the interface. #![allow(clippy::type_complexity)] +mod cost; +pub use cost::*; + mod stack; pub use stack::*; @@ -42,11 +46,11 @@ mod tests; use console::{ account::PrivateKey, network::prelude::*, - program::{Identifier, Literal, Locator, Plaintext, ProgramID, Record, Response, Value}, + program::{Identifier, Literal, Locator, Plaintext, ProgramID, Record, Response, Value, compute_function_id}, types::{Field, U16, U64}, }; -use ledger_block::{Deployment, Execution, Fee, Input, Transition}; -use ledger_store::{atomic_batch_scope, FinalizeStorage, FinalizeStore}; +use ledger_block::{Deployment, Execution, Fee, Input, Output, Transition}; +use ledger_store::{FinalizeStorage, FinalizeStore, atomic_batch_scope}; use synthesizer_program::{ Branch, Closure, @@ -155,7 +159,12 @@ impl Process { for function_name in program.functions().keys() { // Load the verifying key. let verifying_key = N::get_credits_verifying_key(function_name.to_string())?; - stack.insert_verifying_key(function_name, VerifyingKey::new(verifying_key.clone()))?; + // Retrieve the number of public and private variables. + // Note: This number does *NOT* include the number of constants. This is safe because + // this program is never deployed, as it is a first-class citizen of the protocol. + let num_variables = verifying_key.circuit_info.num_public_and_private_variables as u64; + // Insert the verifying key. + stack.insert_verifying_key(function_name, VerifyingKey::new(verifying_key.clone(), num_variables))?; lap!(timer, "Load verifying key for {function_name}"); } lap!(timer, "Load circuit keys"); @@ -280,20 +289,58 @@ impl Process { } } -#[cfg(any(test, feature = "test"))] +#[cfg(test)] pub mod test_helpers { use super::*; - use console::{account::PrivateKey, network::Testnet3, program::Identifier}; + use console::{account::PrivateKey, network::MainnetV0, program::Identifier}; use ledger_block::Transition; use ledger_query::Query; - use ledger_store::{helpers::memory::BlockMemory, BlockStore}; + use ledger_store::{BlockStore, helpers::memory::BlockMemory}; use synthesizer_program::Program; use once_cell::sync::OnceCell; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; type CurrentAleo = circuit::network::AleoV0; + /// Returns an execution for the given program and function name. + pub fn get_execution( + process: &mut Process, + program: &Program, + function_name: &Identifier, + inputs: impl ExactSizeIterator>>, + ) -> Execution { + // Initialize a new rng. + let rng = &mut TestRng::default(); + + // Initialize a private key. + let private_key = PrivateKey::new(rng).unwrap(); + + // Add the program to the process if doesn't yet exist. + if !process.contains_program(program.id()) { + process.add_program(program).unwrap(); + } + + // Compute the authorization. + let authorization = + process.authorize::(&private_key, program.id(), function_name, inputs, rng).unwrap(); + + // Execute the program. + let (_, mut trace) = process.execute::(authorization, rng).unwrap(); + + // Initialize a new block store. + let block_store = BlockStore::>::open(None).unwrap(); + + // Prepare the assignments from the block store. + trace.prepare(ledger_query::Query::from(block_store)).unwrap(); + + // Get the locator. + let locator = format!("{:?}:{function_name:?}", program.id()); + + // Return the execution object. + trace.prove_execution::(&locator, rng).unwrap() + } + pub fn sample_key() -> (Identifier, ProvingKey, VerifyingKey) { static INSTANCE: OnceCell<( Identifier, diff --git a/synthesizer/process/src/stack/authorization/bytes.rs b/synthesizer/process/src/stack/authorization/bytes.rs index d9caf4dfea..a8b7154919 100644 --- a/synthesizer/process/src/stack/authorization/bytes.rs +++ b/synthesizer/process/src/stack/authorization/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/stack/authorization/mod.rs b/synthesizer/process/src/stack/authorization/mod.rs index ec1df28e24..b7aa4b9669 100644 --- a/synthesizer/process/src/stack/authorization/mod.rs +++ b/synthesizer/process/src/stack/authorization/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -120,7 +121,7 @@ impl Authorization { impl Authorization { /// Returns the next `Request` in the authorization. pub fn peek_next(&self) -> Result> { - self.requests.read().get(0).cloned().ok_or_else(|| anyhow!("Failed to peek at the next request.")) + self.requests.read().front().cloned().ok_or_else(|| anyhow!("Failed to peek at the next request.")) } /// Returns the next `Request` from the authorization. @@ -238,6 +239,13 @@ fn ensure_request_and_transition_matches( request.tcm(), transition.tcm(), ); + // Ensure the request and transition have the same 'scm'. + ensure!( + request.scm() == transition.scm(), + "The request ({}) and transition ({}) at index {index} must have the same 'scm' in the authorization.", + request.scm(), + transition.scm(), + ); Ok(()) } @@ -247,7 +255,7 @@ pub(crate) mod test_helpers { use crate::Process; use console::account::PrivateKey; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; type CurrentAleo = circuit::AleoV0; /// Returns a sample authorization. diff --git a/synthesizer/process/src/stack/authorization/serialize.rs b/synthesizer/process/src/stack/authorization/serialize.rs index a2544427ed..04134381f2 100644 --- a/synthesizer/process/src/stack/authorization/serialize.rs +++ b/synthesizer/process/src/stack/authorization/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/stack/authorization/string.rs b/synthesizer/process/src/stack/authorization/string.rs index 9e85b03ca8..5e2b8fc514 100644 --- a/synthesizer/process/src/stack/authorization/string.rs +++ b/synthesizer/process/src/stack/authorization/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/stack/authorize.rs b/synthesizer/process/src/stack/authorize.rs index 5cc289c185..1e9c55403e 100644 --- a/synthesizer/process/src/stack/authorize.rs +++ b/synthesizer/process/src/stack/authorize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -33,16 +34,23 @@ impl Stack { // Retrieve the input types. let input_types = self.get_function(&function_name)?.input_types(); lap!(timer, "Retrieve the input types"); + // Set is_root to true. + let is_root = true; + // This is the root request and does not have a caller. + let caller = None; + // This is the root request and we do not have a root_tvk to pass on. + let root_tvk = None; // Compute the request. - let request = Request::sign(private_key, program_id, function_name, inputs, &input_types, rng)?; + let request = + Request::sign(private_key, program_id, function_name, inputs, &input_types, root_tvk, is_root, rng)?; lap!(timer, "Compute the request"); // Initialize the authorization. let authorization = Authorization::new(request.clone()); // Construct the call stack. let call_stack = CallStack::Authorize(vec![request], *private_key, authorization.clone()); // Construct the authorization from the function. - let _response = self.execute_function::(call_stack, None, rng)?; + let _response = self.execute_function::(call_stack, caller, root_tvk, rng)?; finish!(timer, "Construct the authorization from the function"); // Return the authorization. diff --git a/synthesizer/process/src/stack/call/mod.rs b/synthesizer/process/src/stack/call/mod.rs index 30f0a03506..d5f1a805c9 100644 --- a/synthesizer/process/src/stack/call/mod.rs +++ b/synthesizer/process/src/stack/call/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{stack::Address, CallStack, Registers, RegistersCall, StackEvaluate, StackExecute}; +use crate::{CallStack, Registers, RegistersCall, StackEvaluate, StackExecute, stack::Address}; use aleo_std::prelude::{finish, lap, timer}; use console::{ account::Field, @@ -47,6 +48,7 @@ pub trait CallTrait { stack: &(impl StackEvaluate + StackExecute + StackMatches + StackProgram), registers: &mut ( impl RegistersCall + + RegistersSigner + RegistersSignerCircuit + RegistersLoadCircuit + RegistersStoreCircuit @@ -139,6 +141,7 @@ impl CallTrait for Call { stack: &(impl StackEvaluate + StackExecute + StackMatches + StackProgram), registers: &mut ( impl RegistersCall + + RegistersSigner + RegistersSignerCircuit + RegistersLoadCircuit + RegistersStoreCircuit @@ -181,6 +184,9 @@ impl CallTrait for Call { }; lap!(timer, "Retrieve the substack and resource"); + // If we are not handling the root request, retrieve the root request's tvk + let root_tvk = registers.root_tvk().ok(); + // If the operator is a closure, retrieve the closure and compute the output. let outputs = if let Ok(closure) = substack.program().get_closure(resource) { lap!(timer, "Execute the closure"); @@ -207,6 +213,9 @@ impl CallTrait for Call { // Retrieve the number of public variables in the circuit. let num_public = A::num_public(); + // Indicate that external calls are never a root request. + let is_root = false; + use circuit::Eject; // Eject the existing circuit. let r1cs = A::eject_r1cs_and_reset(); @@ -228,6 +237,8 @@ impl CallTrait for Call { *function.name(), inputs.iter(), &function.input_types(), + root_tvk, + is_root, rng, )?; @@ -240,7 +251,7 @@ impl CallTrait for Call { authorization.push(request.clone()); // Execute the request. - let response = substack.execute_function::(call_stack, console_caller, rng)?; + let response = substack.execute_function::(call_stack, console_caller, root_tvk, rng)?; // Return the request and response. (request, response) @@ -253,6 +264,8 @@ impl CallTrait for Call { *function.name(), inputs.iter(), &function.input_types(), + root_tvk, + is_root, rng, )?; @@ -262,7 +275,7 @@ impl CallTrait for Call { call_stack.push(request.clone())?; // Evaluate the request. - let response = substack.execute_function::(call_stack, console_caller, rng)?; + let response = substack.execute_function::(call_stack, console_caller, root_tvk, rng)?; // Return the request and response. (request, response) @@ -275,6 +288,8 @@ impl CallTrait for Call { *function.name(), inputs.iter(), &function.input_types(), + root_tvk, + is_root, rng, )?; @@ -350,7 +365,7 @@ impl CallTrait for Call { substack.evaluate_function::(registers.call_stack().replicate(), console_caller)?; // Execute the request. let response = - substack.execute_function::(registers.call_stack(), console_caller, rng)?; + substack.execute_function::(registers.call_stack(), console_caller, root_tvk, rng)?; // Ensure the values are equal. if console_response.outputs() != response.outputs() { #[cfg(debug_assertions)] @@ -390,7 +405,7 @@ impl CallTrait for Call { // Compute the transition commitment as `Hash(tvk)`. let candidate_tcm = A::hash_psd2(&[tvk.clone()]); // Ensure the transition commitment matches the computed transition commitment. - A::assert_eq(&tcm, &candidate_tcm); + A::assert_eq(&tcm, candidate_tcm); // Inject the input IDs (from the request) as `Mode::Public`. let input_ids = request .input_ids() diff --git a/synthesizer/process/src/stack/deploy.rs b/synthesizer/process/src/stack/deploy.rs index 39b46f2f6f..19de63e11b 100644 --- a/synthesizer/process/src/stack/deploy.rs +++ b/synthesizer/process/src/stack/deploy.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use super::*; -use rand::{rngs::StdRng, SeedableRng}; +use rand::{SeedableRng, rngs::StdRng}; impl Stack { /// Deploys the given program ID, if it does not exist. @@ -73,11 +74,36 @@ impl Stack { let program_id = self.program.id(); + // Check that the number of combined variables does not exceed the deployment limit. + ensure!(deployment.num_combined_variables()? <= N::MAX_DEPLOYMENT_VARIABLES); + // Check that the number of combined constraints does not exceed the deployment limit. + ensure!(deployment.num_combined_constraints()? <= N::MAX_DEPLOYMENT_CONSTRAINTS); + // Construct the call stacks and assignments used to verify the certificates. let mut call_stacks = Vec::with_capacity(deployment.verifying_keys().len()); + // The `root_tvk` is `None` when verifying the deployment of an individual circuit. + let root_tvk = None; + + // The `caller` is `None` when verifying the deployment of an individual circuit. + let caller = None; + + // Check that the number of functions matches the number of verifying keys. + ensure!( + deployment.program().functions().len() == deployment.verifying_keys().len(), + "The number of functions in the program does not match the number of verifying keys" + ); + + // Create a seeded rng to use for input value and sub-stack generation. + // This is needed to ensure that the verification results of deployments are consistent across all parties, + // because currently there is a possible flakiness due to overflows in Field to Scalar casting. + let seed = u64::from_bytes_le(&deployment.to_deployment_id()?.to_bytes_le()?[0..8])?; + let mut seeded_rng = rand_chacha::ChaChaRng::seed_from_u64(seed); + // Iterate through the program functions and construct the callstacks and corresponding assignments. - for function in deployment.program().functions().values() { + for (function, (_, (verifying_key, _))) in + deployment.program().functions().values().zip_eq(deployment.verifying_keys()) + { // Initialize a burner private key. let burner_private_key = PrivateKey::new(rng)?; // Compute the burner address. @@ -92,12 +118,14 @@ impl Stack { // Retrieve the external stack. let stack = self.get_external_stack(locator.program_id())?; // Sample the input. - stack.sample_value(&burner_address, &ValueType::Record(*locator.resource()), rng) + stack.sample_value(&burner_address, &ValueType::Record(*locator.resource()), &mut seeded_rng) } - _ => self.sample_value(&burner_address, input_type, rng), + _ => self.sample_value(&burner_address, input_type, &mut seeded_rng), }) .collect::>>()?; lap!(timer, "Sample the inputs"); + // Sample 'is_root'. + let is_root = true; // Compute the request, with a burner private key. let request = Request::sign( @@ -106,23 +134,38 @@ impl Stack { *function.name(), inputs.into_iter(), &input_types, + root_tvk, + is_root, rng, )?; lap!(timer, "Compute the request for {}", function.name()); // Initialize the assignments. let assignments = Assignments::::default(); + // Initialize the constraint limit. Account for the constraint added after synthesis that makes the Varuna zerocheck hiding. + let Some(constraint_limit) = verifying_key.circuit_info.num_constraints.checked_sub(1) else { + // Since a deployment must always pay non-zero fee, it must always have at least one constraint. + bail!("The constraint limit of 0 for function '{}' is invalid", function.name()); + }; + // Retrieve the variable limit. + let variable_limit = verifying_key.num_variables(); // Initialize the call stack. - let call_stack = CallStack::CheckDeployment(vec![request], burner_private_key, assignments.clone()); + let call_stack = CallStack::CheckDeployment( + vec![request], + burner_private_key, + assignments.clone(), + Some(constraint_limit as u64), + Some(variable_limit), + ); // Append the function name, callstack, and assignments. call_stacks.push((function.name(), call_stack, assignments)); } // Verify the certificates. - let rngs = (0..call_stacks.len()).map(|_| StdRng::from_seed(rng.gen())).collect::>(); - cfg_iter!(call_stacks).zip_eq(deployment.verifying_keys()).zip_eq(rngs).try_for_each( + let rngs = (0..call_stacks.len()).map(|_| StdRng::from_seed(seeded_rng.gen())).collect::>(); + cfg_into_iter!(call_stacks).zip_eq(deployment.verifying_keys()).zip_eq(rngs).try_for_each( |(((function_name, call_stack, assignments), (_, (verifying_key, certificate))), mut rng)| { // Synthesize the circuit. - if let Err(err) = self.execute_function::(call_stack.clone(), None, &mut rng) { + if let Err(err) = self.execute_function::(call_stack, caller, root_tvk, &mut rng) { bail!("Failed to synthesize the circuit for '{function_name}': {err}") } // Check the certificate. diff --git a/synthesizer/process/src/stack/evaluate.rs b/synthesizer/process/src/stack/evaluate.rs index 9dda9b6db2..507743b54f 100644 --- a/synthesizer/process/src/stack/evaluate.rs +++ b/synthesizer/process/src/stack/evaluate.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -82,6 +83,8 @@ impl StackEvaluate for Stack { Operand::Caller => Ok(Value::Plaintext(Plaintext::from(Literal::Address(registers.caller()?)))), // If the operand is the block height, throw an error. Operand::BlockHeight => bail!("Cannot retrieve the block height from a closure scope."), + // If the operand is the network id, throw an error. + Operand::NetworkID => bail!("Cannot retrieve the network ID from a closure scope."), } }) .collect(); @@ -132,11 +135,11 @@ impl StackEvaluate for Stack { let function = self.get_function(request.function_name())?; let inputs = request.inputs(); let signer = *request.signer(); - let caller = match caller { + let (is_root, caller) = match caller { // If a caller is provided, then this is an evaluation of a child function. - Some(caller) => caller.to_address()?, + Some(caller) => (false, caller.to_address()?), // If no caller is provided, then this is an evaluation of a top-level function. - None => signer, + None => (true, signer), }; let tvk = *request.tvk(); @@ -163,7 +166,7 @@ impl StackEvaluate for Stack { lap!(timer, "Initialize the registers"); // Ensure the request is well-formed. - ensure!(request.verify(&function.input_types()), "Request is invalid"); + ensure!(request.verify(&function.input_types(), is_root), "Request is invalid"); lap!(timer, "Verify the request"); // Store the inputs. @@ -213,6 +216,8 @@ impl StackEvaluate for Stack { Operand::Caller => Ok(Value::Plaintext(Plaintext::from(Literal::Address(registers.caller()?)))), // If the operand is the block height, throw an error. Operand::BlockHeight => bail!("Cannot retrieve the block height from a function scope."), + // If the operand is the network id, throw an error. + Operand::NetworkID => bail!("Cannot retrieve the network ID from a function scope."), } }) .collect::>>()?; diff --git a/synthesizer/process/src/stack/execute.rs b/synthesizer/process/src/stack/execute.rs index 20758e5e84..f0e18ef114 100644 --- a/synthesizer/process/src/stack/execute.rs +++ b/synthesizer/process/src/stack/execute.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -115,6 +116,10 @@ impl StackExecute for Stack { Operand::BlockHeight => { bail!("Illegal operation: cannot retrieve the block height in a closure scope") } + // If the operand is the network id, throw an error. + Operand::NetworkID => { + bail!("Illegal operation: cannot retrieve the network id in a closure scope") + } } }) .collect(); @@ -135,13 +140,23 @@ impl StackExecute for Stack { &self, mut call_stack: CallStack, console_caller: Option>, + root_tvk: Option>, rng: &mut R, ) -> Result> { let timer = timer!("Stack::execute_function"); + // Ensure the global constants for the Aleo environment are initialized. + A::initialize_global_constants(); // Ensure the circuit environment is clean. A::reset(); + // If in 'CheckDeployment' mode, set the constraint limit and variable limit. + // We do not have to reset it after function calls because `CheckDeployment` mode does not execute those. + if let CallStack::CheckDeployment(_, _, _, constraint_limit, variable_limit) = &call_stack { + A::set_constraint_limit(*constraint_limit); + A::set_variable_limit(*variable_limit); + } + // Retrieve the next request. let console_request = call_stack.pop()?; @@ -153,6 +168,8 @@ impl StackExecute for Stack { console_request.network_id() ); + // We can only have a root_tvk if this request was called by another request + ensure!(console_caller.is_some() == root_tvk.is_some()); // Determine if this is the top-level caller. let console_is_root = console_caller.is_none(); @@ -188,12 +205,24 @@ impl StackExecute for Stack { lap!(timer, "Verify the input types"); // Ensure the request is well-formed. - ensure!(console_request.verify(&input_types), "Request is invalid"); + ensure!(console_request.verify(&input_types, console_is_root), "Request is invalid"); lap!(timer, "Verify the console request"); // Initialize the registers. let mut registers = Registers::new(call_stack, self.get_register_types(function.name())?.clone()); + // Set the root tvk, from a parent request or the current request. + // inject the `root_tvk` as `Mode::Private`. + if let Some(root_tvk) = root_tvk { + registers.set_root_tvk(root_tvk); + registers.set_root_tvk_circuit(circuit::Field::::new(circuit::Mode::Private, root_tvk)); + } else { + registers.set_root_tvk(*console_request.tvk()); + registers.set_root_tvk_circuit(circuit::Field::::new(circuit::Mode::Private, *console_request.tvk())); + } + + let root_tvk = Some(registers.root_tvk_circuit()?); + use circuit::{Eject, Inject}; // Inject the transition public key `tpk` as `Mode::Public`. @@ -209,7 +238,7 @@ impl StackExecute for Stack { let caller = Ternary::ternary(&is_root, request.signer(), &parent); // Ensure the request has a valid signature, inputs, and transition view key. - A::assert(request.verify(&input_types, &tpk)); + A::assert(request.verify(&input_types, &tpk, root_tvk, is_root)); lap!(timer, "Verify the circuit request"); // Set the transition signer. @@ -322,6 +351,10 @@ impl StackExecute for Stack { Operand::BlockHeight => { bail!("Illegal operation: cannot retrieve the block height in a function scope") } + // If the operand is the network id, throw an error. + Operand::NetworkID => { + bail!("Illegal operation: cannot retrieve the network id in a function scope") + } } }) .collect::>>()?; @@ -397,9 +430,7 @@ impl StackExecute for Stack { let assignment = A::eject_assignment_and_reset(); // If the circuit is in `Synthesize` or `Execute` mode, synthesize the circuit key, if it does not exist. - if matches!(registers.call_stack(), CallStack::Synthesize(..)) - || matches!(registers.call_stack(), CallStack::Execute(..)) - { + if matches!(registers.call_stack(), CallStack::Synthesize(..) | CallStack::Execute(..)) { // If the proving key does not exist, then synthesize it. if !self.contains_proving_key(function.name()) { // Add the circuit key to the mapping. @@ -416,7 +447,7 @@ impl StackExecute for Stack { lap!(timer, "Save the transition"); } // If the circuit is in `CheckDeployment` mode, then save the assignment. - else if let CallStack::CheckDeployment(_, _, ref assignments) = registers.call_stack() { + else if let CallStack::CheckDeployment(_, _, ref assignments, _, _) = registers.call_stack() { // Construct the call metrics. let metrics = CallMetrics { program_id: *self.program_id(), diff --git a/synthesizer/process/src/stack/finalize_registers/load.rs b/synthesizer/process/src/stack/finalize_registers/load.rs index 1a0c1bd4a2..ad6f800f45 100644 --- a/synthesizer/process/src/stack/finalize_registers/load.rs +++ b/synthesizer/process/src/stack/finalize_registers/load.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -41,6 +42,10 @@ impl RegistersLoad for FinalizeRegisters { Operand::BlockHeight => { return Ok(Value::Plaintext(Plaintext::from(Literal::U32(U32::new(self.state.block_height()))))); } + // If the operand is the network ID, load the network ID. + Operand::NetworkID => { + return Ok(Value::Plaintext(Plaintext::from(Literal::U16(U16::new(N::ID))))); + } }; // Retrieve the value. diff --git a/synthesizer/process/src/stack/finalize_registers/mod.rs b/synthesizer/process/src/stack/finalize_registers/mod.rs index cde50b24ec..ccc02fd42d 100644 --- a/synthesizer/process/src/stack/finalize_registers/mod.rs +++ b/synthesizer/process/src/stack/finalize_registers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,7 +20,7 @@ use crate::FinalizeTypes; use console::{ network::prelude::*, program::{Identifier, Literal, Plaintext, Register, Value}, - types::U32, + types::{U16, U32}, }; use synthesizer_program::{ FinalizeGlobalState, diff --git a/synthesizer/process/src/stack/finalize_registers/store.rs b/synthesizer/process/src/stack/finalize_registers/store.rs index e2eefcc7f2..4af3f55821 100644 --- a/synthesizer/process/src/stack/finalize_registers/store.rs +++ b/synthesizer/process/src/stack/finalize_registers/store.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/stack/finalize_types/initialize.rs b/synthesizer/process/src/stack/finalize_types/initialize.rs index e36fe3d552..dfb9ad2dc1 100644 --- a/synthesizer/process/src/stack/finalize_types/initialize.rs +++ b/synthesizer/process/src/stack/finalize_types/initialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,24 +14,16 @@ // limitations under the License. use super::*; -use crate::RegisterTypes; -use synthesizer_program::{ - Await, - Branch, - CastType, - Contains, - Get, - GetOrUse, - MappingLocator, - RandChaCha, - Remove, - Set, - MAX_ADDITIONAL_SEEDS, -}; impl FinalizeTypes { /// Initializes a new instance of `FinalizeTypes` for the given finalize. /// Checks that the given finalize is well-formed for the given stack. + /// + /// Attention: To support user-defined ordering for awaiting on futures, this method does **not** check + /// that all input futures are awaited **exactly** once. It does however check that all input + /// futures are awaited at least once. This means that it is possible to deploy a program + /// whose finalize is not well-formed, but it is not possible to execute a program whose finalize + /// is not well-formed. #[inline] pub(super) fn initialize_finalize_types( stack: &(impl StackMatches + StackProgram), @@ -53,31 +46,33 @@ impl FinalizeTypes { } } - // Initialize a list of consumed futures. - let mut consumed_futures = Vec::new(); + // Initialize the set of consumed futures. + let mut consumed_futures = HashSet::new(); - // Step 2. Check the commands are well-formed. Store the futures consumed by the `await` commands. + // Step 2. Check the commands are well-formed. Make sure all the input futures are awaited. for command in finalize.commands() { // Check the command opcode, operands, and destinations. finalize_types.check_command(stack, finalize, command)?; - // If the command is an `await`, add the future to the list of consumed futures. + // If the command is an `await`, add the future to the set of consumed futures. if let Command::Await(await_) = command { // Note: `check_command` ensures that the register is a future. This is an additional check. let locator = match finalize_types.get_type(stack, await_.register())? { FinalizeType::Future(locator) => locator, FinalizeType::Plaintext(..) => bail!("Expected a future in '{await_}'"), }; - consumed_futures.push((await_.register(), locator)); + consumed_futures.insert((await_.register(), locator)); } } - // Check that the input futures are consumed in the order they are passed in. - ensure!( - input_futures == consumed_futures, - "Futures in finalize '{}' are not awaited in the order they are passed in.", - finalize.name() - ); + // Check that all input futures are consumed. + for input_future in &input_futures { + ensure!( + consumed_futures.contains(input_future), + "Futures in finalize '{}' are not all awaited.", + finalize.name() + ) + } Ok(finalize_types) } @@ -174,7 +169,7 @@ impl FinalizeTypes { match command { Command::Instruction(instruction) => self.check_instruction(stack, finalize.name(), instruction)?, Command::Await(await_) => self.check_await(stack, await_)?, - Command::Contains(contains) => self.check_contains(stack, finalize.name(), contains)?, + Command::Contains(contains) => self.check_contains(stack, contains)?, Command::Get(get) => self.check_get(stack, get)?, Command::GetOrUse(get_or_use) => self.check_get_or_use(stack, get_or_use)?, Command::RandChaCha(rand_chacha) => self.check_rand_chacha(stack, finalize.name(), rand_chacha)?, @@ -252,16 +247,43 @@ impl FinalizeTypes { fn check_contains( &mut self, stack: &(impl StackMatches + StackProgram), - finalize_name: &Identifier, contains: &Contains, ) -> Result<()> { - // Ensure the declared mapping in `contains` is defined in the program. - if !stack.program().contains_mapping(contains.mapping_name()) { - bail!("Mapping '{}' in '{}/{finalize_name}' is not defined.", contains.mapping_name(), stack.program_id()) - } - // Retrieve the mapping from the program. - // Note that the unwrap is safe, as we have already checked the mapping exists. - let mapping = stack.program().get_mapping(contains.mapping_name()).unwrap(); + // Retrieve the mapping. + let mapping = match contains.mapping() { + CallOperator::Locator(locator) => { + // Retrieve the program ID. + let program_id = locator.program_id(); + // Retrieve the mapping_name. + let mapping_name = locator.resource(); + + // Ensure the locator does not reference the current program. + if stack.program_id() == program_id { + bail!("Locator '{locator}' does not reference an external mapping."); + } + // Ensure the current program contains an import for this external program. + if !stack.program().imports().keys().contains(program_id) { + bail!("External program '{program_id}' is not imported by '{}'.", stack.program_id()); + } + // Retrieve the program. + let external = stack.get_external_program(program_id)?; + // Ensure the mapping exists in the program. + if !external.contains_mapping(mapping_name) { + bail!("Mapping '{mapping_name}' in '{program_id}' is not defined.") + } + // Retrieve the mapping from the program. + external.get_mapping(mapping_name)? + } + CallOperator::Resource(mapping_name) => { + // Ensure the declared mapping in `contains` is defined in the current program. + if !stack.program().contains_mapping(mapping_name) { + bail!("Mapping '{mapping_name}' in '{}' is not defined.", stack.program_id()) + } + // Retrieve the mapping from the program. + stack.program().get_mapping(mapping_name)? + } + }; + // Get the mapping key type. let mapping_key_type = mapping.key().plaintext_type(); // Retrieve the register type of the key. @@ -291,7 +313,7 @@ impl FinalizeTypes { fn check_get(&mut self, stack: &(impl StackMatches + StackProgram), get: &Get) -> Result<()> { // Retrieve the mapping. let mapping = match get.mapping() { - MappingLocator::Locator(locator) => { + CallOperator::Locator(locator) => { // Retrieve the program ID. let program_id = locator.program_id(); // Retrieve the mapping_name. @@ -314,7 +336,7 @@ impl FinalizeTypes { // Retrieve the mapping from the program. external.get_mapping(mapping_name)? } - MappingLocator::Resource(mapping_name) => { + CallOperator::Resource(mapping_name) => { // Ensure the declared mapping in `get` is defined in the current program. if !stack.program().contains_mapping(mapping_name) { bail!("Mapping '{mapping_name}' in '{}' is not defined.", stack.program_id()) @@ -357,7 +379,7 @@ impl FinalizeTypes { ) -> Result<()> { // Retrieve the mapping. let mapping = match get_or_use.mapping() { - MappingLocator::Locator(locator) => { + CallOperator::Locator(locator) => { // Retrieve the program ID. let program_id = locator.program_id(); // Retrieve the mapping_name. @@ -380,7 +402,7 @@ impl FinalizeTypes { // Retrieve the mapping from the program. external.get_mapping(mapping_name)? } - MappingLocator::Resource(mapping_name) => { + CallOperator::Resource(mapping_name) => { // Ensure the declared mapping in `get.or_use` is defined in the current program. if !stack.program().contains_mapping(mapping_name) { bail!("Mapping '{mapping_name}' in '{}' is not defined.", stack.program_id()) @@ -660,7 +682,27 @@ impl FinalizeTypes { } } } - "cast.lossy" => bail!("Instruction '{instruction}' is not supported yet."), + "cast.lossy" => { + // Retrieve the cast operation. + let operation = match instruction { + Instruction::CastLossy(operation) => operation, + _ => bail!("Instruction '{instruction}' is not a cast.lossy operation."), + }; + + // Ensure the instruction has one destination register. + ensure!( + instruction.destinations().len() == 1, + "Instruction '{instruction}' has multiple destinations." + ); + + // Ensure the casted register type is valid and defined. + match operation.cast_type() { + CastType::Plaintext(PlaintextType::Literal(_)) => { + ensure!(instruction.operands().len() == 1, "Expected 1 operand."); + } + _ => bail!("`cast.lossy` is only supported for casting to a literal type."), + } + } _ => bail!("Instruction '{instruction}' is not for opcode '{opcode}'."), }, Opcode::Command(opcode) => { diff --git a/synthesizer/process/src/stack/finalize_types/matches.rs b/synthesizer/process/src/stack/finalize_types/matches.rs index 5e01d2449b..0c18d430ac 100644 --- a/synthesizer/process/src/stack/finalize_types/matches.rs +++ b/synthesizer/process/src/stack/finalize_types/matches.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -96,6 +97,16 @@ impl FinalizeTypes { "Struct member '{struct_name}.{member_name}' expects {member_type}, but found '{block_height_type}' in the operand '{operand}'.", ) } + // Ensure the network ID type (u16) matches the member type. + Operand::NetworkID => { + // Retrieve the network ID type. + let network_id_type = PlaintextType::Literal(LiteralType::U16); + // Ensure the network ID type matches the member type. + ensure!( + &network_id_type == member_type, + "Struct member '{struct_name}.{member_name}' expects {member_type}, but found '{network_id_type}' in the operand '{operand}'.", + ) + } } } Ok(()) @@ -177,6 +188,17 @@ impl FinalizeTypes { array_type.next_element_type() ) } + // Ensure the network ID type (u16) matches the member type. + Operand::NetworkID => { + // Retrieve the network ID type. + let network_id_type = PlaintextType::Literal(LiteralType::U16); + // Ensure the network ID type matches the member type. + ensure!( + &network_id_type == array_type.next_element_type(), + "Array element expects {}, but found '{network_id_type}' in the operand '{operand}'.", + array_type.next_element_type() + ) + } } } Ok(()) diff --git a/synthesizer/process/src/stack/finalize_types/mod.rs b/synthesizer/process/src/stack/finalize_types/mod.rs index 349423351d..d2563f4a71 100644 --- a/synthesizer/process/src/stack/finalize_types/mod.rs +++ b/synthesizer/process/src/stack/finalize_types/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,24 +16,48 @@ mod initialize; mod matches; +use crate::RegisterTypes; + use console::{ network::prelude::*, - program::{ArrayType, Identifier, LiteralType, PlaintextType, Register, RegisterType, StructType}, + program::{ + Access, + ArrayType, + FinalizeType, + Identifier, + LiteralType, + Locator, + PlaintextType, + Register, + RegisterType, + StructType, + }, }; use synthesizer_program::{ + Await, + Branch, + CallOperator, + CastType, Command, + Contains, Finalize, + Get, + GetOrUse, Instruction, InstructionTrait, + MAX_ADDITIONAL_SEEDS, Opcode, Operand, Program, + RandChaCha, + Remove, + Set, StackMatches, StackProgram, }; -use console::program::{Access, FinalizeType, Locator}; use indexmap::IndexMap; +use std::collections::HashSet; #[derive(Clone, Default, PartialEq, Eq)] pub struct FinalizeTypes { @@ -79,6 +104,7 @@ impl FinalizeTypes { Operand::Signer => bail!("'self.signer' is not a valid operand in a finalize context."), Operand::Caller => bail!("'self.caller' is not a valid operand in a finalize context."), Operand::BlockHeight => FinalizeType::Plaintext(PlaintextType::Literal(LiteralType::U32)), + Operand::NetworkID => FinalizeType::Plaintext(PlaintextType::Literal(LiteralType::U16)), }) } diff --git a/synthesizer/process/src/stack/helpers/initialize.rs b/synthesizer/process/src/stack/helpers/initialize.rs index 46b6bd2465..4353733ead 100644 --- a/synthesizer/process/src/stack/helpers/initialize.rs +++ b/synthesizer/process/src/stack/helpers/initialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -27,9 +28,12 @@ impl Stack { universal_srs: process.universal_srs().clone(), proving_keys: Default::default(), verifying_keys: Default::default(), + number_of_calls: Default::default(), + finalize_costs: Default::default(), + program_depth: 0, }; - // Add all of the imports into the stack. + // Add all the imports into the stack. for import in program.imports().keys() { // Ensure the program imports all exist in the process already. if !process.contains_program(import) { @@ -39,17 +43,60 @@ impl Stack { let external_stack = process.get_stack(import)?; // Add the external stack to the stack. stack.insert_external_stack(external_stack.clone())?; + // Update the program depth, checking that it does not exceed the maximum call depth. + stack.program_depth = std::cmp::max(stack.program_depth, external_stack.program_depth() + 1); + ensure!( + stack.program_depth <= N::MAX_PROGRAM_DEPTH, + "Program depth exceeds the maximum allowed call depth" + ); } // Add the program closures to the stack. for closure in program.closures().values() { // Add the closure to the stack. stack.insert_closure(closure)?; } + // Add the program functions to the stack. for function in program.functions().values() { // Add the function to the stack. stack.insert_function(function)?; + // Determine the number of calls for the function. + let mut num_calls = 1; + for instruction in function.instructions() { + if let Instruction::Call(call) = instruction { + // Determine if this is a function call. + if call.is_function_call(&stack)? { + // Increment by the number of calls. + num_calls += match call.operator() { + CallOperator::Locator(locator) => stack + .get_external_stack(locator.program_id())? + .get_number_of_calls(locator.resource())?, + CallOperator::Resource(resource) => stack.get_number_of_calls(resource)?, + }; + } + } + } + // Check that the number of calls does not exceed the maximum. + // Note that one transition is reserved for the fee. + ensure!( + num_calls < ledger_block::Transaction::::MAX_TRANSITIONS, + "Number of calls exceeds the maximum allowed number of transitions" + ); + // Add the number of calls to the stack. + stack.number_of_calls.insert(*function.name(), num_calls); + + // Get the finalize cost. + let finalize_cost = cost_in_microcredits_v2(&stack, function.name())?; + // Check that the finalize cost does not exceed the maximum. + ensure!( + finalize_cost <= N::TRANSACTION_SPEND_LIMIT, + "Finalize block '{}' has a cost '{finalize_cost}' which exceeds the transaction spend limit '{}'", + function.name(), + N::TRANSACTION_SPEND_LIMIT + ); + stack.finalize_costs.insert(*function.name(), finalize_cost); } + // Return the stack. Ok(stack) } @@ -109,7 +156,6 @@ impl Stack { // Add the finalize name and finalize types to the stack. self.finalize_types.insert(*name, finalize_types); } - // Return success. Ok(()) } diff --git a/synthesizer/process/src/stack/helpers/matches.rs b/synthesizer/process/src/stack/helpers/matches.rs index 4ed9a81de7..d1aa51322e 100644 --- a/synthesizer/process/src/stack/helpers/matches.rs +++ b/synthesizer/process/src/stack/helpers/matches.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/stack/helpers/mod.rs b/synthesizer/process/src/stack/helpers/mod.rs index 2b0884a4df..b5988c77b1 100644 --- a/synthesizer/process/src/stack/helpers/mod.rs +++ b/synthesizer/process/src/stack/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/stack/helpers/sample.rs b/synthesizer/process/src/stack/helpers/sample.rs index ed9eaaf9d0..b5c9ff2994 100644 --- a/synthesizer/process/src/stack/helpers/sample.rs +++ b/synthesizer/process/src/stack/helpers/sample.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/stack/helpers/synthesize.rs b/synthesizer/process/src/stack/helpers/synthesize.rs index c3530d0071..3f007fc0af 100644 --- a/synthesizer/process/src/stack/helpers/synthesize.rs +++ b/synthesizer/process/src/stack/helpers/synthesize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -49,16 +50,32 @@ impl Stack { _ => self.sample_value(&burner_address, input_type, rng), }) .collect::>>()?; + // Sample 'is_root'. + let is_root = true; + + // The `root_tvk` is `None` when deploying an individual circuit. + let root_tvk = None; + + // The caller is `None` when deploying an individual circuit. + let caller = None; // Compute the request, with a burner private key. - let request = - Request::sign(&burner_private_key, *program_id, *function_name, inputs.into_iter(), &input_types, rng)?; + let request = Request::sign( + &burner_private_key, + *program_id, + *function_name, + inputs.into_iter(), + &input_types, + root_tvk, + is_root, + rng, + )?; // Initialize the authorization. let authorization = Authorization::new(request.clone()); // Initialize the call stack. let call_stack = CallStack::Synthesize(vec![request], burner_private_key, authorization); // Synthesize the circuit. - let _response = self.execute_function::(call_stack, None, rng)?; + let _response = self.execute_function::(call_stack, caller, root_tvk, rng)?; // Ensure the proving key exists. ensure!(self.contains_proving_key(function_name), "Function '{function_name}' is missing a proving key."); diff --git a/synthesizer/process/src/stack/mod.rs b/synthesizer/process/src/stack/mod.rs index ae1a5b8f43..0161e15b16 100644 --- a/synthesizer/process/src/stack/mod.rs +++ b/synthesizer/process/src/stack/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -36,7 +37,7 @@ mod evaluate; mod execute; mod helpers; -use crate::{traits::*, CallMetrics, Process, Trace}; +use crate::{CallMetrics, Process, Trace, cost_in_microcredits_v2, traits::*}; use console::{ account::{Address, PrivateKey}, network::prelude::*, @@ -64,7 +65,7 @@ use console::{ types::{Field, Group}, }; use ledger_block::{Deployment, Transition}; -use synthesizer_program::{traits::*, CallOperator, Closure, Function, Instruction, Operand, Program}; +use synthesizer_program::{CallOperator, Closure, Function, Instruction, Operand, Program, traits::*}; use synthesizer_snark::{Certificate, ProvingKey, UniversalSRS, VerifyingKey}; use aleo_std::prelude::{finish, lap, timer}; @@ -81,7 +82,7 @@ pub type Assignments = Arc pub enum CallStack { Authorize(Vec>, PrivateKey, Authorization), Synthesize(Vec>, PrivateKey, Authorization), - CheckDeployment(Vec>, PrivateKey, Assignments), + CheckDeployment(Vec>, PrivateKey, Assignments, Option, Option), Evaluate(Authorization), Execute(Authorization, Arc>>), PackageRun(Vec>, PrivateKey, Assignments), @@ -109,11 +110,15 @@ impl CallStack { CallStack::Synthesize(requests, private_key, authorization) => { CallStack::Synthesize(requests.clone(), *private_key, authorization.replicate()) } - CallStack::CheckDeployment(requests, private_key, assignments) => CallStack::CheckDeployment( - requests.clone(), - *private_key, - Arc::new(RwLock::new(assignments.read().clone())), - ), + CallStack::CheckDeployment(requests, private_key, assignments, constraint_limit, variable_limit) => { + CallStack::CheckDeployment( + requests.clone(), + *private_key, + Arc::new(RwLock::new(assignments.read().clone())), + *constraint_limit, + *variable_limit, + ) + } CallStack::Evaluate(authorization) => CallStack::Evaluate(authorization.replicate()), CallStack::Execute(authorization, trace) => { CallStack::Execute(authorization.replicate(), Arc::new(RwLock::new(trace.read().clone()))) @@ -182,6 +187,12 @@ pub struct Stack { proving_keys: Arc, ProvingKey>>>, /// The mapping of function name to verifying key. verifying_keys: Arc, VerifyingKey>>>, + /// The mapping of function names to the number of calls. + number_of_calls: IndexMap, usize>, + /// The mapping of function names to finalize cost. + finalize_costs: IndexMap, u64>, + /// The program depth. + program_depth: usize, } impl Stack { @@ -223,6 +234,12 @@ impl StackProgram for Stack { self.program.id() } + /// Returns the program depth. + #[inline] + fn program_depth(&self) -> usize { + self.program_depth + } + /// Returns `true` if the stack contains the external record. #[inline] fn contains_external_record(&self, locator: &Locator) -> bool { @@ -261,6 +278,15 @@ impl StackProgram for Stack { external_program.get_record(locator.resource()) } + /// Returns the expected finalize cost for the given function name. + #[inline] + fn get_finalize_cost(&self, function_name: &Identifier) -> Result { + self.finalize_costs + .get(function_name) + .copied() + .ok_or_else(|| anyhow!("Function '{function_name}' does not exist")) + } + /// Returns the function with the given function name. #[inline] fn get_function(&self, function_name: &Identifier) -> Result> { @@ -276,23 +302,10 @@ impl StackProgram for Stack { /// Returns the expected number of calls for the given function name. #[inline] fn get_number_of_calls(&self, function_name: &Identifier) -> Result { - // Determine the number of calls for this function (including the function itself). - let mut num_calls = 1; - for instruction in self.get_function(function_name)?.instructions() { - if let Instruction::Call(call) = instruction { - // Determine if this is a function call. - if call.is_function_call(self)? { - // Increment by the number of calls. - num_calls += match call.operator() { - CallOperator::Locator(locator) => { - self.get_external_stack(locator.program_id())?.get_number_of_calls(locator.resource())? - } - CallOperator::Resource(resource) => self.get_number_of_calls(resource)?, - }; - } - } - } - Ok(num_calls) + self.number_of_calls + .get(function_name) + .copied() + .ok_or_else(|| anyhow!("Function '{function_name}' does not exist")) } /// Returns a value for the given value type. diff --git a/synthesizer/process/src/stack/register_types/initialize.rs b/synthesizer/process/src/stack/register_types/initialize.rs index 7b3265a1f5..3714852a3a 100644 --- a/synthesizer/process/src/stack/register_types/initialize.rs +++ b/synthesizer/process/src/stack/register_types/initialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,6 @@ // limitations under the License. use super::*; -use synthesizer_program::CastType; impl RegisterTypes { /// Initializes a new instance of `RegisterTypes` for the given closure. @@ -158,17 +158,17 @@ impl RegisterTypes { } /* Additional checks. */ - // - All futures produces before the `async` call must be consumed by the `async` call, in the order in which they were produced. + // - All futures produces before the `async` call must be consumed by the `async` call. // Get all registers containing futures. - let mut future_registers = register_types + let mut future_registers: IndexSet<(Register, Locator)> = register_types .destinations .iter() .filter_map(|(index, register_type)| match register_type { - RegisterType::Future(locator) => Some((Register::Locator(*index), *locator)), + RegisterType::Future(locator) => Some((Register::::Locator(*index), *locator)), _ => None, }) - .collect::>(); + .collect(); match async_ { // If no `async` instruction exists, then there should not be any future registers. @@ -179,26 +179,22 @@ impl RegisterTypes { function.name() ) } - // Otherwise, check that all the registers were consumed by the `async` call, in order. + // Otherwise, check that all the registers were consumed by the `async` call. Some(async_) => { // Remove the last future, since this is the future created by the `async` call. future_registers.pop(); - // Get the register operands that are `future` types. - let async_future_operands = async_ - .operands() - .iter() - .filter_map(|operand| match operand { - Operand::Register(register) => match register_types.get_type(stack, register).ok() { - Some(RegisterType::Future(locator)) => Some((register.clone(), locator)), - _ => None, - }, - _ => None, - }) - .collect::>(); - // Ensure the future operands are in the same order as the future registers. + // Check only the register operands that are `future` types. + for operand in async_.operands() { + if let Operand::Register(register) = operand { + if let Ok(RegisterType::Future(locator)) = register_types.get_type(stack, register) { + assert!(future_registers.swap_remove(&(register.clone(), locator))); + } + } + } + // Ensure that all the futures created are consumed in the async call. ensure!( - async_future_operands == future_registers, - "Function '{}' contains futures, but the 'async' instruction does not consume all of them in the order they were produced", + future_registers.is_empty(), + "Function '{}' contains futures, but the 'async' instruction does not consume all of the ones produced.", function.name() ); } @@ -554,7 +550,27 @@ impl RegisterTypes { } } } - "cast.lossy" => bail!("Instruction '{instruction}' is not supported yet."), + "cast.lossy" => { + // Retrieve the cast operation. + let operation = match instruction { + Instruction::CastLossy(operation) => operation, + _ => bail!("Instruction '{instruction}' is not a cast.lossy operation."), + }; + + // Ensure the instruction has one destination register. + ensure!( + instruction.destinations().len() == 1, + "Instruction '{instruction}' has multiple destinations." + ); + + // Ensure the casted register type is valid and defined. + match operation.cast_type() { + CastType::Plaintext(PlaintextType::Literal(_)) => { + ensure!(instruction.operands().len() == 1, "Expected 1 operand."); + } + _ => bail!("`cast.lossy` is only supported for casting to a literal type."), + } + } _ => bail!("Instruction '{instruction}' is not for opcode '{opcode}'."), }, Opcode::Command(opcode) => { diff --git a/synthesizer/process/src/stack/register_types/matches.rs b/synthesizer/process/src/stack/register_types/matches.rs index 3957726841..0f18c91713 100644 --- a/synthesizer/process/src/stack/register_types/matches.rs +++ b/synthesizer/process/src/stack/register_types/matches.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -88,6 +89,10 @@ impl RegisterTypes { Operand::BlockHeight => bail!( "Struct member '{struct_name}.{member_name}' cannot be from a block height in a non-finalize scope" ), + // If the operand is a network ID type, throw an error. + Operand::NetworkID => bail!( + "Struct member '{struct_name}.{member_name}' cannot be from a network ID in a non-finalize scope" + ), } } Ok(()) @@ -162,6 +167,8 @@ impl RegisterTypes { } // If the operand is a block height type, throw an error. Operand::BlockHeight => bail!("Array element cannot be from a block height in a non-finalize scope"), + // If the operand is a network ID type, throw an error. + Operand::NetworkID => bail!("Array element cannot be from a network ID in a non-finalize scope"), } } Ok(()) @@ -224,6 +231,9 @@ impl RegisterTypes { Operand::BlockHeight => { bail!("Forbidden operation: Cannot cast a block height as a record owner") } + Operand::NetworkID => { + bail!("Forbidden operation: Cannot cast a network ID as a record owner") + } } // Ensure the operand types match the record entry types. @@ -279,6 +289,12 @@ impl RegisterTypes { "Record entry '{record_name}.{entry_name}' expects a '{plaintext_type}', but found a block height in the operand '{operand}'." ) } + // Fail if the operand is a network ID. + Operand::NetworkID => { + bail!( + "Record entry '{record_name}.{entry_name}' expects a '{plaintext_type}', but found a network ID in the operand '{operand}'." + ) + } } } } diff --git a/synthesizer/process/src/stack/register_types/mod.rs b/synthesizer/process/src/stack/register_types/mod.rs index 725adf37b0..16d7e5e59d 100644 --- a/synthesizer/process/src/stack/register_types/mod.rs +++ b/synthesizer/process/src/stack/register_types/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -33,6 +34,7 @@ use console::{ }; use synthesizer_program::{ CallOperator, + CastType, Closure, Function, Instruction, @@ -45,7 +47,7 @@ use synthesizer_program::{ }; use console::program::{FinalizeType, Locator}; -use indexmap::IndexMap; +use indexmap::{IndexMap, IndexSet}; #[derive(Clone, Default, PartialEq, Eq)] pub struct RegisterTypes { @@ -97,6 +99,7 @@ impl RegisterTypes { RegisterType::Plaintext(PlaintextType::Literal(LiteralType::Address)) } Operand::BlockHeight => bail!("'block.height' is not a valid operand in a non-finalize context."), + Operand::NetworkID => bail!("'network.id' is not a valid operand in a non-finalize context."), }) } diff --git a/synthesizer/process/src/stack/registers/call.rs b/synthesizer/process/src/stack/registers/call.rs index 185c64e408..08931035f3 100644 --- a/synthesizer/process/src/stack/registers/call.rs +++ b/synthesizer/process/src/stack/registers/call.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/stack/registers/caller.rs b/synthesizer/process/src/stack/registers/caller.rs index ddea05cdec..28f9816f8a 100644 --- a/synthesizer/process/src/stack/registers/caller.rs +++ b/synthesizer/process/src/stack/registers/caller.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -27,6 +28,18 @@ impl> RegistersSigner for Registers self.signer = Some(signer); } + /// Returns the root transition view key. + #[inline] + fn root_tvk(&self) -> Result> { + self.root_tvk.ok_or_else(|| anyhow!("Root tvk (console) is not set in the registers.")) + } + + /// Sets the root transition view key. + #[inline] + fn set_root_tvk(&mut self, root_tvk: Field) { + self.root_tvk = Some(root_tvk); + } + /// Returns the transition caller. #[inline] fn caller(&self) -> Result> { @@ -65,6 +78,18 @@ impl> RegistersSignerCircuit for self.signer_circuit = Some(signer_circuit); } + /// Returns the root transition view key, as a circuit. + #[inline] + fn root_tvk_circuit(&self) -> Result> { + self.root_tvk_circuit.clone().ok_or_else(|| anyhow!("Root tvk (circuit) is not set in the registers.")) + } + + /// Sets the root transition view key, as a circuit. + #[inline] + fn set_root_tvk_circuit(&mut self, root_tvk_circuit: circuit::Field) { + self.root_tvk_circuit = Some(root_tvk_circuit); + } + /// Returns the transition caller, as a circuit. #[inline] fn caller_circuit(&self) -> Result> { diff --git a/synthesizer/process/src/stack/registers/load.rs b/synthesizer/process/src/stack/registers/load.rs index f9e1e1f875..80cdb3c268 100644 --- a/synthesizer/process/src/stack/registers/load.rs +++ b/synthesizer/process/src/stack/registers/load.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -38,6 +39,8 @@ impl> RegistersLoad for Registers return Ok(Value::Plaintext(Plaintext::from(Literal::Address(self.caller()?)))), // If the operand is the block height, throw an error. Operand::BlockHeight => bail!("Cannot load the block height in a non-finalize context"), + // If the operand is the network ID, throw an error. + Operand::NetworkID => bail!("Cannot load the network ID in a non-finalize context"), }; // Retrieve the stack value. @@ -121,6 +124,8 @@ impl> RegistersLoadCircuit for R } // If the operand is the block height, throw an error. Operand::BlockHeight => bail!("Cannot load the block height in a non-finalize context"), + // If the operand is the network ID, throw an error. + Operand::NetworkID => bail!("Cannot load the network ID in a non-finalize context"), }; // Retrieve the circuit value. diff --git a/synthesizer/process/src/stack/registers/mod.rs b/synthesizer/process/src/stack/registers/mod.rs index 3e6af26bbc..5e1e0d249c 100644 --- a/synthesizer/process/src/stack/registers/mod.rs +++ b/synthesizer/process/src/stack/registers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -51,6 +52,10 @@ pub struct Registers> { signer: Option>, /// The transition signer, as a circuit. signer_circuit: Option>, + /// The root transition view key. + root_tvk: Option>, + /// The root transition view key, as a circuit. + root_tvk_circuit: Option>, /// The transition caller. caller: Option>, /// The transition caller, as a circuit. @@ -72,6 +77,8 @@ impl> Registers { circuit_registers: IndexMap::new(), signer: None, signer_circuit: None, + root_tvk: None, + root_tvk_circuit: None, caller: None, caller_circuit: None, tvk: None, diff --git a/synthesizer/process/src/stack/registers/store.rs b/synthesizer/process/src/stack/registers/store.rs index 96f3718c61..3728c3c5fe 100644 --- a/synthesizer/process/src/stack/registers/store.rs +++ b/synthesizer/process/src/stack/registers/store.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/tests/mod.rs b/synthesizer/process/src/tests/mod.rs index 0a1d4bbafb..342a746f9b 100644 --- a/synthesizer/process/src/tests/mod.rs +++ b/synthesizer/process/src/tests/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/tests/test_credits.rs b/synthesizer/process/src/tests/test_credits.rs index aefae59a3c..9de634854f 100644 --- a/synthesizer/process/src/tests/test_credits.rs +++ b/synthesizer/process/src/tests/test_credits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,28 +17,29 @@ use crate::Process; use circuit::network::AleoV0; use console::{ account::{Address, PrivateKey}, - network::{prelude::*, Testnet3}, + network::{MainnetV0, prelude::*}, program::{Identifier, Literal, Plaintext, ProgramID, Value}, types::U64, }; -use ledger_committee::{MIN_DELEGATOR_STAKE, MIN_VALIDATOR_STAKE}; +use ledger_committee::{MIN_DELEGATOR_STAKE, MIN_VALIDATOR_SELF_STAKE, MIN_VALIDATOR_STAKE}; use ledger_query::Query; use ledger_store::{ - atomic_finalize, - helpers::memory::{BlockMemory, FinalizeMemory}, BlockStore, FinalizeMode, FinalizeStorage, FinalizeStore, + atomic_finalize, + helpers::memory::{BlockMemory, FinalizeMemory}, }; use synthesizer_program::{FinalizeGlobalState, FinalizeStoreTrait, Program}; use indexmap::IndexMap; -type CurrentNetwork = Testnet3; +type CurrentNetwork = MainnetV0; type CurrentAleo = AleoV0; const NUM_BLOCKS_TO_UNLOCK: u32 = 360; +const TEST_COMMISSION: u8 = 5; /// Samples a new finalize store. macro_rules! sample_finalize_store { @@ -105,31 +107,54 @@ fn account_balance>( } /// Get the current committee state from the `committee` mapping for the given validator address. -/// Returns the `committee_state` as a tuple of `(microcredits, is_open)`. +/// Returns the `committee_state` as a tuple of `(microcredits, is_open, commission)`. fn committee_state>( store: &FinalizeStore, address: &Address, -) -> Result> { +) -> Result> { // Retrieve the committee state from the finalize store. - let state = match get_mapping_value(store, "credits.aleo", "committee", Literal::Address(*address))? { + let committee_state = match get_mapping_value(store, "credits.aleo", "committee", Literal::Address(*address))? { Some(Value::Plaintext(Plaintext::Struct(state, _))) => state, None => return Ok(None), _ => bail!("Malformed committee state for {address}"), }; - // Retrieve `microcredits` from the committee state. - let microcredits = match state.get(&Identifier::from_str("microcredits")?) { - Some(Plaintext::Literal(Literal::U64(microcredits), _)) => **microcredits, - _ => bail!("`microcredits` not found for: {address}"), + // Retrieve the delegated microcredits from the finalize store. + let staked_microcredits = match get_mapping_value(store, "credits.aleo", "delegated", Literal::Address(*address))? { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(microcredits), _))) => microcredits, + None => return Ok(None), + _ => bail!("Malformed delegate state for {address}"), + }; + + // Retrieve `commission` from the committee state. + let commission = match committee_state.get(&Identifier::from_str("commission")?) { + Some(Plaintext::Literal(Literal::U8(commission), _)) => **commission, + _ => bail!("`commission` not found for: {address}"), }; // Retrieve `is_open` from the committee state. - let is_open = match state.get(&Identifier::from_str("is_open")?) { + let is_open = match committee_state.get(&Identifier::from_str("is_open")?) { Some(Plaintext::Literal(Literal::Boolean(is_open), _)) => **is_open, _ => bail!("`is_open` not found for: {address}"), }; - Ok(Some((microcredits, is_open))) + Ok(Some((*staked_microcredits, is_open, commission))) +} + +/// Get the current delegated state from the `delegated` mapping for the given validator address. +/// Returns the `delegated_state` as the number of microcredits delegated to the validator. +fn delegated_state>( + store: &FinalizeStore, + address: &Address, +) -> Result> { + // Retrieve the delegated state from the finalize store. + let state = match get_mapping_value(store, "credits.aleo", "delegated", Literal::Address(*address))? { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(microcredits), _))) => microcredits, + None => return Ok(None), + _ => bail!("Malformed delegate state for {address}"), + }; + + Ok(Some(*state)) } /// Get the current bond state from the `bonding` mapping for the given staker address. @@ -188,14 +213,62 @@ fn unbond_state>( Ok(Some((microcredits, height))) } +/// Get the current withdrawal address from the `withdraw` mapping for the given staker address. +fn withdraw_state>( + store: &FinalizeStore, + address: &Address, +) -> Result>> { + // Retrieve the withdraw state from the finalize store. + let withdrawal_address = match get_mapping_value(store, "credits.aleo", "withdraw", Literal::Address(*address))? { + Some(Value::Plaintext(Plaintext::Literal(Literal::Address(withdrawal_address), _))) => withdrawal_address, + None => return Ok(None), + _ => bail!("Malformed withdraw state for {address}"), + }; + + Ok(Some(withdrawal_address)) +} + +/// Initialize an account with a given balance +fn initialize_account>( + finalize_store: &FinalizeStore, + address: &Address, + balance: u64, +) -> Result<()> { + // Initialize the store for 'credits.aleo'. + let program = Program::::credits()?; + for mapping in program.mappings().values() { + // Ensure that all mappings are initialized. + if !finalize_store.contains_mapping_confirmed(program.id(), mapping.name())? { + // Initialize the mappings for 'credits.aleo'. + finalize_store.initialize_mapping(*program.id(), *mapping.name())?; + } + } + + // Initialize the account with the given balance. + let key = Plaintext::from(Literal::Address(*address)); + let value = Value::from(Literal::U64(U64::new(balance))); + finalize_store.insert_key_value( + ProgramID::from_str("credits.aleo")?, + Identifier::from_str("account")?, + key, + value, + )?; + assert_eq!(balance, account_balance(finalize_store, address).unwrap()); + + Ok(()) +} + /// Initializes the validator and delegator balances in the finalize store. -/// Returns the private keys and balances for the validators and delegators. +/// Returns the private keys, balances, withdrawal private keys and withdrawal addresses for the validators and delegators. fn initialize_stakers>( finalize_store: &FinalizeStore, num_validators: u32, num_delegators: u32, rng: &mut TestRng, -) -> Result<(IndexMap, (Address, u64)>, IndexMap, (Address, u64)>)> { +) -> Result<( + IndexMap, (Address, u64, PrivateKey, Address)>, + IndexMap, (Address, u64)>, +)> { // Initialize the store for 'credits.aleo'. let program = Program::::credits()?; for mapping in program.mappings().values() { @@ -216,7 +289,7 @@ fn initialize_stakers>( // Initialize a new account. let private_key = PrivateKey::::new(rng)?; let address = Address::try_from(&private_key)?; - let balance = 10_000_000_000_000u64; + let balance = 100_000_000_000_000u64; // Add the balance directly to the finalize store. let key = Plaintext::from(Literal::Address(address)); @@ -226,8 +299,11 @@ fn initialize_stakers>( // Store the validator or delegator. if i < num_validators { + // Validators are required to have a different withdrawal address + let withdrawal_private_key = PrivateKey::::new(rng)?; + let withdrawal_address = Address::try_from(&withdrawal_private_key)?; // Insert the validator into the list of validators. - validators.insert(private_key, (address, balance)); + validators.insert(private_key, (address, balance, withdrawal_private_key, withdrawal_address)); } else { // Insert the delegator into the list of delegators. delegators.insert(private_key, (address, balance)); @@ -271,12 +347,34 @@ fn execute_function>( Ok(()) } +/// Perform a `bond_validator`. +fn bond_validator>( + process: &Process, + finalize_store: &FinalizeStore, + caller_private_key: &PrivateKey, + withdrawal_address: &Address, + amount: u64, + commission: u8, + rng: &mut TestRng, +) -> Result<()> { + execute_function( + process, + finalize_store, + caller_private_key, + "bond_validator", + &[withdrawal_address.to_string(), format!("{amount}_u64"), format!("{commission}_u8")], + None, + rng, + ) +} + /// Perform a `bond_public`. fn bond_public>( process: &Process, finalize_store: &FinalizeStore, caller_private_key: &PrivateKey, validator_address: &Address, + withdrawal_address: &Address, amount: u64, rng: &mut TestRng, ) -> Result<()> { @@ -285,7 +383,7 @@ fn bond_public>( finalize_store, caller_private_key, "bond_public", - &[validator_address.to_string(), format!("{amount}_u64")], + &[validator_address.to_string(), withdrawal_address.to_string(), format!("{amount}_u64")], None, rng, ) @@ -296,6 +394,7 @@ fn unbond_public>( process: &Process, finalize_store: &FinalizeStore, caller_private_key: &PrivateKey, + address: &Address, amount: u64, block_height: u32, rng: &mut TestRng, @@ -305,7 +404,7 @@ fn unbond_public>( finalize_store, caller_private_key, "unbond_public", - &[format!("{amount}_u64")], + &[address.to_string(), format!("{amount}_u64")], Some(block_height), rng, ) @@ -330,34 +429,32 @@ fn set_validator_state>( ) } -/// Perform an `unbond_delegator_as_validator` -fn unbond_delegator_as_validator>( +/// Perform a `claim_unbond_public`. +fn claim_unbond_public>( process: &Process, finalize_store: &FinalizeStore, caller_private_key: &PrivateKey, - delegator_address: &Address, + address: &Address, + block_height: u32, rng: &mut TestRng, ) -> Result<()> { execute_function( process, finalize_store, caller_private_key, - "unbond_delegator_as_validator", - &[delegator_address.to_string()], - None, + "claim_unbond_public", + &[address.to_string()], + Some(block_height), rng, ) } -/// Perform a `claim_unbond_public`. -fn claim_unbond_public>( - process: &Process, - finalize_store: &FinalizeStore, - caller_private_key: &PrivateKey, - block_height: u32, - rng: &mut TestRng, -) -> Result<()> { - execute_function(process, finalize_store, caller_private_key, "claim_unbond_public", &[], Some(block_height), rng) +#[test] +fn test_credits_program_id_simple() { + let program = Program::::credits().unwrap(); + + // Ensure that the program is correct. + assert_eq!(program.id().to_string(), "credits.aleo"); } #[test] @@ -371,7 +468,7 @@ fn test_bond_validator_simple() { // Initialize the validators. let (validators, _) = initialize_stakers(&store, 1, 0, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); // Retrieve the account balance. let public_balance = account_balance(&store, validator_address).unwrap(); @@ -381,19 +478,24 @@ fn test_bond_validator_simple() { // Sanity check the state before finalizing. assert_eq!(committee_state(&store, validator_address).unwrap(), None); + assert_eq!(delegated_state(&store, validator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), None); assert_eq!(account_balance(&store, validator_address).unwrap(), public_balance); /* Ensure bonding as a validator with the exact MIN_VALIDATOR_STAKE succeeds. */ test_atomic_finalize!(store, FinalizeMode::RealRun, { // Perform the bond. - bond_public(&process, &store, validator_private_key, validator_address, amount, rng).unwrap(); + bond_validator(&process, &store, validator_private_key, withdrawal_address, amount, TEST_COMMISSION, rng) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((amount, true))); + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!(committee_state(&store, validator_address).unwrap(), Some((amount, true, TEST_COMMISSION))); + assert_eq!(delegated_state(&store, validator_address).unwrap(), Some(amount)); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, amount))); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); // Check that the account balance is correct. assert_eq!(account_balance(&store, validator_address).unwrap(), public_balance - amount); @@ -402,12 +504,108 @@ fn test_bond_validator_simple() { .unwrap(); // Sanity check the state after finalizing. - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((amount, true))); + assert_eq!(committee_state(&store, validator_address).unwrap(), Some((amount, true, TEST_COMMISSION))); + assert_eq!(delegated_state(&store, validator_address).unwrap(), Some(amount)); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, amount))); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); assert_eq!(account_balance(&store, validator_address).unwrap(), public_balance - amount); } +#[test] +fn test_bond_public_with_minimum_bond() { + let rng = &mut TestRng::default(); + + // Construct the process. + let process = Process::::load().unwrap(); + // Initialize a new finalize store. + let (store, _temp_dir) = sample_finalize_store!(); + + // Initialize the validator and delegator keys + let validator_private_key = PrivateKey::::new(rng).unwrap(); + let validator_address = Address::try_from(&validator_private_key).unwrap(); + let withdrawal_private_key = PrivateKey::::new(rng).unwrap(); + let withdrawal_address = Address::try_from(&withdrawal_private_key).unwrap(); + let delegator_private_key = PrivateKey::::new(rng).unwrap(); + let delegator_address = Address::try_from(&delegator_private_key).unwrap(); + + // Initialize the account balances + let validator_balance = 1_000_000_000u64; // 1,000 credits + let delegator_balance = 100_000_000_000_000u64; + initialize_account(&store, &validator_address, validator_balance).unwrap(); + initialize_account(&store, &delegator_address, delegator_balance).unwrap(); + + let delegator_amount = MIN_VALIDATOR_STAKE - MIN_VALIDATOR_SELF_STAKE; + let validator_amount = MIN_VALIDATOR_SELF_STAKE; + + // Sanity check the state before finalizing. + assert_eq!(committee_state(&store, &validator_address).unwrap(), None); + assert_eq!(delegated_state(&store, &validator_address).unwrap(), None); + assert_eq!(bond_state(&store, &validator_address).unwrap(), None); + assert_eq!(unbond_state(&store, &validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, &validator_address).unwrap(), None); + assert_eq!(account_balance(&store, &validator_address).unwrap(), validator_balance); + assert_eq!(account_balance(&store, &delegator_address).unwrap(), delegator_balance); + + /* + 1. Delegator bonds to validator before validator is in the committee + 2. Validator can then bond_validator to join the committee + */ + test_atomic_finalize!(store, FinalizeMode::RealRun, { + // Perform the bond public. + bond_public( + &process, + &store, + &delegator_private_key, + &validator_address, + &delegator_address, + delegator_amount, + rng, + ) + .unwrap(); + + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!(committee_state(&store, &validator_address).unwrap(), None); + assert_eq!(delegated_state(&store, &validator_address).unwrap(), Some(delegator_amount)); + assert_eq!(bond_state(&store, &delegator_address).unwrap(), Some((validator_address, delegator_amount))); + assert_eq!(unbond_state(&store, &validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, &delegator_address).unwrap(), Some(delegator_address)); + + // Check that the account balance is correct. + assert_eq!(account_balance(&store, &delegator_address).unwrap(), delegator_balance - delegator_amount); + + // Perform the bond validator with the minimum self bond + bond_validator( + &process, + &store, + &validator_private_key, + &withdrawal_address, + validator_amount, + TEST_COMMISSION, + rng, + ) + .unwrap(); + + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!( + committee_state(&store, &validator_address).unwrap(), + Some((validator_amount + delegator_amount, true, TEST_COMMISSION)) + ); + assert_eq!(delegated_state(&store, &validator_address).unwrap(), Some(validator_amount + delegator_amount)); + assert_eq!(bond_state(&store, &delegator_address).unwrap(), Some((validator_address, delegator_amount))); + assert_eq!(unbond_state(&store, &validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, &validator_address).unwrap(), Some(withdrawal_address)); + assert_eq!(withdraw_state(&store, &delegator_address).unwrap(), Some(delegator_address)); + + // Check that the account balance is correct. + assert_eq!(account_balance(&store, &delegator_address).unwrap(), delegator_balance - delegator_amount); + assert_eq!(account_balance(&store, &validator_address).unwrap(), validator_balance - validator_amount); + + Ok(()) + }) + .unwrap(); +} + #[test] fn test_bond_validator_below_min_stake_fails() { let rng = &mut TestRng::default(); @@ -419,7 +617,7 @@ fn test_bond_validator_below_min_stake_fails() { // Initialize the validators. let (validators, _) = initialize_stakers(&store, 1, 0, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); // Retrieve the account balance. let public_balance = account_balance(&store, validator_address).unwrap(); @@ -427,13 +625,51 @@ fn test_bond_validator_below_min_stake_fails() { /* Ensure bonding as a validator below the MIN_VALIDATOR_STAKE fails. */ test_atomic_finalize!(store, FinalizeMode::RealRun, { let amount = rng.gen_range(1_000_000..MIN_VALIDATOR_STAKE); - let result = bond_public(&process, &store, validator_private_key, validator_address, amount, rng); + let result = + bond_validator(&process, &store, validator_private_key, withdrawal_address, amount, TEST_COMMISSION, rng); + assert!(result.is_err()); + + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!(committee_state(&store, validator_address).unwrap(), None); + assert_eq!(bond_state(&store, validator_address).unwrap(), None); + assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), None); + + // Check that the account balance is correct. + assert_eq!(account_balance(&store, validator_address).unwrap(), public_balance); + Ok(()) + }) + .unwrap(); +} + +#[test] +fn test_bond_validator_same_withdrawal_address_fails() { + let rng = &mut TestRng::default(); + + // Construct the process. + let process = Process::::load().unwrap(); + // Initialize a new finalize store. + let (store, _temp_dir) = sample_finalize_store!(); + + // Initialize the validators. + let (validators, _) = initialize_stakers(&store, 1, 0, rng).unwrap(); + let (validator_private_key, (validator_address, _, _, _)) = validators.first().unwrap(); + + // Retrieve the account balance. + let public_balance = account_balance(&store, validator_address).unwrap(); + + /* Ensure bonding as a validator below the MIN_VALIDATOR_STAKE fails. */ + test_atomic_finalize!(store, FinalizeMode::RealRun, { + let amount = MIN_VALIDATOR_STAKE; + let result = + bond_validator(&process, &store, validator_private_key, validator_address, amount, TEST_COMMISSION, rng); assert!(result.is_err()); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. assert_eq!(committee_state(&store, validator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), None); // Check that the account balance is correct. assert_eq!(account_balance(&store, validator_address).unwrap(), public_balance); @@ -453,7 +689,7 @@ fn test_bond_validator_with_insufficient_funds_fails() { // Initialize the validators. let (validators, _) = initialize_stakers(&store, 1, 0, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); // Retrieve the account balance. let public_balance = account_balance(&store, validator_address).unwrap(); @@ -461,13 +697,16 @@ fn test_bond_validator_with_insufficient_funds_fails() { /* Ensure bonding an amount larger than the account balance will fail. */ test_atomic_finalize!(store, FinalizeMode::RealRun, { let amount = public_balance + 1; - let result = bond_public(&process, &store, validator_private_key, validator_address, amount, rng); + let result = + bond_validator(&process, &store, validator_private_key, withdrawal_address, amount, TEST_COMMISSION, rng); assert!(result.is_err()); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. assert_eq!(committee_state(&store, validator_address).unwrap(), None); + assert_eq!(delegated_state(&store, validator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), None); // Check that the account balance is correct. assert_eq!(account_balance(&store, validator_address).unwrap(), public_balance); @@ -476,6 +715,74 @@ fn test_bond_validator_with_insufficient_funds_fails() { .unwrap(); } +#[test] +fn test_bond_validator_different_commission_fails() { + let rng = &mut TestRng::default(); + + // Construct the process. + let process = Process::::load().unwrap(); + // Initialize a new finalize store. + let (store, _temp_dir) = sample_finalize_store!(); + + // Initialize the validators. + let (validators, _) = initialize_stakers(&store, 1, 0, rng).unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); + + // Retrieve the account balance. + let public_balance = account_balance(&store, validator_address).unwrap(); + + /* Ensure that bonding additional stake succeeds. */ + test_atomic_finalize!(store, FinalizeMode::RealRun, { + /* First Bond */ + + // Perform the first bond. + let amount = MIN_VALIDATOR_STAKE; + assert!(amount < public_balance); + bond_validator(&process, &store, validator_private_key, withdrawal_address, amount, TEST_COMMISSION, rng) + .unwrap(); + + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!(committee_state(&store, validator_address).unwrap(), Some((amount, true, TEST_COMMISSION))); + assert_eq!(delegated_state(&store, validator_address).unwrap(), Some(amount)); + assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, amount))); + assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + + // Retrieve the account balance. + let public_balance_1 = account_balance(&store, validator_address).unwrap(); + assert_eq!(public_balance_1, public_balance - amount); + + /* Second Bond */ + + // Perform the second bond with a different commission + let amount = MIN_VALIDATOR_STAKE; + assert!(amount < public_balance); + let result = bond_validator( + &process, + &store, + validator_private_key, + withdrawal_address, + amount, + TEST_COMMISSION + 1, + rng, + ); + assert!(result.is_err()); + + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!(committee_state(&store, validator_address).unwrap(), Some((amount, true, TEST_COMMISSION))); + assert_eq!(delegated_state(&store, validator_address).unwrap(), Some(amount)); + assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, amount))); + assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + + // Retrieve the account balance. + let public_balance_2 = account_balance(&store, validator_address).unwrap(); + assert_eq!(public_balance_2, public_balance - amount); + Ok(()) + }) + .unwrap(); +} + #[test] fn test_bond_validator_multiple_bonds() { let rng = &mut TestRng::default(); @@ -487,7 +794,7 @@ fn test_bond_validator_multiple_bonds() { // Initialize the validators. let (validators, _) = initialize_stakers(&store, 1, 0, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); // Retrieve the account balance. let public_balance = account_balance(&store, validator_address).unwrap(); @@ -497,14 +804,17 @@ fn test_bond_validator_multiple_bonds() { /* First Bond */ // Perform the first bond. - let amount = 1_000_000_000_000u64; + let amount = MIN_VALIDATOR_STAKE; assert!(amount < public_balance); - bond_public(&process, &store, validator_private_key, validator_address, amount, rng).unwrap(); + bond_validator(&process, &store, validator_private_key, withdrawal_address, amount, TEST_COMMISSION, rng) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((amount, true))); + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!(committee_state(&store, validator_address).unwrap(), Some((amount, true, TEST_COMMISSION))); + assert_eq!(delegated_state(&store, validator_address).unwrap(), Some(amount)); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, amount))); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); // Retrieve the account balance. let public_balance_1 = account_balance(&store, validator_address).unwrap(); @@ -513,14 +823,17 @@ fn test_bond_validator_multiple_bonds() { /* Second Bond */ // Perform the second bond. - let amount = 1_000_000_000_000u64; + let amount = MIN_VALIDATOR_STAKE; assert!(amount < public_balance_1); - bond_public(&process, &store, validator_private_key, validator_address, amount, rng).unwrap(); + bond_validator(&process, &store, validator_private_key, withdrawal_address, amount, TEST_COMMISSION, rng) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((amount * 2, true))); + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!(committee_state(&store, validator_address).unwrap(), Some((amount * 2, true, TEST_COMMISSION))); + assert_eq!(delegated_state(&store, validator_address).unwrap(), Some(amount * 2)); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, amount * 2))); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); // Retrieve the account balance. let public_balance_2 = account_balance(&store, validator_address).unwrap(); @@ -542,8 +855,8 @@ fn test_bond_validator_to_other_validator_fails() { // Initialize the validators. let (validators, _) = initialize_stakers(&store, 2, 0, rng).unwrap(); let mut validators = validators.into_iter(); - let (validator_private_key_1, (validator_address_1, _)) = validators.next().unwrap(); - let (validator_private_key_2, (validator_address_2, _)) = validators.next().unwrap(); + let (validator_private_key_1, (validator_address_1, _, _, withdrawal_address_1)) = validators.next().unwrap(); + let (validator_private_key_2, (validator_address_2, _, _, withdrawal_address_2)) = validators.next().unwrap(); /* Ensure that bonding to another validator fails. */ test_atomic_finalize!(store, FinalizeMode::RealRun, { @@ -555,15 +868,20 @@ fn test_bond_validator_to_other_validator_fails() { // Perform the bond for validator 1. let amount = MIN_VALIDATOR_STAKE; - bond_public(&process, &store, &validator_private_key_1, &validator_address_1, amount, rng).unwrap(); + bond_validator(&process, &store, &validator_private_key_1, &withdrawal_address_1, amount, TEST_COMMISSION, rng) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. - assert_eq!(committee_state(&store, &validator_address_1).unwrap(), Some((amount, true))); + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!(committee_state(&store, &validator_address_1).unwrap(), Some((amount, true, TEST_COMMISSION))); assert_eq!(committee_state(&store, &validator_address_2).unwrap(), None); + assert_eq!(delegated_state(&store, &validator_address_1).unwrap(), Some(amount)); + assert_eq!(delegated_state(&store, &validator_address_2).unwrap(), None); assert_eq!(bond_state(&store, &validator_address_1).unwrap(), Some((validator_address_1, amount))); assert_eq!(bond_state(&store, &validator_address_2).unwrap(), None); assert_eq!(unbond_state(&store, &validator_address_1).unwrap(), None); assert_eq!(unbond_state(&store, &validator_address_2).unwrap(), None); + assert_eq!(withdraw_state(&store, &validator_address_1).unwrap(), Some(withdrawal_address_1)); + assert_eq!(withdraw_state(&store, &validator_address_2).unwrap(), None); // Retrieve the account balance. assert_eq!(account_balance(&store, &validator_address_1).unwrap(), public_balance_1 - amount); @@ -573,15 +891,20 @@ fn test_bond_validator_to_other_validator_fails() { // Perform the bond for validator 2. let amount = MIN_VALIDATOR_STAKE; - bond_public(&process, &store, &validator_private_key_2, &validator_address_2, amount, rng).unwrap(); - - // Check that the committee, bond, and unbond state are correct. - assert_eq!(committee_state(&store, &validator_address_1).unwrap(), Some((amount, true))); - assert_eq!(committee_state(&store, &validator_address_2).unwrap(), Some((amount, true))); + bond_validator(&process, &store, &validator_private_key_2, &withdrawal_address_2, amount, TEST_COMMISSION, rng) + .unwrap(); + + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!(committee_state(&store, &validator_address_1).unwrap(), Some((amount, true, TEST_COMMISSION))); + assert_eq!(committee_state(&store, &validator_address_2).unwrap(), Some((amount, true, TEST_COMMISSION))); + assert_eq!(delegated_state(&store, &validator_address_1).unwrap(), Some(amount)); + assert_eq!(delegated_state(&store, &validator_address_2).unwrap(), Some(amount)); assert_eq!(bond_state(&store, &validator_address_1).unwrap(), Some((validator_address_1, amount))); assert_eq!(bond_state(&store, &validator_address_2).unwrap(), Some((validator_address_2, amount))); assert_eq!(unbond_state(&store, &validator_address_1).unwrap(), None); assert_eq!(unbond_state(&store, &validator_address_2).unwrap(), None); + assert_eq!(withdraw_state(&store, &validator_address_1).unwrap(), Some(withdrawal_address_1)); + assert_eq!(withdraw_state(&store, &validator_address_2).unwrap(), Some(withdrawal_address_2)); // Retrieve the account balance. assert_eq!(account_balance(&store, &validator_address_1).unwrap(), public_balance_1 - amount); @@ -591,7 +914,15 @@ fn test_bond_validator_to_other_validator_fails() { // Ensure that bonding to another validator fails. assert!(public_balance_1 > 2 * amount, "There is not enough balance to bond to another validator."); - let result = bond_public(&process, &store, &validator_private_key_1, &validator_address_2, amount, rng); + let result = bond_public( + &process, + &store, + &validator_private_key_1, + &validator_address_2, + &validator_address_1, + amount, + rng, + ); assert!(result.is_err()); Ok(()) }) @@ -609,7 +940,7 @@ fn test_bond_delegator_simple() { // Initialize the validators and delegators. let (validators, delegators) = initialize_stakers(&store, 1, 1, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); // Retrieve the account balances. @@ -618,7 +949,8 @@ fn test_bond_delegator_simple() { // Bond the validator. let validator_amount = MIN_VALIDATOR_STAKE; - bond_public(&process, &store, validator_private_key, validator_address, validator_amount, rng).unwrap(); + bond_validator(&process, &store, validator_private_key, withdrawal_address, validator_amount, TEST_COMMISSION, rng) + .unwrap(); // Prepare the delegator amount. let delegator_amount = MIN_DELEGATOR_STAKE; @@ -626,16 +958,27 @@ fn test_bond_delegator_simple() { /* Ensure bonding a delegator with the exact MIN_DELEGATOR_STAKE succeeds. */ test_atomic_finalize!(store, FinalizeMode::RealRun, { // Bond the delegator. - bond_public(&process, &store, delegator_private_key, validator_address, delegator_amount, rng).unwrap(); + bond_public( + &process, + &store, + delegator_private_key, + validator_address, + delegator_address, + delegator_amount, + rng, + ) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. let combined_amount = validator_amount + delegator_amount; - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((combined_amount, true))); + assert_eq!(committee_state(&store, validator_address).unwrap(), Some((combined_amount, true, TEST_COMMISSION))); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); assert_eq!(bond_state(&store, delegator_address).unwrap(), Some((*validator_address, delegator_amount))); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); // Check that the balances are correct. assert_eq!(account_balance(&store, validator_address).unwrap(), validator_balance - validator_amount); @@ -659,7 +1002,7 @@ fn test_bond_delegator_below_min_stake_fails() { // Initialize the validators and delegators. let (validators, delegators) = initialize_stakers(&store, 1, 1, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); // Retrieve the account balance. @@ -670,20 +1013,42 @@ fn test_bond_delegator_below_min_stake_fails() { test_atomic_finalize!(store, FinalizeMode::RealRun, { // Bond the validator. let validator_amount = MIN_VALIDATOR_STAKE; - bond_public(&process, &store, validator_private_key, validator_address, validator_amount, rng).unwrap(); + bond_validator( + &process, + &store, + validator_private_key, + withdrawal_address, + validator_amount, + TEST_COMMISSION, + rng, + ) + .unwrap(); // Bond the delegator. let delegator_amount = rng.gen_range(1_000_000..MIN_DELEGATOR_STAKE); - let result = bond_public(&process, &store, delegator_private_key, validator_address, delegator_amount, rng); + let result = bond_public( + &process, + &store, + delegator_private_key, + validator_address, + delegator_address, + delegator_amount, + rng, + ); assert!(result.is_err()); - // Check that the committee, bond, and unbond state are correct. - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((validator_amount, true))); + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!( + committee_state(&store, validator_address).unwrap(), + Some((validator_amount, true, TEST_COMMISSION)) + ); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); assert_eq!(bond_state(&store, delegator_address).unwrap(), None); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), None); // Check that the account balance is correct. assert_eq!(account_balance(&store, validator_address).unwrap(), validator_balance - validator_amount); @@ -704,7 +1069,7 @@ fn test_bond_delegator_with_insufficient_funds_fails() { // Initialize the validators and delegators. let (validators, delegators) = initialize_stakers(&store, 1, 1, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); // Retrieve the account balance. @@ -715,20 +1080,42 @@ fn test_bond_delegator_with_insufficient_funds_fails() { test_atomic_finalize!(store, FinalizeMode::RealRun, { // Bond the validator. let validator_amount = MIN_VALIDATOR_STAKE; - bond_public(&process, &store, validator_private_key, validator_address, validator_amount, rng).unwrap(); + bond_validator( + &process, + &store, + validator_private_key, + withdrawal_address, + validator_amount, + TEST_COMMISSION, + rng, + ) + .unwrap(); // Bond the delegator. let delegator_amount = delegator_balance + 1; - let result = bond_public(&process, &store, delegator_private_key, validator_address, delegator_amount, rng); + let result = bond_public( + &process, + &store, + delegator_private_key, + withdrawal_address, + delegator_address, + delegator_amount, + rng, + ); assert!(result.is_err()); - // Check that the committee, bond, and unbond state are correct. - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((validator_amount, true))); + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!( + committee_state(&store, validator_address).unwrap(), + Some((validator_amount, true, TEST_COMMISSION)) + ); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); assert_eq!(bond_state(&store, delegator_address).unwrap(), None); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), None); // Check that the account balance is correct. assert_eq!(account_balance(&store, validator_address).unwrap(), validator_balance - validator_amount); @@ -749,7 +1136,7 @@ fn test_bond_delegator_multiple_bonds() { // Initialize the validators and delegators. let (validators, delegators) = initialize_stakers(&store, 1, 1, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); // Retrieve the account balance. @@ -758,7 +1145,8 @@ fn test_bond_delegator_multiple_bonds() { // Bond the validator. let validator_amount = MIN_VALIDATOR_STAKE; - bond_public(&process, &store, validator_private_key, validator_address, validator_amount, rng).unwrap(); + bond_validator(&process, &store, validator_private_key, withdrawal_address, validator_amount, TEST_COMMISSION, rng) + .unwrap(); /* Ensure that bonding additional stake as a delegator succeeds. */ test_atomic_finalize!(store, FinalizeMode::RealRun, { @@ -767,16 +1155,27 @@ fn test_bond_delegator_multiple_bonds() { // Perform the first bond. let delegator_amount = MIN_DELEGATOR_STAKE; assert!(delegator_amount < delegator_balance); - bond_public(&process, &store, delegator_private_key, validator_address, delegator_amount, rng).unwrap(); + bond_public( + &process, + &store, + delegator_private_key, + validator_address, + delegator_address, + delegator_amount, + rng, + ) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. let combined_amount = validator_amount + delegator_amount; - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((combined_amount, true))); + assert_eq!(committee_state(&store, validator_address).unwrap(), Some((combined_amount, true, TEST_COMMISSION))); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); assert_eq!(bond_state(&store, delegator_address).unwrap(), Some((*validator_address, delegator_amount))); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); // Retrieve the account balance. let validator_balance_1 = account_balance(&store, validator_address).unwrap(); @@ -789,16 +1188,27 @@ fn test_bond_delegator_multiple_bonds() { // Perform the second bond. let delegator_amount = MIN_DELEGATOR_STAKE; assert!(delegator_amount < delegator_balance_1); - bond_public(&process, &store, delegator_private_key, validator_address, delegator_amount, rng).unwrap(); + bond_public( + &process, + &store, + delegator_private_key, + validator_address, + delegator_address, + delegator_amount, + rng, + ) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. let combined_amount = validator_amount + delegator_amount + delegator_amount; - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((combined_amount, true))); + assert_eq!(committee_state(&store, validator_address).unwrap(), Some((combined_amount, true, TEST_COMMISSION))); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); assert_eq!(bond_state(&store, delegator_address).unwrap(), Some((*validator_address, 2 * delegator_amount))); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); // Retrieve the account balance. let validator_balance_2 = account_balance(&store, validator_address).unwrap(); @@ -811,43 +1221,135 @@ fn test_bond_delegator_multiple_bonds() { } #[test] -fn test_bond_delegator_to_nonexistent_validator_fails() { +fn test_bond_validator_and_delegator_multiple_times() { let rng = &mut TestRng::default(); // Construct the process. let process = Process::::load().unwrap(); + // Initialize a new finalize store. - let (store, _temp_dir) = sample_finalize_store!(); + let finalize_store = FinalizeStore::>::open(None).unwrap(); // Initialize the validators and delegators. - let (_, delegators) = initialize_stakers(&store, 0, 1, rng).unwrap(); + let (validators, delegators) = initialize_stakers(&finalize_store, 1, 1, rng).unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); - // Sample a random validator address. - let validator_address = &Address::new(rng.gen()); + // Retrieve the account balances. + let validator_public_balance = account_balance(&finalize_store, validator_address).unwrap(); + let delegator_public_balance = account_balance(&finalize_store, delegator_address).unwrap(); - // Retrieve the account balance. - let delegator_balance = account_balance(&store, delegator_address).unwrap(); - assert!(delegator_balance > MIN_DELEGATOR_STAKE); + // Prepare the validator amount. + let validator_amount = MIN_VALIDATOR_STAKE; + // Perform the bond. + bond_validator( + &process, + &finalize_store, + validator_private_key, + withdrawal_address, + validator_amount, + TEST_COMMISSION, + rng, + ) + .unwrap(); - /* Ensure bonding to a nonexistent validator fails. */ - test_atomic_finalize!(store, FinalizeMode::RealRun, { - let amount = MIN_DELEGATOR_STAKE; - let result = bond_public(&process, &store, delegator_private_key, validator_address, amount, rng); - assert!(result.is_err()); - assert_eq!(committee_state(&store, validator_address).unwrap(), None); - assert_eq!(committee_state(&store, delegator_address).unwrap(), None); - assert_eq!(bond_state(&store, validator_address).unwrap(), None); - assert_eq!(bond_state(&store, delegator_address).unwrap(), None); - assert_eq!(unbond_state(&store, validator_address).unwrap(), None); - assert_eq!(unbond_state(&store, delegator_address).unwrap(), None); - assert_eq!(account_balance(&store, delegator_address).unwrap(), delegator_balance); - Ok(()) - }) + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!( + committee_state(&finalize_store, validator_address).unwrap(), + Some((validator_amount, true, TEST_COMMISSION)) + ); + assert_eq!(bond_state(&finalize_store, validator_address).unwrap(), Some((*validator_address, validator_amount))); + assert_eq!(unbond_state(&finalize_store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&finalize_store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!( + account_balance(&finalize_store, validator_address).unwrap(), + validator_public_balance - validator_amount + ); + + // Bond the delegator to the validator. + let delegator_amount = MIN_DELEGATOR_STAKE; + bond_public( + &process, + &finalize_store, + delegator_private_key, + validator_address, + delegator_address, + delegator_amount, + rng, + ) + .unwrap(); + + // Check that the committee, bond, unbond, and withdraw states are correct. + let combined_amount = validator_amount + delegator_amount; + assert_eq!( + committee_state(&finalize_store, validator_address).unwrap(), + Some((combined_amount, true, TEST_COMMISSION)) + ); + assert_eq!(bond_state(&finalize_store, delegator_address).unwrap(), Some((*validator_address, delegator_amount))); + assert_eq!(unbond_state(&finalize_store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&finalize_store, delegator_address).unwrap(), Some(*delegator_address)); + assert_eq!( + account_balance(&finalize_store, delegator_address).unwrap(), + delegator_public_balance - delegator_amount + ); + + // Bond the validator again. + bond_validator( + &process, + &finalize_store, + validator_private_key, + withdrawal_address, + validator_amount, + TEST_COMMISSION, + rng, + ) + .unwrap(); + + // Check that the committee, bond, unbond, and withdraw states are correct. + let combined_amount = 2 * validator_amount + delegator_amount; + assert_eq!( + committee_state(&finalize_store, validator_address).unwrap(), + Some((combined_amount, true, TEST_COMMISSION)) + ); + assert_eq!( + bond_state(&finalize_store, validator_address).unwrap(), + Some((*validator_address, 2 * validator_amount)) + ); + assert_eq!(unbond_state(&finalize_store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&finalize_store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!( + account_balance(&finalize_store, validator_address).unwrap(), + validator_public_balance - (2 * validator_amount) + ); + + // Bond the delegator to the validator again. + bond_public( + &process, + &finalize_store, + delegator_private_key, + validator_address, + delegator_address, + delegator_amount, + rng, + ) .unwrap(); - // Sanity check after finalizing. - assert_eq!(account_balance(&store, delegator_address).unwrap(), delegator_balance); + // Check that the committee, bond, unbond, and withdraw states are correct. + let combined_amount = 2 * (validator_amount + delegator_amount); + assert_eq!( + committee_state(&finalize_store, validator_address).unwrap(), + Some((combined_amount, true, TEST_COMMISSION)) + ); + assert_eq!( + bond_state(&finalize_store, delegator_address).unwrap(), + Some((*validator_address, 2 * delegator_amount)) + ); + assert_eq!(unbond_state(&finalize_store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&finalize_store, delegator_address).unwrap(), Some(*delegator_address)); + assert_eq!( + account_balance(&finalize_store, delegator_address).unwrap(), + delegator_public_balance - (2 * delegator_amount) + ); } #[test] @@ -862,8 +1364,8 @@ fn test_bond_delegator_to_multiple_validators_fails() { // Initialize the validators and delegators. let (validators, delegators) = initialize_stakers(&store, 2, 1, rng).unwrap(); let mut validators = validators.into_iter(); - let (validator_private_key_1, (validator_address_1, _)) = validators.next().unwrap(); - let (validator_private_key_2, (validator_address_2, _)) = validators.next().unwrap(); + let (validator_private_key_1, (validator_address_1, _, _, withdrawal_address_1)) = validators.next().unwrap(); + let (validator_private_key_2, (validator_address_2, _, _, withdrawal_address_2)) = validators.next().unwrap(); let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); // Retrieve the account balance. @@ -873,11 +1375,29 @@ fn test_bond_delegator_to_multiple_validators_fails() { // Bond validator 1. let validator_1_amount = MIN_VALIDATOR_STAKE; - bond_public(&process, &store, &validator_private_key_1, &validator_address_1, validator_1_amount, rng).unwrap(); + bond_validator( + &process, + &store, + &validator_private_key_1, + &withdrawal_address_1, + validator_1_amount, + TEST_COMMISSION, + rng, + ) + .unwrap(); // Bond validator 2. let validator_2_amount = MIN_VALIDATOR_STAKE; - bond_public(&process, &store, &validator_private_key_2, &validator_address_2, validator_2_amount, rng).unwrap(); + bond_validator( + &process, + &store, + &validator_private_key_2, + &withdrawal_address_2, + validator_2_amount, + TEST_COMMISSION, + rng, + ) + .unwrap(); /* Ensure bonding a delegator to multiple validators fails. */ test_atomic_finalize!(store, FinalizeMode::RealRun, { @@ -886,12 +1406,27 @@ fn test_bond_delegator_to_multiple_validators_fails() { // Perform the first bond. let delegator_amount = MIN_DELEGATOR_STAKE; assert!(delegator_amount < delegator_balance); - bond_public(&process, &store, delegator_private_key, &validator_address_1, delegator_amount, rng).unwrap(); + bond_public( + &process, + &store, + delegator_private_key, + &validator_address_1, + delegator_address, + delegator_amount, + rng, + ) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. let combined_amount = validator_1_amount + delegator_amount; - assert_eq!(committee_state(&store, &validator_address_1).unwrap(), Some((combined_amount, true))); - assert_eq!(committee_state(&store, &validator_address_2).unwrap(), Some((validator_2_amount, true))); + assert_eq!( + committee_state(&store, &validator_address_1).unwrap(), + Some((combined_amount, true, TEST_COMMISSION)) + ); + assert_eq!( + committee_state(&store, &validator_address_2).unwrap(), + Some((validator_2_amount, true, TEST_COMMISSION)) + ); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); assert_eq!(bond_state(&store, &validator_address_1).unwrap(), Some((validator_address_1, validator_1_amount))); assert_eq!(bond_state(&store, &validator_address_2).unwrap(), Some((validator_address_2, validator_2_amount))); @@ -899,6 +1434,9 @@ fn test_bond_delegator_to_multiple_validators_fails() { assert_eq!(unbond_state(&store, &validator_address_1).unwrap(), None); assert_eq!(unbond_state(&store, &validator_address_2).unwrap(), None); assert_eq!(unbond_state(&store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, &validator_address_1).unwrap(), Some(withdrawal_address_1)); + assert_eq!(withdraw_state(&store, &validator_address_2).unwrap(), Some(withdrawal_address_2)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); // Retrieve the account balance. let validator_1_balance_1 = account_balance(&store, &validator_address_1).unwrap(); @@ -913,13 +1451,27 @@ fn test_bond_delegator_to_multiple_validators_fails() { // Perform the second bond. let delegator_amount = MIN_DELEGATOR_STAKE; assert!(delegator_amount < delegator_balance_1); - let result = bond_public(&process, &store, delegator_private_key, &validator_address_2, delegator_amount, rng); + let result = bond_public( + &process, + &store, + delegator_private_key, + &validator_address_2, + delegator_address, + delegator_amount, + rng, + ); assert!(result.is_err()); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. let combined_amount = validator_1_amount + delegator_amount; - assert_eq!(committee_state(&store, &validator_address_1).unwrap(), Some((combined_amount, true))); - assert_eq!(committee_state(&store, &validator_address_2).unwrap(), Some((validator_2_amount, true))); + assert_eq!( + committee_state(&store, &validator_address_1).unwrap(), + Some((combined_amount, true, TEST_COMMISSION)) + ); + assert_eq!( + committee_state(&store, &validator_address_2).unwrap(), + Some((validator_2_amount, true, TEST_COMMISSION)) + ); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); assert_eq!(bond_state(&store, &validator_address_1).unwrap(), Some((validator_address_1, validator_1_amount))); assert_eq!(bond_state(&store, &validator_address_2).unwrap(), Some((validator_address_2, validator_2_amount))); @@ -927,6 +1479,9 @@ fn test_bond_delegator_to_multiple_validators_fails() { assert_eq!(unbond_state(&store, &validator_address_1).unwrap(), None); assert_eq!(unbond_state(&store, &validator_address_2).unwrap(), None); assert_eq!(unbond_state(&store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, &validator_address_1).unwrap(), Some(withdrawal_address_1)); + assert_eq!(withdraw_state(&store, &validator_address_2).unwrap(), Some(withdrawal_address_2)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); // Retrieve the account balance. let validator_1_balance_2 = account_balance(&store, &validator_address_1).unwrap(); @@ -951,14 +1506,16 @@ fn test_unbond_validator() { // Initialize the validators and delegators. let (validators, _) = initialize_stakers(&store, 1, 0, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, withdrawal_private_key, withdrawal_address)) = + validators.first().unwrap(); // Retrieve the account balance. let validator_balance = account_balance(&store, validator_address).unwrap(); // Perform the bond. let validator_amount = 3 * MIN_VALIDATOR_STAKE; - bond_public(&process, &store, validator_private_key, validator_address, validator_amount, rng).unwrap(); + bond_validator(&process, &store, validator_private_key, withdrawal_address, validator_amount, TEST_COMMISSION, rng) + .unwrap(); /* Ensure the validator can unbond their entire balance. */ test_atomic_finalize!(store, FinalizeMode::RealRun, { @@ -967,14 +1524,27 @@ fn test_unbond_validator() { // Perform the first unbond. let unbond_amount_1 = MIN_VALIDATOR_STAKE; let block_height_1 = rng.gen_range(1..100); - unbond_public(&process, &store, validator_private_key, unbond_amount_1, block_height_1, rng).unwrap(); + unbond_public( + &process, + &store, + withdrawal_private_key, + validator_address, + unbond_amount_1, + block_height_1, + rng, + ) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. let decremented_amount = validator_amount - unbond_amount_1; let unlock_height = block_height_1 + NUM_BLOCKS_TO_UNLOCK; - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((decremented_amount, true))); + assert_eq!( + committee_state(&store, validator_address).unwrap(), + Some((decremented_amount, true, TEST_COMMISSION)) + ); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, decremented_amount))); assert_eq!(unbond_state(&store, validator_address).unwrap(), Some((unbond_amount_1, unlock_height))); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); // Retrieve the account balance. let validator_balance_1 = account_balance(&store, validator_address).unwrap(); @@ -985,15 +1555,28 @@ fn test_unbond_validator() { // Perform the second unbond. let unbond_amount_2 = MIN_VALIDATOR_STAKE; let block_height_2 = rng.gen_range(block_height_1..1000); - unbond_public(&process, &store, validator_private_key, unbond_amount_2, block_height_2, rng).unwrap(); + unbond_public( + &process, + &store, + withdrawal_private_key, + validator_address, + unbond_amount_2, + block_height_2, + rng, + ) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. let decremented_amount = validator_amount - unbond_amount_1 - unbond_amount_2; let unbond_combined_amount = unbond_amount_1 + unbond_amount_2; let unlock_height = block_height_2 + NUM_BLOCKS_TO_UNLOCK; - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((decremented_amount, true))); + assert_eq!( + committee_state(&store, validator_address).unwrap(), + Some((decremented_amount, true, TEST_COMMISSION)) + ); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, decremented_amount))); assert_eq!(unbond_state(&store, validator_address).unwrap(), Some((unbond_combined_amount, unlock_height))); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); // Retrieve the account balance. let validator_balance_2 = account_balance(&store, validator_address).unwrap(); @@ -1004,13 +1587,23 @@ fn test_unbond_validator() { // Perform the third unbond, which should unbond all remaining stake. let unbond_amount_3 = 1; // Notice: This is 1 credit, when the remaining is MIN_VALIDATOR_STAKE. let block_height_3 = rng.gen_range(block_height_2..10000); - unbond_public(&process, &store, validator_private_key, unbond_amount_3, block_height_3, rng).unwrap(); + unbond_public( + &process, + &store, + withdrawal_private_key, + validator_address, + unbond_amount_3, + block_height_3, + rng, + ) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. let unlock_height = block_height_3 + NUM_BLOCKS_TO_UNLOCK; assert_eq!(committee_state(&store, validator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, validator_address).unwrap(), Some((validator_amount, unlock_height))); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); // Retrieve the account balance. let validator_balance_3 = account_balance(&store, validator_address).unwrap(); @@ -1021,13 +1614,22 @@ fn test_unbond_validator() { // Perform the fourth unbond, which should fail (as there is no stake left). let unbond_amount_4 = 1; let block_height_4 = rng.gen_range(block_height_3..100000); - let result = unbond_public(&process, &store, validator_private_key, unbond_amount_4, block_height_4, rng); + let result = unbond_public( + &process, + &store, + withdrawal_private_key, + validator_address, + unbond_amount_4, + block_height_4, + rng, + ); assert!(result.is_err()); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. assert_eq!(committee_state(&store, validator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, validator_address).unwrap(), Some((validator_amount, unlock_height))); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); // Retrieve the account balance. let validator_balance_4 = account_balance(&store, validator_address).unwrap(); @@ -1036,8 +1638,96 @@ fn test_unbond_validator() { }) .unwrap(); } + #[test] -fn test_unbond_validator_fails_if_unbonding_beyond_their_stake() { +fn test_bond_validator_fails_if_unbonding_state() { + let rng = &mut TestRng::default(); + + // Construct the process. + let process = Process::::load().unwrap(); + // Initialize a new finalize store. + let (store, _temp_dir) = sample_finalize_store!(); + + // Initialize the validators and delegators. + let (validators, _) = initialize_stakers(&store, 1, 0, rng).unwrap(); + let (validator_private_key, (validator_address, _, withdrawal_private_key, withdrawal_address)) = + validators.first().unwrap(); + + // Perform the bond. + let validator_amount = MIN_VALIDATOR_STAKE; + bond_validator(&process, &store, validator_private_key, withdrawal_address, validator_amount, TEST_COMMISSION, rng) + .unwrap(); + + /* Ensure the validator can unbond their entire balance. */ + test_atomic_finalize!(store, FinalizeMode::RealRun, { + // Ensure the validator is part of the committee and bonded correctly + assert_eq!( + committee_state(&store, validator_address).unwrap(), + Some((validator_amount, true, TEST_COMMISSION)) + ); + assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); + assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + + // Perform the unbond + let block_height = rng.gen_range(1..100); + unbond_public(&process, &store, withdrawal_private_key, validator_address, validator_amount, block_height, rng) + .unwrap(); + + // Ensure unbonding the validator removed them from the committee and updated state correctly + let unlock_height = block_height + NUM_BLOCKS_TO_UNLOCK; + assert_eq!(committee_state(&store, validator_address).unwrap(), None); + assert_eq!(bond_state(&store, validator_address).unwrap(), None); + assert_eq!(unbond_state(&store, validator_address).unwrap(), Some((validator_amount, unlock_height))); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + + // Try bond_validator again, should fail due to unbonding state + let rebonding_result = bond_validator( + &process, + &store, + validator_private_key, + withdrawal_address, + validator_amount, + TEST_COMMISSION, + rng, + ); + assert!(rebonding_result.is_err()); + + // Ensure the error wasn't due to insufficient balance + let validator_balance = account_balance(&store, validator_address).unwrap(); + assert!(validator_balance > MIN_VALIDATOR_STAKE); + + // Ensure the validator didn't reenter the committee + assert_eq!(committee_state(&store, validator_address).unwrap(), None); + + // Claim Unbond Public to clear unbonding state + claim_unbond_public(&process, &store, validator_private_key, validator_address, unlock_height, rng).unwrap(); + + // Try bond_validator again with new commission, should succeed + let new_commission = TEST_COMMISSION + 1; + bond_validator( + &process, + &store, + validator_private_key, + withdrawal_address, + validator_amount, + new_commission, + rng, + ) + .unwrap(); + + // Ensure the validator is part of the committee and bonded correctly + assert_eq!(committee_state(&store, validator_address).unwrap(), Some((validator_amount, true, new_commission))); + assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); + assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + Ok(()) + }) + .unwrap(); +} + +#[test] +fn test_unbond_validator_fails_if_unbonding_beyond_their_stake() { let rng = &mut TestRng::default(); // Construct the process. @@ -1047,7 +1737,8 @@ fn test_unbond_validator_fails_if_unbonding_beyond_their_stake() { // Initialize the validators and delegators. let (validators, delegators) = initialize_stakers(&store, 1, 1, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, withdrawal_private_key, withdrawal_address)) = + validators.first().unwrap(); let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); // Retrieve the account balance. @@ -1056,20 +1747,33 @@ fn test_unbond_validator_fails_if_unbonding_beyond_their_stake() { // Bond the validator. let validator_amount = 2 * MIN_VALIDATOR_STAKE; - bond_public(&process, &store, validator_private_key, validator_address, validator_amount, rng).unwrap(); + bond_validator(&process, &store, validator_private_key, withdrawal_address, validator_amount, TEST_COMMISSION, rng) + .unwrap(); /* Ensure the validator cannot unbond more than their stake. */ test_atomic_finalize!(store, FinalizeMode::RealRun, { // Perform the unbond. let unbond_amount = validator_amount + 1; let block_height = rng.gen_range(1..100); - let result = unbond_public(&process, &store, validator_private_key, unbond_amount, block_height, rng); + let result = unbond_public( + &process, + &store, + withdrawal_private_key, + validator_address, + unbond_amount, + block_height, + rng, + ); assert!(result.is_err()); - // Check that the committee, bond, and unbond state are correct. - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((validator_amount, true))); + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!( + committee_state(&store, validator_address).unwrap(), + Some((validator_amount, true, TEST_COMMISSION)) + ); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); // Retrieve the account balance. let validator_balance_1 = account_balance(&store, validator_address).unwrap(); @@ -1080,24 +1784,35 @@ fn test_unbond_validator_fails_if_unbonding_beyond_their_stake() { // Bond the delegator. let delegator_amount = MIN_DELEGATOR_STAKE; - bond_public(&process, &store, delegator_private_key, validator_address, delegator_amount, rng).unwrap(); + bond_public(&process, &store, delegator_private_key, validator_address, delegator_address, delegator_amount, rng) + .unwrap(); /* Ensure the validator cannot unbond more than their stake. */ test_atomic_finalize!(store, FinalizeMode::RealRun, { // Perform the unbond. let unbond_amount = validator_amount + 1; let block_height = rng.gen_range(1..100); - let result = unbond_public(&process, &store, validator_private_key, unbond_amount, block_height, rng); + let result = unbond_public( + &process, + &store, + withdrawal_private_key, + validator_address, + unbond_amount, + block_height, + rng, + ); assert!(result.is_err()); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. let combined_amount = validator_amount + delegator_amount; - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((combined_amount, true))); + assert_eq!(committee_state(&store, validator_address).unwrap(), Some((combined_amount, true, TEST_COMMISSION))); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); assert_eq!(bond_state(&store, delegator_address).unwrap(), Some((*validator_address, delegator_amount))); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); // Retrieve the account balance. let validator_balance_1 = account_balance(&store, validator_address).unwrap(); @@ -1110,7 +1825,7 @@ fn test_unbond_validator_fails_if_unbonding_beyond_their_stake() { } #[test] -fn test_unbond_validator_fails_if_there_is_a_delegator() { +fn test_unbond_validator_continues_if_there_is_a_delegator() { let rng = &mut TestRng::default(); // Construct the process. @@ -1120,7 +1835,8 @@ fn test_unbond_validator_fails_if_there_is_a_delegator() { // Initialize the validators and delegators. let (validators, delegators) = initialize_stakers(&store, 1, 1, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, withdrawal_private_key, withdrawal_address)) = + validators.first().unwrap(); let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); // Retrieve the account balance. @@ -1129,35 +1845,55 @@ fn test_unbond_validator_fails_if_there_is_a_delegator() { // Bond the validator. let validator_amount = 2 * MIN_VALIDATOR_STAKE; - bond_public(&process, &store, validator_private_key, validator_address, validator_amount, rng).unwrap(); + bond_validator(&process, &store, validator_private_key, withdrawal_address, validator_amount, TEST_COMMISSION, rng) + .unwrap(); // Bond the delegator. let delegator_amount = MIN_DELEGATOR_STAKE; - bond_public(&process, &store, delegator_private_key, validator_address, delegator_amount, rng).unwrap(); + bond_public(&process, &store, delegator_private_key, validator_address, delegator_address, delegator_amount, rng) + .unwrap(); - /* Ensure the validator cannot fully-unbond if there remains a delegator. */ + /* Ensure the validator can fully-unbond if there remains a delegator. */ test_atomic_finalize!(store, FinalizeMode::RealRun, { // Perform the first unbond. let unbond_amount_1 = MIN_VALIDATOR_STAKE; let block_height_1 = rng.gen_range(1..100); - unbond_public(&process, &store, validator_private_key, unbond_amount_1, block_height_1, rng).unwrap(); + unbond_public( + &process, + &store, + withdrawal_private_key, + validator_address, + unbond_amount_1, + block_height_1, + rng, + ) + .unwrap(); // Perform the second unbond. - let unbond_amount_2 = 1; + let unbond_amount_2 = MIN_DELEGATOR_STAKE + 2; let block_height_2 = rng.gen_range(block_height_1..1000); - let result = unbond_public(&process, &store, validator_private_key, unbond_amount_2, block_height_2, rng); - assert!(result.is_err()); - - // Check that the committee, bond, and unbond state are correct. - let combined_amount = validator_amount + delegator_amount - unbond_amount_1; - let validator_bond = validator_amount - unbond_amount_1; - let unlock_height = block_height_1 + NUM_BLOCKS_TO_UNLOCK; - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((combined_amount, true))); + let result = unbond_public( + &process, + &store, + withdrawal_private_key, + validator_address, + unbond_amount_2, + block_height_2, + rng, + ); + assert!(result.is_ok()); + + // Check that the committee, bond, unbond, and withdraw states are correct. + let unlock_height = block_height_2 + NUM_BLOCKS_TO_UNLOCK; + assert_eq!(committee_state(&store, validator_address).unwrap(), None); + assert_eq!(delegated_state(&store, validator_address).unwrap(), Some(delegator_amount)); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); - assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_bond))); + assert_eq!(bond_state(&store, validator_address).unwrap(), None); assert_eq!(bond_state(&store, delegator_address).unwrap(), Some((*validator_address, delegator_amount))); - assert_eq!(unbond_state(&store, validator_address).unwrap(), Some((validator_bond, unlock_height))); + assert_eq!(unbond_state(&store, validator_address).unwrap(), Some((validator_amount, unlock_height))); assert_eq!(unbond_state(&store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); // Retrieve the account balance. let validator_balance_1 = account_balance(&store, validator_address).unwrap(); @@ -1180,7 +1916,7 @@ fn test_unbond_delegator() { // Initialize the validators and delegators. let (validators, delegators) = initialize_stakers(&store, 1, 1, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); // Retrieve the account balance. @@ -1189,11 +1925,13 @@ fn test_unbond_delegator() { // Bond the validator. let validator_amount = MIN_VALIDATOR_STAKE; - bond_public(&process, &store, validator_private_key, validator_address, validator_amount, rng).unwrap(); + bond_validator(&process, &store, validator_private_key, withdrawal_address, validator_amount, TEST_COMMISSION, rng) + .unwrap(); // Bond the delegator. let delegator_amount = 3 * MIN_DELEGATOR_STAKE; - bond_public(&process, &store, delegator_private_key, validator_address, delegator_amount, rng).unwrap(); + bond_public(&process, &store, delegator_private_key, validator_address, delegator_address, delegator_amount, rng) + .unwrap(); /* Ensure the delegator can unbond their entire balance. */ test_atomic_finalize!(store, FinalizeMode::RealRun, { @@ -1202,18 +1940,24 @@ fn test_unbond_delegator() { // Perform the first unbond. let unbond_amount_1 = MIN_DELEGATOR_STAKE; let block_height_1 = rng.gen_range(1..100); - unbond_public(&process, &store, delegator_private_key, unbond_amount_1, block_height_1, rng).unwrap(); + unbond_public(&process, &store, delegator_private_key, delegator_address, unbond_amount_1, block_height_1, rng) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. let decremented_amount = validator_amount + delegator_amount - unbond_amount_1; let decremented_delegator = delegator_amount - unbond_amount_1; let unlock_height = block_height_1 + NUM_BLOCKS_TO_UNLOCK; - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((decremented_amount, true))); + assert_eq!( + committee_state(&store, validator_address).unwrap(), + Some((decremented_amount, true, TEST_COMMISSION)) + ); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); assert_eq!(bond_state(&store, delegator_address).unwrap(), Some((*validator_address, decremented_delegator))); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, delegator_address).unwrap(), Some((unbond_amount_1, unlock_height))); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); // Retrieve the account balance. let validator_balance_1 = account_balance(&store, validator_address).unwrap(); @@ -1226,19 +1970,25 @@ fn test_unbond_delegator() { // Perform the second unbond. let unbond_amount_2 = MIN_DELEGATOR_STAKE; let block_height_2 = rng.gen_range(block_height_1..1000); - unbond_public(&process, &store, delegator_private_key, unbond_amount_2, block_height_2, rng).unwrap(); + unbond_public(&process, &store, delegator_private_key, delegator_address, unbond_amount_2, block_height_2, rng) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. let decremented_amount = decremented_amount - unbond_amount_2; let decremented_delegator = decremented_delegator - unbond_amount_2; let unbond_combined_amount = unbond_amount_1 + unbond_amount_2; let unlock_height = block_height_2 + NUM_BLOCKS_TO_UNLOCK; - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((decremented_amount, true))); + assert_eq!( + committee_state(&store, validator_address).unwrap(), + Some((decremented_amount, true, TEST_COMMISSION)) + ); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); assert_eq!(bond_state(&store, delegator_address).unwrap(), Some((*validator_address, decremented_delegator))); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, delegator_address).unwrap(), Some((unbond_combined_amount, unlock_height))); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); // Retrieve the account balance. let validator_balance_2 = account_balance(&store, validator_address).unwrap(); @@ -1251,16 +2001,22 @@ fn test_unbond_delegator() { // Perform the third unbond, which should unbond all remaining stake. let unbond_amount_3 = 1; // Notice: This is 1 credit, when the remaining is MIN_DELEGATOR_STAKE. let block_height_3 = rng.gen_range(block_height_2..10000); - unbond_public(&process, &store, delegator_private_key, unbond_amount_3, block_height_3, rng).unwrap(); + unbond_public(&process, &store, delegator_private_key, delegator_address, unbond_amount_3, block_height_3, rng) + .unwrap(); - // Check that the committee, bond, and unbond state are correct. + // Check that the committee, bond, unbond, and withdraw states are correct. let unlock_height = block_height_3 + NUM_BLOCKS_TO_UNLOCK; - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((validator_amount, true))); + assert_eq!( + committee_state(&store, validator_address).unwrap(), + Some((validator_amount, true, TEST_COMMISSION)) + ); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); assert_eq!(bond_state(&store, delegator_address).unwrap(), None); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, delegator_address).unwrap(), Some((delegator_amount, unlock_height))); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); // Retrieve the account balance. let validator_balance_3 = account_balance(&store, validator_address).unwrap(); @@ -1273,16 +2029,29 @@ fn test_unbond_delegator() { // Perform the fourth unbond, which should fail (as there is no stake left). let unbond_amount_4 = 1; let block_height_4 = rng.gen_range(block_height_3..100000); - let result = unbond_public(&process, &store, delegator_private_key, unbond_amount_4, block_height_4, rng); + let result = unbond_public( + &process, + &store, + delegator_private_key, + delegator_address, + unbond_amount_4, + block_height_4, + rng, + ); assert!(result.is_err()); - // Check that the committee, bond, and unbond state are correct. - assert_eq!(committee_state(&store, validator_address).unwrap(), Some((validator_amount, true))); + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!( + committee_state(&store, validator_address).unwrap(), + Some((validator_amount, true, TEST_COMMISSION)) + ); assert_eq!(committee_state(&store, delegator_address).unwrap(), None); assert_eq!(bond_state(&store, validator_address).unwrap(), Some((*validator_address, validator_amount))); assert_eq!(bond_state(&store, delegator_address).unwrap(), None); assert_eq!(unbond_state(&store, validator_address).unwrap(), None); assert_eq!(unbond_state(&store, delegator_address).unwrap(), Some((delegator_amount, unlock_height))); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); // Retrieve the account balance. let validator_balance_4 = account_balance(&store, validator_address).unwrap(); @@ -1294,6 +2063,124 @@ fn test_unbond_delegator() { .unwrap(); } +#[test] +fn test_unbond_delegator_without_validator() { + let rng = &mut TestRng::default(); + + // Construct the process. + let process = Process::::load().unwrap(); + // Initialize a new finalize store. + let (store, _temp_dir) = sample_finalize_store!(); + + // Initialize the validators and delegators. + let (validators, delegators) = initialize_stakers(&store, 1, 1, rng).unwrap(); + let (_, (validator_address, _, _, _)) = validators.first().unwrap(); + let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); + + // Bond the delegator. + let delegator_amount = MIN_DELEGATOR_STAKE; + bond_public(&process, &store, delegator_private_key, validator_address, delegator_address, delegator_amount, rng) + .unwrap(); + + /* Ensure the delegator can unbond their entire balance. */ + test_atomic_finalize!(store, FinalizeMode::RealRun, { + // Perform the unbond. + let block_height = rng.gen_range(1..100); + unbond_public(&process, &store, delegator_private_key, delegator_address, delegator_amount, block_height, rng) + .unwrap(); + + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!(committee_state(&store, validator_address).unwrap(), None); + assert_eq!(committee_state(&store, delegator_address).unwrap(), None); + assert_eq!(bond_state(&store, validator_address).unwrap(), None); + assert_eq!(bond_state(&store, delegator_address).unwrap(), None); + assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!( + unbond_state(&store, delegator_address).unwrap(), + Some((delegator_amount, block_height + NUM_BLOCKS_TO_UNLOCK)) + ); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); + + Ok(()) + }) + .unwrap(); +} + +#[test] +fn test_unbond_delegator_removes_validator_with_insufficient_stake() { + let rng = &mut TestRng::default(); + + // Construct the process. + let process = Process::::load().unwrap(); + // Initialize a new finalize store. + let (store, _temp_dir) = sample_finalize_store!(); + + // Initialize the validators and delegators. + let (validators, delegators) = initialize_stakers(&store, 1, 1, rng).unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); + let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); + + // Bond the delegator. + let delegator_amount = MIN_VALIDATOR_STAKE - MIN_VALIDATOR_SELF_STAKE; + bond_public(&process, &store, delegator_private_key, validator_address, delegator_address, delegator_amount, rng) + .unwrap(); + + // Bond the validator + bond_validator( + &process, + &store, + validator_private_key, + withdrawal_address, + MIN_VALIDATOR_SELF_STAKE, + TEST_COMMISSION, + rng, + ) + .unwrap(); + + /* Ensure the delegator can unbond their entire balance. */ + test_atomic_finalize!(store, FinalizeMode::RealRun, { + // Ensure that the validator is part of the committee and correctly bonded + assert_eq!( + committee_state(&store, validator_address).unwrap(), + Some((MIN_VALIDATOR_STAKE, true, TEST_COMMISSION)) + ); + assert_eq!(committee_state(&store, delegator_address).unwrap(), None); + assert_eq!( + bond_state(&store, validator_address).unwrap(), + Some((*validator_address, MIN_VALIDATOR_SELF_STAKE)) + ); + assert_eq!(bond_state(&store, delegator_address).unwrap(), Some((*validator_address, delegator_amount))); + assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(unbond_state(&store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); + + let block_height = rng.gen_range(1..100); + unbond_public(&process, &store, delegator_private_key, delegator_address, delegator_amount, block_height, rng) + .unwrap(); + + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!(committee_state(&store, validator_address).unwrap(), None); + assert_eq!(committee_state(&store, delegator_address).unwrap(), None); + assert_eq!(bond_state(&store, validator_address).unwrap(), None); + assert_eq!(bond_state(&store, delegator_address).unwrap(), None); + assert_eq!( + unbond_state(&store, validator_address).unwrap(), + Some((MIN_VALIDATOR_SELF_STAKE, block_height + NUM_BLOCKS_TO_UNLOCK)) + ); + assert_eq!( + unbond_state(&store, delegator_address).unwrap(), + Some((delegator_amount, block_height + NUM_BLOCKS_TO_UNLOCK)) + ); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*delegator_address)); + + Ok(()) + }) + .unwrap(); +} + #[test] fn test_unbond_delegator_as_validator() { let rng = &mut TestRng::default(); @@ -1307,28 +2194,48 @@ fn test_unbond_delegator_as_validator() { // Initialize the validators and delegators. let (validators, delegators) = initialize_stakers(&finalize_store, 2, 1, rng).unwrap(); let mut validators = validators.into_iter(); - let (validator_private_key_1, (validator_address_1, _)) = validators.next().unwrap(); - let (validator_private_key_2, (validator_address_2, _)) = validators.next().unwrap(); + let (validator_private_key_1, (validator_address_1, _, withdrawal_private_key_1, withdrawal_address_1)) = + validators.next().unwrap(); + let (validator_private_key_2, (_, _, withdrawal_private_key_2, withdrawal_address_2)) = validators.next().unwrap(); let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); /* Ensure unbonding a delegator as an open validator fails. */ // Bond the validators. - let validator_amount = 1_000_000_000_000u64; - bond_public(&process, &finalize_store, &validator_private_key_1, &validator_address_1, validator_amount, rng) - .unwrap(); - bond_public(&process, &finalize_store, &validator_private_key_2, &validator_address_2, validator_amount, rng) - .unwrap(); + let validator_amount = MIN_VALIDATOR_STAKE; + bond_validator( + &process, + &finalize_store, + &validator_private_key_1, + &withdrawal_address_1, + validator_amount, + TEST_COMMISSION, + rng, + ) + .unwrap(); + bond_validator( + &process, + &finalize_store, + &validator_private_key_2, + &withdrawal_address_2, + validator_amount, + TEST_COMMISSION, + rng, + ) + .unwrap(); // Bond the delegator. let delegator_amount = MIN_DELEGATOR_STAKE; - bond_public(&process, &finalize_store, delegator_private_key, &validator_address_1, delegator_amount, rng).unwrap(); - - // Ensure that unbonding a delegator as an open validator fails. - assert!( - unbond_delegator_as_validator(&process, &finalize_store, &validator_private_key_1, delegator_address, rng) - .is_err() - ); + bond_public( + &process, + &finalize_store, + delegator_private_key, + &validator_address_1, + delegator_address, + delegator_amount, + rng, + ) + .unwrap(); // Set the validator `is_open` state to `false`. set_validator_state(&process, &finalize_store, &validator_private_key_1, false, rng).unwrap(); @@ -1336,19 +2243,27 @@ fn test_unbond_delegator_as_validator() { /* Ensure unbonding a delegator for another closed validator fails. */ // Ensure that unbonding a delegator as an open validator fails. + let block_height = rng.gen_range(1..100); + assert!( - unbond_delegator_as_validator(&process, &finalize_store, &validator_private_key_2, delegator_address, rng) + unbond_public(&process, &finalize_store, &withdrawal_private_key_2, delegator_address, 0u64, block_height, rng) .is_err() ); /* Ensure unbonding a delegator as a closed validator succeeds. */ // Ensure that unbonding a delegator as a closed validator succeeds. - unbond_delegator_as_validator(&process, &finalize_store, &validator_private_key_1, delegator_address, rng).unwrap(); + unbond_public(&process, &finalize_store, &withdrawal_private_key_1, delegator_address, 0u64, block_height, rng) + .unwrap(); - assert_eq!(committee_state(&finalize_store, &validator_address_1).unwrap(), Some((validator_amount, false))); + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!( + committee_state(&finalize_store, &validator_address_1).unwrap(), + Some((validator_amount, false, TEST_COMMISSION)) + ); assert_eq!(bond_state(&finalize_store, delegator_address).unwrap(), None); assert_eq!(unbond_state(&finalize_store, delegator_address).unwrap().unwrap().0, delegator_amount); + assert_eq!(withdraw_state(&finalize_store, delegator_address).unwrap(), Some(*delegator_address)); } #[test] @@ -1363,30 +2278,49 @@ fn test_claim_unbond() { // Initialize the validators and delegators. let (validators, _) = initialize_stakers(&finalize_store, 1, 0, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); - - // Fetch the account balance. - let public_balance = account_balance(&finalize_store, validator_address).unwrap(); + let (validator_private_key, (validator_address, _, withdrawal_private_key, withdrawal_address)) = + validators.first().unwrap(); // Perform the bond. - let validator_amount = 1_000_000_000_000u64; - bond_public(&process, &finalize_store, validator_private_key, validator_address, validator_amount, rng).unwrap(); + let validator_amount = MIN_VALIDATOR_STAKE; + bond_validator( + &process, + &finalize_store, + validator_private_key, + withdrawal_address, + validator_amount, + TEST_COMMISSION, + rng, + ) + .unwrap(); /* Ensure claiming an unbond fails when no unbond_state exists. */ - assert!(claim_unbond_public(&process, &finalize_store, validator_private_key, 1, rng).is_err()); + assert!(claim_unbond_public(&process, &finalize_store, validator_private_key, validator_address, 1, rng).is_err()); // Perform the unbond. - unbond_public(&process, &finalize_store, validator_private_key, validator_amount, 1, rng).unwrap(); + unbond_public(&process, &finalize_store, withdrawal_private_key, validator_address, validator_amount, 1, rng) + .unwrap(); let unbond_height = unbond_state(&finalize_store, validator_address).unwrap().unwrap().1; /* Ensure claiming an unbond before the unlock height fails. */ - assert!(claim_unbond_public(&process, &finalize_store, validator_private_key, unbond_height - 1, rng).is_err()); + assert!( + claim_unbond_public( + &process, + &finalize_store, + validator_private_key, + validator_address, + unbond_height - 1, + rng + ) + .is_err() + ); /* Ensure that claiming an unbond after the unlock height succeeds. */ - claim_unbond_public(&process, &finalize_store, validator_private_key, unbond_height, rng).unwrap(); - assert_eq!(account_balance(&finalize_store, validator_address).unwrap(), public_balance); + let random_private_key = PrivateKey::::new(rng).unwrap(); + claim_unbond_public(&process, &finalize_store, &random_private_key, validator_address, unbond_height, rng).unwrap(); + assert_eq!(account_balance(&finalize_store, withdrawal_address).unwrap(), validator_amount); } #[test] @@ -1401,28 +2335,29 @@ fn test_set_validator_state() { // Initialize the validators. let (validators, _) = initialize_stakers(&finalize_store, 1, 0, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); /* Ensure calling `set_validator_state` succeeds. */ // Perform the bond. - let amount = 1_000_000_000_000u64; - bond_public(&process, &finalize_store, validator_private_key, validator_address, amount, rng).unwrap(); + let amount = MIN_VALIDATOR_STAKE; + bond_validator(&process, &finalize_store, validator_private_key, withdrawal_address, amount, TEST_COMMISSION, rng) + .unwrap(); // Check that the validator state is correct. - assert_eq!(committee_state(&finalize_store, validator_address).unwrap(), Some((amount, true))); + assert_eq!(committee_state(&finalize_store, validator_address).unwrap(), Some((amount, true, TEST_COMMISSION))); // Set the validator `is_open` state to `false`. set_validator_state(&process, &finalize_store, validator_private_key, false, rng).unwrap(); - assert_eq!(committee_state(&finalize_store, validator_address).unwrap(), Some((amount, false))); + assert_eq!(committee_state(&finalize_store, validator_address).unwrap(), Some((amount, false, TEST_COMMISSION))); // Set the validator state `is_open` to `false` again. set_validator_state(&process, &finalize_store, validator_private_key, false, rng).unwrap(); - assert_eq!(committee_state(&finalize_store, validator_address).unwrap(), Some((amount, false))); + assert_eq!(committee_state(&finalize_store, validator_address).unwrap(), Some((amount, false, TEST_COMMISSION))); // Set the validator `is_open` state back to `true`. set_validator_state(&process, &finalize_store, validator_private_key, true, rng).unwrap(); - assert_eq!(committee_state(&finalize_store, validator_address).unwrap(), Some((amount, true))); + assert_eq!(committee_state(&finalize_store, validator_address).unwrap(), Some((amount, true, TEST_COMMISSION))); } #[test] @@ -1445,7 +2380,144 @@ fn test_set_validator_state_for_non_validator_fails() { } #[test] -fn test_bonding_to_closed_fails() { +fn test_bonding_existing_stakers_to_closed_validator() { + let rng = &mut TestRng::default(); + + // Construct the process. + let process = Process::::load().unwrap(); + + // Initialize a new finalize store. + let finalize_store = FinalizeStore::>::open(None).unwrap(); + + // Initialize the validators and delegators. + let (validators, delegators) = initialize_stakers(&finalize_store, 1, 1, rng).unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); + let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); + + // Retrieve the account balances. + let validator_public_balance = account_balance(&finalize_store, validator_address).unwrap(); + let delegator_public_balance = account_balance(&finalize_store, delegator_address).unwrap(); + + // Prepare the validator amount. + let validator_amount = MIN_VALIDATOR_STAKE; + // Perform the bond. + bond_validator( + &process, + &finalize_store, + validator_private_key, + withdrawal_address, + validator_amount, + TEST_COMMISSION, + rng, + ) + .unwrap(); + + // Check that the committee, bond, unbond, and withdraw states are correct. + assert_eq!( + committee_state(&finalize_store, validator_address).unwrap(), + Some((validator_amount, true, TEST_COMMISSION)) + ); + assert_eq!(bond_state(&finalize_store, validator_address).unwrap(), Some((*validator_address, validator_amount))); + assert_eq!(unbond_state(&finalize_store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&finalize_store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!( + account_balance(&finalize_store, validator_address).unwrap(), + validator_public_balance - validator_amount + ); + + // Bond the delegator to the validator. + let delegator_amount = MIN_DELEGATOR_STAKE; + bond_public( + &process, + &finalize_store, + delegator_private_key, + validator_address, + delegator_address, + delegator_amount, + rng, + ) + .unwrap(); + + // Check that the committee, bond, unbond, and withdraw states are correct. + let combined_amount = validator_amount + delegator_amount; + assert_eq!( + committee_state(&finalize_store, validator_address).unwrap(), + Some((combined_amount, true, TEST_COMMISSION)) + ); + assert_eq!(bond_state(&finalize_store, delegator_address).unwrap(), Some((*validator_address, delegator_amount))); + assert_eq!(unbond_state(&finalize_store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&finalize_store, delegator_address).unwrap(), Some(*delegator_address)); + assert_eq!( + account_balance(&finalize_store, delegator_address).unwrap(), + delegator_public_balance - delegator_amount + ); + + // Set the validator `is_open` state to `false`. + set_validator_state(&process, &finalize_store, validator_private_key, false, rng).unwrap(); + + /* Ensure bonding to a closed validator succeeds for the existing stakers. */ + + // Bond the validator again. + bond_validator( + &process, + &finalize_store, + validator_private_key, + withdrawal_address, + validator_amount, + TEST_COMMISSION, + rng, + ) + .unwrap(); + + // Check that the committee, bond, unbond, and withdraw states are correct. + let combined_amount = 2 * validator_amount + delegator_amount; + assert_eq!( + committee_state(&finalize_store, validator_address).unwrap(), + Some((combined_amount, false, TEST_COMMISSION)) + ); + assert_eq!( + bond_state(&finalize_store, validator_address).unwrap(), + Some((*validator_address, 2 * validator_amount)) + ); + assert_eq!(unbond_state(&finalize_store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&finalize_store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!( + account_balance(&finalize_store, validator_address).unwrap(), + validator_public_balance - (2 * validator_amount) + ); + + // Bond the delegator to the validator again. + bond_public( + &process, + &finalize_store, + delegator_private_key, + validator_address, + delegator_address, + delegator_amount, + rng, + ) + .unwrap(); + + // Check that the committee, bond, unbond, and withdraw states are correct. + let combined_amount = 2 * (validator_amount + delegator_amount); + assert_eq!( + committee_state(&finalize_store, validator_address).unwrap(), + Some((combined_amount, false, TEST_COMMISSION)) + ); + assert_eq!( + bond_state(&finalize_store, delegator_address).unwrap(), + Some((*validator_address, 2 * delegator_amount)) + ); + assert_eq!(unbond_state(&finalize_store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&finalize_store, delegator_address).unwrap(), Some(*delegator_address)); + assert_eq!( + account_balance(&finalize_store, delegator_address).unwrap(), + delegator_public_balance - (2 * delegator_amount) + ); +} + +#[test] +fn test_bonding_new_staker_to_closed_validator_fails() { let rng = &mut TestRng::default(); // Construct the process. @@ -1456,30 +2528,283 @@ fn test_bonding_to_closed_fails() { // Initialize the validators and delegators. let (validators, delegators) = initialize_stakers(&finalize_store, 1, 1, rng).unwrap(); - let (validator_private_key, (validator_address, _)) = validators.first().unwrap(); - let (delegator_private_key, (_, _)) = delegators.first().unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); + let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); /* Ensure bonding to a closed validator fails. */ // Perform the bond. - let amount = 1_000_000_000_000u64; - bond_public(&process, &finalize_store, validator_private_key, validator_address, amount, rng).unwrap(); + let amount = MIN_VALIDATOR_STAKE; + bond_validator(&process, &finalize_store, validator_private_key, withdrawal_address, amount, TEST_COMMISSION, rng) + .unwrap(); // Set the validator `is_open` state to `false`. set_validator_state(&process, &finalize_store, validator_private_key, false, rng).unwrap(); - // Ensure that the validator can't bond additional stake. - let validator_amount = 1_000_000_000_000u64; + // Ensure that new delegators can't bond to the validator. + let delegator_amount = MIN_DELEGATOR_STAKE; assert!( - bond_public(&process, &finalize_store, validator_private_key, validator_address, validator_amount, rng) - .is_err() + bond_public( + &process, + &finalize_store, + delegator_private_key, + validator_address, + delegator_address, + delegator_amount, + rng + ) + .is_err() ); +} + +// All the the above test cases use the same staker and withdraw addresses. +// The following test check the functionality of the withdraw address using a different staker and withdraw address. + +#[test] +fn test_claim_unbond_public_to_withdrawal_address() { + let rng = &mut TestRng::default(); + + // Construct the process. + let process = Process::::load().unwrap(); + + // Initialize a new finalize store. + let (store, _temp_dir) = sample_finalize_store!(); + + // Initialize the validators and delegators. + let (validators, delegators) = initialize_stakers(&store, 1, 1, rng).unwrap(); + let (validator_private_key, (validator_address, _, withdrawal_private_key, withdrawal_address)) = + validators.first().unwrap(); + let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); + + // Retrieve the account balance. + let validator_balance = account_balance(&store, validator_address).unwrap(); + let delegator_balance = account_balance(&store, delegator_address).unwrap(); + + // Initialize new withdrawal addresses. + let delegator_withdraw_private_key = PrivateKey::::new(rng).unwrap(); + let delegator_withdrawal_address = Address::try_from(&delegator_withdraw_private_key).unwrap(); - // Ensure that delegators can't bond to the validator. - let delegator_amount = 1_000_000u64; + // Bond the validator the withdrawal address. + let validator_amount = MIN_VALIDATOR_STAKE; + bond_validator(&process, &store, validator_private_key, withdrawal_address, validator_amount, TEST_COMMISSION, rng) + .unwrap(); + + // Bond the delegator to the validator. + let delegator_amount = MIN_DELEGATOR_STAKE; + bond_public( + &process, + &store, + delegator_private_key, + validator_address, + &delegator_withdrawal_address, + delegator_amount, + rng, + ) + .unwrap(); + + // Unbond the delegator completely. + unbond_public(&process, &store, &delegator_withdraw_private_key, delegator_address, delegator_amount, 1, rng) + .unwrap(); + let unbond_height = unbond_state(&store, delegator_address).unwrap().unwrap().1; + + // Check that the bond, unbond, and withdraw states are correct. + assert_eq!(account_balance(&store, delegator_address).unwrap(), delegator_balance - delegator_amount); + assert!(account_balance(&store, &delegator_withdrawal_address).is_err()); + assert_eq!(bond_state(&store, delegator_address).unwrap(), None); + assert_eq!(unbond_state(&store, delegator_address).unwrap().unwrap().0, delegator_amount); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(delegator_withdrawal_address)); + + /* Ensure that claiming an unbond after the unlock height succeeds. */ + claim_unbond_public(&process, &store, delegator_private_key, delegator_address, unbond_height, rng).unwrap(); + + // Check that the bond, unbond, and withdraw states are correct. + assert_eq!(account_balance(&store, delegator_address).unwrap(), delegator_balance - delegator_amount); + assert_eq!(account_balance(&store, &delegator_withdrawal_address).unwrap(), delegator_amount); + assert_eq!(bond_state(&store, delegator_address).unwrap(), None); + assert_eq!(unbond_state(&store, delegator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), None); + + // Unbond the validator completely. + unbond_public(&process, &store, withdrawal_private_key, validator_address, validator_amount, unbond_height, rng) + .unwrap(); + let unbond_height = unbond_state(&store, validator_address).unwrap().unwrap().1; + + // Check that the bond, unbond, and withdraw states are correct. + assert_eq!(account_balance(&store, validator_address).unwrap(), validator_balance - validator_amount); + assert!(account_balance(&store, withdrawal_address).is_err()); + assert_eq!(bond_state(&store, validator_address).unwrap(), None); + assert_eq!(unbond_state(&store, validator_address).unwrap().unwrap().0, validator_amount); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + + /* Ensure that claiming an unbond after the unlock height succeeds. */ + claim_unbond_public(&process, &store, validator_private_key, validator_address, unbond_height, rng).unwrap(); + + // Check that the bond, unbond, and withdraw states are correct. + assert_eq!(account_balance(&store, validator_address).unwrap(), validator_balance - validator_amount); + assert_eq!(account_balance(&store, withdrawal_address).unwrap(), validator_amount); + assert_eq!(bond_state(&store, validator_address).unwrap(), None); + assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), None); +} + +#[test] +fn test_bonding_multiple_stakers_to_same_withdrawal_address() { + let rng = &mut TestRng::default(); + + // Construct the process. + let process = Process::::load().unwrap(); + + // Initialize a new finalize store. + let (store, _temp_dir) = sample_finalize_store!(); + + // Initialize the validators and delegators. + let (validators, delegators) = initialize_stakers(&store, 1, 1, rng).unwrap(); + let (validator_private_key, (validator_address, _, _, withdrawal_address)) = validators.first().unwrap(); + let (delegator_private_key, (delegator_address, _)) = delegators.first().unwrap(); + + // Bond the validator the withdrawal address. + let validator_amount = MIN_VALIDATOR_STAKE; + bond_validator(&process, &store, validator_private_key, withdrawal_address, validator_amount, TEST_COMMISSION, rng) + .unwrap(); + + // Prepare the delegator amount. + let delegator_amount = MIN_DELEGATOR_STAKE; + // Bond the delegator the same withdrawal address. + bond_public(&process, &store, delegator_private_key, validator_address, withdrawal_address, delegator_amount, rng) + .unwrap(); + + // Check that the withdraw state is correct. + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + assert_eq!(withdraw_state(&store, delegator_address).unwrap(), Some(*withdrawal_address)); +} + +#[test] +fn test_claim_unbond_public_removes_withdraw_mapping() { + let rng = &mut TestRng::default(); + + // Construct the process. + let process = Process::::load().unwrap(); + + // Initialize a new finalize store. + let (store, _temp_dir) = sample_finalize_store!(); + + // Initialize the validators and delegators. + let (validators, _) = initialize_stakers(&store, 1, 0, rng).unwrap(); + let (validator_private_key, (validator_address, _, withdrawal_private_key, withdrawal_address)) = + validators.first().unwrap(); + + // Retrieve the account balance. + let validator_balance = account_balance(&store, validator_address).unwrap(); + + // Bond the validator the withdrawal address. + let validator_amount = MIN_VALIDATOR_STAKE * 2; + bond_validator(&process, &store, validator_private_key, withdrawal_address, validator_amount, TEST_COMMISSION, rng) + .unwrap(); + + // Unbond half of the validator's stake. + let unbond_amount = validator_amount / 2; + unbond_public(&process, &store, withdrawal_private_key, validator_address, unbond_amount, 1, rng).unwrap(); + let unbond_height = unbond_state(&store, validator_address).unwrap().unwrap().1; + + /* Ensure that claiming an unbond after the unlock height succeeds. */ + claim_unbond_public(&process, &store, validator_private_key, validator_address, unbond_height, rng).unwrap(); + + // Check that the account, bond, unbond, and withdraw states are correct. + assert_eq!(account_balance(&store, validator_address).unwrap(), validator_balance - validator_amount); + assert_eq!(account_balance(&store, withdrawal_address).unwrap(), unbond_amount); + assert_eq!( + bond_state(&store, validator_address).unwrap(), + Some((*validator_address, validator_amount - unbond_amount)) + ); + assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), Some(*withdrawal_address)); + + // Unbond the remaining validator stake. + unbond_public(&process, &store, withdrawal_private_key, validator_address, unbond_amount, unbond_height, rng) + .unwrap(); + let unbond_height = unbond_state(&store, validator_address).unwrap().unwrap().1; + + /* Ensure that claiming an unbond after the unlock height succeeds. */ + claim_unbond_public(&process, &store, validator_private_key, validator_address, unbond_height, rng).unwrap(); + + // Check that the account, bond, unbond, and withdraw states are correct. + // The withdraw state should be removed after the last unbond is claimed. + assert_eq!(account_balance(&store, validator_address).unwrap(), validator_balance - validator_amount); + assert_eq!(account_balance(&store, withdrawal_address).unwrap(), validator_amount); + assert_eq!(bond_state(&store, validator_address).unwrap(), None); + assert_eq!(unbond_state(&store, validator_address).unwrap(), None); + assert_eq!(withdraw_state(&store, validator_address).unwrap(), None); +} + +#[test] +fn test_bond_validator_to_different_withdraw_address_fails() { + let rng = &mut TestRng::default(); + + // Construct the process. + let process = Process::::load().unwrap(); + + // Initialize a new finalize store. + let (store, _temp_dir) = sample_finalize_store!(); + + // Initialize the validators and delegators. + let (validators, _) = initialize_stakers(&store, 1, 0, rng).unwrap(); + let (validator_private_key, (_, _, _, withdrawal_address)) = validators.first().unwrap(); + + // Bond the validator the withdrawal address. + let validator_amount = MIN_VALIDATOR_STAKE; + bond_validator(&process, &store, validator_private_key, withdrawal_address, validator_amount, TEST_COMMISSION, rng) + .unwrap(); + + // Initialize a new withdraw address. + let new_withdraw_private_key = PrivateKey::::new(rng).unwrap(); + let new_withdraw_private_key = Address::try_from(&new_withdraw_private_key).unwrap(); + + // Ensure that bonding to a different withdraw address fails. assert!( - bond_public(&process, &finalize_store, delegator_private_key, validator_address, delegator_amount, rng) - .is_err() + bond_validator( + &process, + &store, + validator_private_key, + &new_withdraw_private_key, + validator_amount, + TEST_COMMISSION, + rng + ) + .is_err() + ); +} + +#[test] +fn test_bond_validator_with_different_commission_fails() { + let rng = &mut TestRng::default(); + + // Construct the process. + let process = Process::::load().unwrap(); + + // Initialize a new finalize store. + let (store, _temp_dir) = sample_finalize_store!(); + + // Initialize the validators and delegators. + let (validators, _) = initialize_stakers(&store, 1, 0, rng).unwrap(); + let (validator_private_key, (_, _, _, withdrawal_address)) = validators.first().unwrap(); + + // Bond the validator the withdrawal address. + let validator_amount = MIN_VALIDATOR_STAKE; + bond_validator(&process, &store, validator_private_key, withdrawal_address, validator_amount, TEST_COMMISSION, rng) + .unwrap(); + + // Ensure that bonding to a different withdraw address fails. + assert!( + bond_validator( + &process, + &store, + validator_private_key, + withdrawal_address, + validator_amount, + TEST_COMMISSION + 1, + rng + ) + .is_err() ); } @@ -1520,14 +2845,20 @@ mod sanity_checks { let program_id = *program.id(); // Retrieve the input types. let input_types = program.get_function(&function_name).unwrap().input_types(); + // Sample 'root_tvk'. + let root_tvk = None; + // Sample 'is_root'. + let is_root = true; // Compute the request. - let request = Request::sign(private_key, program_id, function_name, inputs.iter(), &input_types, rng).unwrap(); + let request = + Request::sign(private_key, program_id, function_name, inputs.iter(), &input_types, root_tvk, is_root, rng) + .unwrap(); // Initialize the assignments. let assignments = Assignments::::default(); // Initialize the call stack. - let call_stack = CallStack::CheckDeployment(vec![request], *private_key, assignments.clone()); + let call_stack = CallStack::CheckDeployment(vec![request], *private_key, assignments.clone(), None, None); // Synthesize the circuit. - let _response = stack.execute_function::(call_stack, None, rng).unwrap(); + let _response = stack.execute_function::(call_stack, None, None, rng).unwrap(); // Retrieve the assignment. let assignment = assignments.read().last().unwrap().0.clone(); assignment @@ -1560,10 +2891,10 @@ mod sanity_checks { // Compute the assignment. let assignment = get_assignment::<_, CurrentAleo>(stack, &private_key, function_name, &[r0, r1, r2], rng); - assert_eq!(15, assignment.num_public()); - assert_eq!(50681, assignment.num_private()); - assert_eq!(50729, assignment.num_constraints()); - assert_eq!((98547, 109769, 77341), assignment.num_nonzeros()); + assert_eq!(16, assignment.num_public()); + assert_eq!(50956, assignment.num_private()); + assert_eq!(51002, assignment.num_constraints()); + assert_eq!((99540, 111472, 77613), assignment.num_nonzeros()); } #[test] @@ -1588,10 +2919,38 @@ mod sanity_checks { // Compute the assignment. let assignment = get_assignment::<_, CurrentAleo>(stack, &private_key, function_name, &[r0, r1], rng); - assert_eq!(10, assignment.num_public()); - assert_eq!(12043, assignment.num_private()); - assert_eq!(12052, assignment.num_constraints()); - assert_eq!((27250, 36303, 16407), assignment.num_nonzeros()); + assert_eq!(11, assignment.num_public()); + assert_eq!(12318, assignment.num_private()); + assert_eq!(12325, assignment.num_constraints()); + assert_eq!((28243, 38006, 16679), assignment.num_nonzeros()); + } + + #[test] + fn test_sanity_check_transfer_public_as_signer() { + let rng = &mut TestRng::default(); + + // Initialize a new signer account. + let private_key = PrivateKey::::new(rng).unwrap(); + let signer = Address::try_from(&private_key).unwrap(); + + // Construct a new process. + let process = Process::load().unwrap(); + // Retrieve the stack. + let stack = process.get_stack(ProgramID::from_str("credits.aleo").unwrap()).unwrap(); + + // Declare the function name. + let function_name = Identifier::from_str("transfer_public_as_signer").unwrap(); + + // Declare the inputs. + let r0 = Value::::from_str(&format!("{signer}")).unwrap(); + let r1 = Value::::from_str("1_500_000_000_000_000_u64").unwrap(); + + // Compute the assignment. + let assignment = get_assignment::<_, CurrentAleo>(stack, &private_key, function_name, &[r0, r1], rng); + assert_eq!(11, assignment.num_public()); + assert_eq!(12323, assignment.num_private()); + assert_eq!(12330, assignment.num_constraints()); + assert_eq!((28257, 38029, 16684), assignment.num_nonzeros()); } #[test] @@ -1622,10 +2981,10 @@ mod sanity_checks { // Compute the assignment. let assignment = get_assignment::<_, CurrentAleo>(stack, &private_key, function_name, &[r0, r1, r2, r3], rng); - assert_eq!(14, assignment.num_public()); - assert_eq!(37840, assignment.num_private()); - assert_eq!(37878, assignment.num_constraints()); - assert_eq!((72163, 80588, 56623), assignment.num_nonzeros()); + assert_eq!(15, assignment.num_public()); + assert_eq!(38115, assignment.num_private()); + assert_eq!(38151, assignment.num_constraints()); + assert_eq!((73156, 82291, 56895), assignment.num_nonzeros()); } #[test] @@ -1650,9 +3009,9 @@ mod sanity_checks { // Compute the assignment. let assignment = get_assignment::<_, CurrentAleo>(stack, &private_key, function_name, &[r0, r1, r2], rng); - assert_eq!(11, assignment.num_public()); - assert_eq!(12645, assignment.num_private()); - assert_eq!(12657, assignment.num_constraints()); - assert_eq!((29594, 39585, 16941), assignment.num_nonzeros()); + assert_eq!(12, assignment.num_public()); + assert_eq!(12920, assignment.num_private()); + assert_eq!(12930, assignment.num_constraints()); + assert_eq!((30587, 41288, 17213), assignment.num_nonzeros()); } } diff --git a/synthesizer/process/src/tests/test_execute.rs b/synthesizer/process/src/tests/test_execute.rs index 1837b54967..3af7055726 100644 --- a/synthesizer/process/src/tests/test_execute.rs +++ b/synthesizer/process/src/tests/test_execute.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,35 +14,36 @@ // limitations under the License. use crate::{ - traits::{StackEvaluate, StackExecute}, CallStack, Process, + Stack, Trace, + traits::{StackEvaluate, StackExecute}, }; -use circuit::{network::AleoV0, Aleo}; +use circuit::{Aleo, network::AleoV0}; use console::{ account::{Address, PrivateKey, ViewKey}, - network::{prelude::*, Testnet3}, + network::{MainnetV0, prelude::*}, program::{Identifier, Literal, Plaintext, ProgramID, Record, Value}, types::{Field, U64}, }; -use ledger_block::Fee; +use ledger_block::{Fee, Transaction}; use ledger_query::Query; use ledger_store::{ - helpers::memory::{BlockMemory, FinalizeMemory}, BlockStorage, BlockStore, FinalizeStorage, FinalizeStore, + helpers::memory::{BlockMemory, FinalizeMemory}, }; -use synthesizer_program::{FinalizeGlobalState, FinalizeStoreTrait, Program}; +use synthesizer_program::{FinalizeGlobalState, FinalizeStoreTrait, Program, StackProgram}; use synthesizer_snark::UniversalSRS; use indexmap::IndexMap; use parking_lot::RwLock; use std::sync::Arc; -type CurrentNetwork = Testnet3; +type CurrentNetwork = MainnetV0; type CurrentAleo = AleoV0; /// Samples a new finalize state. @@ -395,7 +397,7 @@ output r4 as field.private;", // Re-run to ensure state continues to work. let trace = Arc::new(RwLock::new(Trace::new())); let call_stack = CallStack::execute(authorization, trace).unwrap(); - let response = stack.execute_function::(call_stack, None, rng).unwrap(); + let response = stack.execute_function::(call_stack, None, None, rng).unwrap(); let candidate = response.outputs(); assert_eq!(3, candidate.len()); assert_eq!(r2, candidate[0]); @@ -477,7 +479,7 @@ output r1 as token.record;", } #[test] -fn test_process_execute_transfer_public() { +fn test_process_execute_transfer_public_to_private() { // Initialize a new program. let program = Program::::credits().unwrap(); @@ -1926,7 +1928,7 @@ function a: // Construct the expected transition order. let expected_order = [ - (program0.id(), Identifier::::from_str("c").unwrap()), + (program0.id(), Identifier::::from_str("c").unwrap()), (program1.id(), Identifier::from_str("b").unwrap()), (program2.id(), Identifier::from_str("a").unwrap()), ]; @@ -2108,16 +2110,16 @@ fn test_complex_execution_order() { // Construct the expected execution order. let expected_order = [ - (program0.id(), Identifier::::from_str("c").unwrap()), - (program1.id(), Identifier::::from_str("d").unwrap()), - (program2.id(), Identifier::::from_str("b").unwrap()), - (program0.id(), Identifier::::from_str("c").unwrap()), - (program1.id(), Identifier::::from_str("d").unwrap()), - (program2.id(), Identifier::::from_str("b").unwrap()), - (program1.id(), Identifier::::from_str("d").unwrap()), - (program0.id(), Identifier::::from_str("c").unwrap()), - (program3.id(), Identifier::::from_str("e").unwrap()), - (program4.id(), Identifier::::from_str("a").unwrap()), + (program0.id(), Identifier::::from_str("c").unwrap()), + (program1.id(), Identifier::::from_str("d").unwrap()), + (program2.id(), Identifier::::from_str("b").unwrap()), + (program0.id(), Identifier::::from_str("c").unwrap()), + (program1.id(), Identifier::::from_str("d").unwrap()), + (program2.id(), Identifier::::from_str("b").unwrap()), + (program1.id(), Identifier::::from_str("d").unwrap()), + (program0.id(), Identifier::::from_str("c").unwrap()), + (program3.id(), Identifier::::from_str("e").unwrap()), + (program4.id(), Identifier::::from_str("a").unwrap()), ]; for (transition, (expected_program_id, expected_function_name)) in trace.transitions().iter().zip_eq(expected_order.iter()) @@ -2375,7 +2377,7 @@ fn test_process_deploy_credits_program() { let deployment = empty_process.deploy::(&program, rng).unwrap(); // Ensure the deployment is valid on the empty process. - assert!(empty_process.verify_deployment::(&deployment, rng).is_ok()); + empty_process.verify_deployment::(&deployment, rng).unwrap(); // Ensure the deployment is not valid on the standard process. assert!(process.verify_deployment::(&deployment, rng).is_err()); @@ -2399,7 +2401,7 @@ function compute: let deployment = empty_process.deploy::(&program, rng).unwrap(); // Ensure the deployment is valid on the empty process. - assert!(empty_process.verify_deployment::(&deployment, rng).is_ok()); + empty_process.verify_deployment::(&deployment, rng).unwrap(); // Ensure the deployment is not valid on the standard process. assert!(process.verify_deployment::(&deployment, rng).is_err()); } @@ -2483,3 +2485,164 @@ function {function_name}: assert_ne!(execution_1.peek().unwrap().id(), execution_2.peek().unwrap().id()); assert_ne!(execution_1.to_execution_id().unwrap(), execution_2.to_execution_id().unwrap()); } + +#[test] +fn test_long_import_chain() { + // Initialize a new program. + let program = Program::::from_str( + r" + program test0.aleo; + function c:", + ) + .unwrap(); + + // Construct the process. + let mut process = crate::test_helpers::sample_process(&program); + + // Add `MAX_PROGRAM_DEPTH` programs to the process. + for i in 1..=CurrentNetwork::MAX_PROGRAM_DEPTH { + println!("Adding program {i}"); + // Initialize a new program. + let program = Program::from_str(&format!( + " + import test{}.aleo; + program test{}.aleo; + function c:", + i - 1, + i + )) + .unwrap(); + // Add the program to the process. + process.add_program(&program).unwrap(); + } + + // Add the `MAX_PROGRAM_DEPTH + 1` program to the process, which should fail. + let program = Program::from_str(&format!( + " + import test{}.aleo; + program test{}.aleo; + function c:", + CurrentNetwork::MAX_PROGRAM_DEPTH, + CurrentNetwork::MAX_PROGRAM_DEPTH + 1 + )) + .unwrap(); + let result = process.add_program(&program); + assert!(result.is_err()); +} + +#[test] +fn test_long_import_chain_with_calls() { + // Initialize a new program. + let program = Program::::from_str( + r" + program test0.aleo; + function c:", + ) + .unwrap(); + + // Construct the process. + let mut process = crate::test_helpers::sample_process(&program); + + // Check that the number of calls, up to `Transaction::MAX_TRANSITIONS - 1`, is correct. + for i in 1..(Transaction::::MAX_TRANSITIONS - 1) { + println!("Adding program {}", i); + // Initialize a new program. + let program = Program::from_str(&format!( + " + import test{}.aleo; + program test{}.aleo; + function c: + call test{}.aleo/c;", + i - 1, + i, + i - 1 + )) + .unwrap(); + // Add the program to the process. + process.add_program(&program).unwrap(); + // Check that the number of calls is correct. + let stack = process.get_stack(program.id()).unwrap(); + let number_of_calls = stack.get_number_of_calls(program.functions().into_iter().next().unwrap().0).unwrap(); + assert_eq!(number_of_calls, i + 1); + } + + // Check that `Transaction::MAX_TRANSITIONS - 1`-th call fails. + let program = Program::from_str(&format!( + " + import test{}.aleo; + program test{}.aleo; + function c: + call test{}.aleo/c;", + Transaction::::MAX_TRANSITIONS - 2, + Transaction::::MAX_TRANSITIONS - 1, + Transaction::::MAX_TRANSITIONS - 2 + )) + .unwrap(); + let result = process.add_program(&program); + assert!(result.is_err()) +} + +#[test] +fn test_max_imports() { + // Construct the process. + let mut process = Process::::load().unwrap(); + + // Add `MAX_IMPORTS` programs to the process. + for i in 0..CurrentNetwork::MAX_IMPORTS { + println!("Adding program {i}"); + // Initialize a new program. + let program = Program::from_str(&format!("program test{i}.aleo; function c:")).unwrap(); + // Add the program to the process. + process.add_program(&program).unwrap(); + } + + // Add a program importing all `MAX_IMPORTS` programs, which should pass. + let import_string = + (0..CurrentNetwork::MAX_IMPORTS).map(|i| format!("import test{}.aleo;", i)).collect::>().join(" "); + let program = + Program::from_str(&format!("{import_string}program test{}.aleo; function c:", CurrentNetwork::MAX_IMPORTS)) + .unwrap(); + process.add_program(&program).unwrap(); + + // Attempt to construct a program importing `MAX_IMPORTS + 1` programs, which should fail. + let import_string = + (0..CurrentNetwork::MAX_IMPORTS + 1).map(|i| format!("import test{}.aleo;", i)).collect::>().join(" "); + let result = Program::::from_str(&format!( + "{import_string}program test{}.aleo; function c:", + CurrentNetwork::MAX_IMPORTS + 1 + )); + assert!(result.is_err()); +} + +#[test] +fn test_program_exceeding_transaction_spend_limit() { + // Construct a finalize body whose finalize cost is excessively large. + let mut finalize_body = r" + cast 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 into r0 as [u8; 16u32]; + cast r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 into r1 as [[u8; 16u32]; 16u32]; + cast r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 into r2 as [[[u8; 16u32]; 16u32]; 16u32];" + .to_string(); + (3..500).for_each(|i| { + finalize_body.push_str(&format!("hash.bhp256 r2 into r{i} as field;\n")); + }); + // Construct the program. + let program = Program::from_str(&format!( + r"program test_max_spend_limit.aleo; + function foo: + async foo into r0; + output r0 as test_max_spend_limit.aleo/foo.future; + finalize foo:{finalize_body}", + )) + .unwrap(); + + // Initialize a `Process`. + let mut process = Process::::load().unwrap(); + + // Attempt to add the program to the process, which should fail. + let result = process.add_program(&program); + assert!(result.is_err()); + + // Attempt to initialize a `Stack` directly with the program, which should fail. + let result = Stack::initialize(&process, &program); + assert!(result.is_err()); +} diff --git a/synthesizer/process/src/trace/call_metrics/mod.rs b/synthesizer/process/src/trace/call_metrics/mod.rs index d45fec6d94..69d7bb26ec 100644 --- a/synthesizer/process/src/trace/call_metrics/mod.rs +++ b/synthesizer/process/src/trace/call_metrics/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/trace/inclusion/mod.rs b/synthesizer/process/src/trace/inclusion/mod.rs index b61b9d0f77..0517a29460 100644 --- a/synthesizer/process/src/trace/inclusion/mod.rs +++ b/synthesizer/process/src/trace/inclusion/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,7 +20,7 @@ use crate::Stack; use console::{ network::prelude::*, - program::{InputID, StatePath, TransactionLeaf, TransitionLeaf, TransitionPath, TRANSACTION_DEPTH}, + program::{InputID, StatePath, TRANSACTION_DEPTH, TransactionLeaf, TransitionLeaf, TransitionPath}, types::{Field, Group}, }; use ledger_block::{Input, Output, Transaction, Transition}; diff --git a/synthesizer/process/src/trace/inclusion/prepare.rs b/synthesizer/process/src/trace/inclusion/prepare.rs index cdde9be46f..9fefd076a8 100644 --- a/synthesizer/process/src/trace/inclusion/prepare.rs +++ b/synthesizer/process/src/trace/inclusion/prepare.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/trace/mod.rs b/synthesizer/process/src/trace/mod.rs index 988be7ad29..8a994d79c7 100644 --- a/synthesizer/process/src/trace/mod.rs +++ b/synthesizer/process/src/trace/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -308,15 +309,16 @@ impl Trace { let batch_inclusion_inputs = Inclusion::prepare_verifier_inputs(global_state_root, transitions)?; // Insert the batch of inclusion verifier inputs to the verifier inputs. if !batch_inclusion_inputs.is_empty() { - // Fetch the inclusion verifying key. - let verifying_key = VerifyingKey::::new(N::inclusion_verifying_key().clone()); + // Retrieve the inclusion verifying key. + let verifying_key = N::inclusion_verifying_key().clone(); + // Retrieve the number of public and private variables. + // Note: This number does *NOT* include the number of constants. This is safe because + // this program is never deployed, as it is a first-class citizen of the protocol. + let num_variables = verifying_key.circuit_info.num_public_and_private_variables as u64; // Insert the inclusion verifier inputs. - verifier_inputs.push((verifying_key, batch_inclusion_inputs)); + verifier_inputs.push((VerifyingKey::::new(verifying_key, num_variables), batch_inclusion_inputs)); } // Verify the proof. - match VerifyingKey::verify_batch(locator, verifier_inputs, proof) { - true => Ok(()), - false => bail!("Failed to verify proof"), - } + VerifyingKey::verify_batch(locator, verifier_inputs, proof).map_err(|e| anyhow!("Failed to verify proof - {e}")) } } diff --git a/synthesizer/process/src/traits/mod.rs b/synthesizer/process/src/traits/mod.rs index c82b4ffd59..7d7eeddd4d 100644 --- a/synthesizer/process/src/traits/mod.rs +++ b/synthesizer/process/src/traits/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -72,6 +73,7 @@ pub trait StackExecute { &self, call_stack: CallStack, console_caller: Option>, + root_tvk: Option>, rng: &mut R, ) -> Result>; } diff --git a/synthesizer/process/src/verify_deployment.rs b/synthesizer/process/src/verify_deployment.rs index f499fdebcc..3aca6313ab 100644 --- a/synthesizer/process/src/verify_deployment.rs +++ b/synthesizer/process/src/verify_deployment.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/process/src/verify_execution.rs b/synthesizer/process/src/verify_execution.rs index f4c57cf744..da4d9fbe89 100644 --- a/synthesizer/process/src/verify_execution.rs +++ b/synthesizer/process/src/verify_execution.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -73,16 +74,10 @@ impl Process { // Ensure the number of outputs is within the allowed range. ensure!(transition.outputs().len() <= N::MAX_OUTPUTS, "Transition exceeded maximum number of outputs"); - // Compute the function ID as `Hash(network_id, program_id, function_name)`. - let function_id = N::hash_bhp1024( - &( - U16::::new(N::ID), - transition.program_id().name(), - transition.program_id().network(), - transition.function_name(), - ) - .to_bits_le(), - )?; + // Retrieve the network ID. + let network_id = U16::new(N::ID); + // Compute the function ID. + let function_id = compute_function_id(&network_id, transition.program_id(), transition.function_name())?; // Ensure each input is valid. if transition @@ -97,6 +92,7 @@ impl Process { // Ensure each output is valid. let num_inputs = transition.inputs().len(); + let num_outputs = transition.outputs().len(); if transition .outputs() .iter() @@ -112,6 +108,18 @@ impl Process { // Retrieve the function from the stack. let function = stack.get_function(transition.function_name())?; + // Ensure the number of inputs and outputs match the expected number in the function. + ensure!(function.inputs().len() == num_inputs, "The number of transition inputs is incorrect"); + ensure!(function.outputs().len() == num_outputs, "The number of transition outputs is incorrect"); + + // Ensure the input and output types are equivalent to the ones defined in the function. + // We only need to check that the variant type matches because we already check the hashes in + // the `Input::verify` and `Output::verify` functions. + let transition_input_variants = transition.inputs().iter().map(Input::variant).collect::>(); + let transition_output_variants = transition.outputs().iter().map(Output::variant).collect::>(); + ensure!(function.input_variants() == transition_input_variants, "The input variants do not match"); + ensure!(function.output_variants() == transition_output_variants, "The output variants do not match"); + // Retrieve the parent program ID. // Note: The last transition in the execution does not have a parent, by definition. let parent = reverse_call_graph.get(transition.id()).and_then(|tid| execution.get_program_id(tid)); @@ -137,6 +145,16 @@ impl Process { let num_instances = verifier_inputs.values().map(|(_, inputs)| inputs.len()).sum::(); // Ensure the number of instances matches the number of transitions. ensure!(num_instances == execution.transitions().len(), "The number of verifier instances is incorrect"); + // Ensure the same signer is used for all transitions. + execution.transitions().try_fold(None, |signer, transition| { + Ok(match signer { + None => Some(transition.scm()), + Some(signer) => { + ensure!(signer == transition.scm(), "The transitions did not use the same signer"); + Some(signer) + } + }) + })?; // Construct the list of verifier inputs. let verifier_inputs: Vec<_> = verifier_inputs.values().cloned().collect(); @@ -173,7 +191,7 @@ impl Process { let (parent_x, parent_y) = parent.to_address()?.to_xy_coordinates(); // [Inputs] Construct the verifier inputs to verify the proof. - let mut inputs = vec![N::Field::one(), *tpk_x, *tpk_y, **transition.tcm()]; + let mut inputs = vec![N::Field::one(), *tpk_x, *tpk_y, **transition.tcm(), **transition.scm()]; // [Inputs] Extend the verifier inputs with the input IDs. inputs.extend(transition.inputs().iter().flat_map(|input| input.verifier_inputs())); // [Inputs] Extend the verifier inputs with the public inputs for 'self.caller'. diff --git a/synthesizer/process/src/verify_fee.rs b/synthesizer/process/src/verify_fee.rs index 5d7a9455c4..7f4d8e1fe9 100644 --- a/synthesizer/process/src/verify_fee.rs +++ b/synthesizer/process/src/verify_fee.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,13 +22,14 @@ impl Process { pub fn verify_fee(&self, fee: &Fee, deployment_or_execution_id: Field) -> Result<()> { let timer = timer!("Process::verify_fee"); + // Retrieve the stack. + let stack = self.get_stack(fee.program_id())?; + // Retrieve the function from the stack. + let function = stack.get_function(fee.function_name())?; + #[cfg(debug_assertions)] { println!("Verifying fee from {}/{}...", fee.program_id(), fee.function_name()); - // Retrieve the stack. - let stack = self.get_stack(fee.program_id())?; - // Retrieve the function from the stack. - let function = stack.get_function(fee.function_name())?; // Ensure the number of function calls in this function is 1. if stack.get_number_of_calls(function.name())? != 1 { bail!("The number of function calls in '{}/{}' should be 1", stack.program_id(), function.name()) @@ -51,6 +53,14 @@ impl Process { // Ensure the number of outputs is within the allowed range. ensure!(fee.outputs().len() <= N::MAX_INPUTS, "Fee exceeded maximum number of outputs"); + // Ensure the input and output types are equivalent to the ones defined in the function. + // We only need to check that the variant type matches because we already check the hashes in + // the `Input::verify` and `Output::verify` functions. + let fee_input_variants = fee.inputs().iter().map(Input::variant).collect::>(); + let fee_output_variants = fee.outputs().iter().map(Output::variant).collect::>(); + ensure!(function.input_variants() == fee_input_variants, "The fee input variants do not match"); + ensure!(function.output_variants() == fee_output_variants, "The fee output variants do not match"); + // Retrieve the candidate deployment or execution ID. let Ok(candidate_id) = fee.deployment_or_execution_id() else { bail!("Failed to get the deployment or execution ID in the fee transition") @@ -76,11 +86,10 @@ impl Process { fn verify_fee_private(&self, fee: &&Fee) -> Result<()> { let timer = timer!("Process::verify_fee_private"); - // Compute the function ID as `Hash(network_id, program_id, function_name)`. - let function_id = N::hash_bhp1024( - &(U16::::new(N::ID), fee.program_id().name(), fee.program_id().network(), fee.function_name()) - .to_bits_le(), - )?; + // Retrieve the network ID. + let network_id = U16::new(N::ID); + // Compute the function ID. + let function_id = compute_function_id(&network_id, fee.program_id(), fee.function_name())?; // Ensure the fee contains 1 input record. ensure!( @@ -120,7 +129,7 @@ impl Process { let (parent_x, parent_y) = fee.program_id().to_address()?.to_xy_coordinates(); // Construct the public inputs to verify the proof. - let mut inputs = vec![N::Field::one(), *tpk_x, *tpk_y, **fee.tcm()]; + let mut inputs = vec![N::Field::one(), *tpk_x, *tpk_y, **fee.tcm(), **fee.scm()]; // Extend the inputs with the input IDs. inputs.extend(fee.inputs().iter().flat_map(|input| input.verifier_inputs())); // Extend the verifier inputs with the public inputs for 'self.caller'. @@ -146,11 +155,10 @@ impl Process { fn verify_fee_public(&self, fee: &&Fee) -> Result<()> { let timer = timer!("Process::verify_fee_public"); - // Compute the function ID as `Hash(network_id, program_id, function_name)`. - let function_id = N::hash_bhp1024( - &(U16::::new(N::ID), fee.program_id().name(), fee.program_id().network(), fee.function_name()) - .to_bits_le(), - )?; + // Retrieve the network ID. + let network_id = U16::new(N::ID); + // Compute the function ID. + let function_id = compute_function_id(&network_id, fee.program_id(), fee.function_name())?; // Ensure the fee contains all public inputs. ensure!( @@ -166,7 +174,7 @@ impl Process { } lap!(timer, "Verify the inputs"); - // Ensure there are is one output. + // Ensure there is one output. ensure!( fee.outputs().len() == 1, "The number of outputs in the fee transition should be 1, found {}", @@ -190,7 +198,7 @@ impl Process { let (parent_x, parent_y) = fee.program_id().to_address()?.to_xy_coordinates(); // Construct the public inputs to verify the proof. - let mut inputs = vec![N::Field::one(), *tpk_x, *tpk_y, **fee.tcm()]; + let mut inputs = vec![N::Field::one(), *tpk_x, *tpk_y, **fee.tcm(), **fee.scm()]; // Extend the inputs with the input IDs. inputs.extend(fee.inputs().iter().flat_map(|input| input.verifier_inputs())); // Extend the verifier inputs with the public inputs for 'self.caller' @@ -241,17 +249,17 @@ mod tests { // Compute the deployment ID. let deployment_id = deployment.to_deployment_id().unwrap(); // Verify the fee. - assert!(process.verify_fee(&fee, deployment_id).is_ok()); + process.verify_fee(&fee, deployment_id).unwrap(); } Transaction::Execute(_, execution, fee) => { // Compute the execution ID. let execution_id = execution.to_execution_id().unwrap(); // Verify the fee. - assert!(process.verify_fee(&fee.unwrap(), execution_id).is_ok()); + process.verify_fee(&fee.unwrap(), execution_id).unwrap(); } Transaction::Fee(_, fee) => match fee.is_fee_private() { - true => assert!(process.verify_fee_private(&&fee).is_ok()), - false => assert!(process.verify_fee_public(&&fee).is_ok()), + true => process.verify_fee_private(&&fee).unwrap(), + false => process.verify_fee_public(&&fee).unwrap(), }, } } diff --git a/synthesizer/program/Cargo.toml b/synthesizer/program/Cargo.toml index 9c1515671c..851bd1c888 100644 --- a/synthesizer/program/Cargo.toml +++ b/synthesizer/program/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-synthesizer-program" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Program for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -31,12 +31,12 @@ wasm = [ "console/wasm" ] [dependencies.circuit] package = "snarkvm-circuit" path = "../../circuit" -version = "=0.16.19" +version = "=1.1.0" [dependencies.console] package = "snarkvm-console" path = "../../console" -version = "=0.16.19" +version = "=1.1.0" default-features = false features = [ "account", "network", "program", "types" ] diff --git a/synthesizer/program/benches/instruction.rs b/synthesizer/program/benches/instruction.rs index 7940c49261..b2c4d887d5 100644 --- a/synthesizer/program/benches/instruction.rs +++ b/synthesizer/program/benches/instruction.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,7 +19,7 @@ // extern crate criterion; // // use console::{ -// network::{Testnet3, Network}, +// network::{MainnetV0, Network}, // prelude::{TestRng, Uniform, Zero}, // program::{ // Identifier, @@ -62,10 +63,10 @@ // // /// A helper function to construct a set of `FinalizeRegisters` with the given arguments. // fn setup_finalize_registers( -// stack: &Stack, +// stack: &Stack, // finalize_body: impl Display, -// args: &[Value], -// ) -> FinalizeRegisters { +// args: &[Value], +// ) -> FinalizeRegisters { // // Initialize a `Finalize` block with the benchmark arguments as inputs. // let mut finalize_string = "finalize foo:".to_string(); // for (i, arg) in args.iter().enumerate() { @@ -75,11 +76,11 @@ // })); // } // finalize_string.push_str(&finalize_body.to_string()); -// let finalize = Finalize::::from_str(&finalize_string).unwrap(); +// let finalize = Finalize::::from_str(&finalize_string).unwrap(); // // Construct the finalize state. -// let state = FinalizeGlobalState::new::(0, 0, 0, 0, ::BlockHash::default()).unwrap(); +// let state = FinalizeGlobalState::new::(0, 0, 0, 0, ::BlockHash::default()).unwrap(); // // Initialize a fresh set of finalize registers. -// let mut registers = FinalizeRegisters::new(state, ::TransitionID::default(), Identifier::from_str("test").unwrap(), FinalizeTypes::from_finalize(stack, &finalize).unwrap()); +// let mut registers = FinalizeRegisters::new(state, ::TransitionID::default(), Identifier::from_str("test").unwrap(), FinalizeTypes::from_finalize(stack, &finalize).unwrap()); // // Add the arguments into the registers. // for (i, arg) in args.iter().enumerate() { // registers.store(stack, &Register::Locator(i as u64), arg.clone()).unwrap(); @@ -92,7 +93,7 @@ // // Initialize an RNG. // let rng = &mut TestRng::default(); // // Initialize a process. -// let process = Process::::load().unwrap(); +// let process = Process::::load().unwrap(); // // Get the stack for the credits program. // // Note that this is not used for anything other than to satisfy the function signature for `finalize`. // // This is because `Stack`s are only used in finalize contexts to check that structs are well-formed. @@ -104,7 +105,7 @@ // { // use snarkvm_synthesizer_program::$instruction; // let name = concat!(stringify!($instruction), "/", stringify!($input)); -// let instruction = Instruction::::$instruction($instruction::from_str(&format!("{} r0 into r1", $instruction::::opcode().to_string())).unwrap()); +// let instruction = Instruction::::$instruction($instruction::from_str(&format!("{} r0 into r1", $instruction::::opcode().to_string())).unwrap()); // c.bench_function(&format!("{name}/instruction"), |b| { // b.iter_batched( // || { @@ -122,7 +123,7 @@ // { // use snarkvm_synthesizer_program::$instruction; // let name = concat!(stringify!($instruction), "/", stringify!($input)); -// let instruction = Instruction::::$instruction($instruction::from_str(&format!("{} r0 into r1 as {}", $instruction::::opcode().to_string(), $as_type)).unwrap()); +// let instruction = Instruction::::$instruction($instruction::from_str(&format!("{} r0 into r1 as {}", $instruction::::opcode().to_string(), $as_type)).unwrap()); // c.bench_function(&format!("{name}/instruction"), |b| { // b.iter_batched( // || { @@ -140,7 +141,7 @@ // { // use snarkvm_synthesizer_program::$instruction; // let name = concat!(stringify!($instruction), "/", stringify!($input_a), "_", stringify!($input_b)); -// let instruction = Instruction::::$instruction($instruction::from_str(&format!("{} r0 r1 into r2", $instruction::::opcode().to_string())).unwrap()); +// let instruction = Instruction::::$instruction($instruction::from_str(&format!("{} r0 r1 into r2", $instruction::::opcode().to_string())).unwrap()); // c.bench_function(&format!("{name}/instruction"), |b| { // b.iter_batched( // || { @@ -158,7 +159,7 @@ // { // use snarkvm_synthesizer_program::$instruction; // let name = concat!(stringify!($instruction), "/", stringify!($input_a), "_", stringify!($input_b), "_", stringify!($input_c)); -// let instruction = Instruction::::$instruction($instruction::from_str(&format!("{} r0 r1 r2 into r3", $instruction::::opcode().to_string())).unwrap()); +// let instruction = Instruction::::$instruction($instruction::from_str(&format!("{} r0 r1 r2 into r3", $instruction::::opcode().to_string())).unwrap()); // c.bench_function(&format!("{name}/instruction"), |b| { // b.iter_batched( // || { @@ -179,7 +180,7 @@ // $({ // // Define the default sampling method. // let mut samples = iter::repeat_with(|| { -// let mut arg: $input:: = Uniform::rand(rng); +// let mut arg: $input:: = Uniform::rand(rng); // while (std::panic::catch_unwind(|| arg.$operation())).is_err() { // arg = Uniform::rand(rng); // } @@ -203,7 +204,7 @@ // $({ // // Define the default sampling method. // let mut samples = iter::repeat_with(|| { -// let mut arg: $input:: = Uniform::rand(rng); +// let mut arg: $input:: = Uniform::rand(rng); // while (std::panic::catch_unwind(|| arg.$operation().unwrap())).is_err() { // arg = Uniform::rand(rng); // } @@ -227,8 +228,8 @@ // $({ // // Define the default sampling method. // let mut samples = iter::repeat_with(|| { -// let mut first: $input_a:: = Uniform::rand(rng); -// let mut second: $input_b:: = Uniform::rand(rng); +// let mut first: $input_a:: = Uniform::rand(rng); +// let mut second: $input_b:: = Uniform::rand(rng); // while (std::panic::catch_unwind(|| first.$operation(&second))).is_err() { // first = Uniform::rand(rng); // second = Uniform::rand(rng); @@ -252,9 +253,9 @@ // ($operation:tt, $instruction:ident { $( ($input_a:ident, $input_b:ident, $input_c:ident), )+ }) => { // $({ // let mut samples = iter::repeat_with(|| { -// let mut first: $input_a:: = Uniform::rand(rng); -// let mut second: $input_b:: = Uniform::rand(rng); -// let mut third: $input_c:: = Uniform::rand(rng); +// let mut first: $input_a:: = Uniform::rand(rng); +// let mut second: $input_b:: = Uniform::rand(rng); +// let mut third: $input_c:: = Uniform::rand(rng); // while (std::panic::catch_unwind(|| $input_b::ternary(&first, &second, &third))).is_err() { // first = Uniform::rand(rng); // second = Uniform::rand(rng); @@ -314,13 +315,13 @@ // macro_rules! bench_assert { // ($typ:tt) => { // let mut samples = iter::repeat_with(|| { -// let result = $typ::::rand(rng); +// let result = $typ::::rand(rng); // (result.clone(), result) // }); // { // use snarkvm_synthesizer_program::AssertEq; // let name = concat!("AssertEq/", stringify!($typ), "_", stringify!($typ)); -// let instruction = Instruction::::AssertEq(AssertEq::from_str(&format!("{} r0 r1", AssertEq::::opcode().to_string())).unwrap()); +// let instruction = Instruction::::AssertEq(AssertEq::from_str(&format!("{} r0 r1", AssertEq::::opcode().to_string())).unwrap()); // c.bench_function(&format!("{name}/instruction"), |b| { // b.iter_batched( // || { @@ -333,17 +334,17 @@ // }); // }; // let mut samples = iter::repeat_with(|| { -// let first = $typ::::rand(rng); -// let mut second = $typ::::rand(rng); +// let first = $typ::::rand(rng); +// let mut second = $typ::::rand(rng); // while first == second { -// second = $typ::::rand(rng); +// second = $typ::::rand(rng); // } // (first, second) // }); // { // use snarkvm_synthesizer_program::AssertNeq; // let name = concat!("AssertNeq/", stringify!($typ), "_", stringify!($typ)); -// let instruction = Instruction::::AssertNeq(AssertNeq::from_str(&format!("{} r0 r1", AssertNeq::::opcode().to_string())).unwrap()); +// let instruction = Instruction::::AssertNeq(AssertNeq::from_str(&format!("{} r0 r1", AssertNeq::::opcode().to_string())).unwrap()); // c.bench_function(&format!("{name}/instruction"), |b| { // b.iter_batched( // || { @@ -390,19 +391,19 @@ // // macro_rules! bench_ped64_commit_instruction { // ($instruction:tt) => { -// let mut samples = iter::repeat_with(|| { (Boolean::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (Boolean::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (Boolean, Scalar), }); -// let mut samples = iter::repeat_with(|| { (I8::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (I8::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (I8, Scalar), }); -// let mut samples = iter::repeat_with(|| { (I16::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (I16::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (I16, Scalar), }); -// let mut samples = iter::repeat_with(|| { (I32::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (I32::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (I32, Scalar), }); -// let mut samples = iter::repeat_with(|| { (U8::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (U8::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (U8, Scalar), }); -// let mut samples = iter::repeat_with(|| { (U16::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (U16::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (U16, Scalar), }); -// let mut samples = iter::repeat_with(|| { (U32::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (U32::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (U32, Scalar), }); // } // } @@ -410,19 +411,19 @@ // macro_rules! bench_commit_instruction { // ($instruction:tt) => { // bench_ped64_commit_instruction!($instruction); -// let mut samples = iter::repeat_with(|| { (Field::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (Field::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (Field, Scalar), }); -// let mut samples = iter::repeat_with(|| { (Group::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (Group::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (Group, Scalar), }); -// let mut samples = iter::repeat_with(|| { (I64::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (I64::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (I64, Scalar), }); -// let mut samples = iter::repeat_with(|| { (I128::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (I128::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (I128, Scalar), }); -// let mut samples = iter::repeat_with(|| { (U64::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (U64::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (U64, Scalar), }); -// let mut samples = iter::repeat_with(|| { (U128::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (U128::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (U128, Scalar), }); -// let mut samples = iter::repeat_with(|| { (Scalar::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (Scalar::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, $instruction { (Scalar, Scalar), }); // } // } @@ -435,9 +436,9 @@ // bench_ped64_commit_instruction!(CommitPED64); // // bench_ped64_commit_instruction!(CommitPED128); -// let mut samples = iter::repeat_with(|| { (I64::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (I64::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, CommitPED128 { (I64, Scalar), }); -// let mut samples = iter::repeat_with(|| { (U64::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (U64::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, CommitPED128 { (U64, Scalar), }); // // use console::prelude::Div; @@ -505,19 +506,19 @@ // // macro_rules! bench_ped64_hash_instruction { // ($instruction:tt) => { -// let mut samples = iter::repeat_with(|| { Boolean::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { Boolean::::rand(rng) }); // bench_instruction!(samples, $instruction { Boolean, }, "group"); -// let mut samples = iter::repeat_with(|| { I8::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { I8::::rand(rng) }); // bench_instruction!(samples, $instruction { I8, }, "group"); -// let mut samples = iter::repeat_with(|| { I16::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { I16::::rand(rng) }); // bench_instruction!(samples, $instruction { I16, }, "group"); -// let mut samples = iter::repeat_with(|| { I32::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { I32::::rand(rng) }); // bench_instruction!(samples, $instruction { I32, }, "group"); -// let mut samples = iter::repeat_with(|| { U8::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { U8::::rand(rng) }); // bench_instruction!(samples, $instruction { U8, }, "group"); -// let mut samples = iter::repeat_with(|| { U16::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { U16::::rand(rng) }); // bench_instruction!(samples, $instruction { U16, }, "group"); -// let mut samples = iter::repeat_with(|| { U32::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { U32::::rand(rng) }); // bench_instruction!(samples, $instruction { U32, }, "group"); // } // } @@ -525,19 +526,19 @@ // macro_rules! bench_hash_instruction { // ($instruction:tt) => { // bench_ped64_hash_instruction!($instruction); -// let mut samples = iter::repeat_with(|| { Field::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { Field::::rand(rng) }); // bench_instruction!(samples, $instruction { Field, }, "group"); -// let mut samples = iter::repeat_with(|| { Group::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { Group::::rand(rng) }); // bench_instruction!(samples, $instruction { Group, }, "group"); -// let mut samples = iter::repeat_with(|| { I64::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { I64::::rand(rng) }); // bench_instruction!(samples, $instruction { I64, }, "group"); -// let mut samples = iter::repeat_with(|| { I128::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { I128::::rand(rng) }); // bench_instruction!(samples, $instruction { I128, }, "group"); -// let mut samples = iter::repeat_with(|| { U64::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { U64::::rand(rng) }); // bench_instruction!(samples, $instruction { U64, }, "group"); -// let mut samples = iter::repeat_with(|| { U128::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { U128::::rand(rng) }); // bench_instruction!(samples, $instruction { U128, }, "group"); -// let mut samples = iter::repeat_with(|| { Scalar::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { Scalar::::rand(rng) }); // bench_instruction!(samples, $instruction { Scalar, }, "group"); // } // } @@ -550,9 +551,9 @@ // bench_ped64_hash_instruction!(HashPED64); // // bench_ped64_hash_instruction!(HashPED128); -// let mut samples = iter::repeat_with(|| { I64::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { I64::::rand(rng) }); // bench_instruction!(samples, HashPED128 { I64, }, "group"); -// let mut samples = iter::repeat_with(|| { U64::::rand(rng) }); +// let mut samples = iter::repeat_with(|| { U64::::rand(rng) }); // bench_instruction!(samples, HashPED128 { U64, }, "group"); // // bench_hash_instruction!(HashPSD2); @@ -562,46 +563,46 @@ // use console::prelude::Inverse; // bench_instruction_with_default!(inverse?, Inv { Field, }); // -// let mut samples = iter::repeat_with(|| { (Boolean::::rand(rng), Boolean::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (Boolean::::rand(rng), Boolean::::rand(rng)) }); // bench_instruction!(samples, IsEq { (Boolean, Boolean), }); // bench_instruction!(samples, IsNeq { (Boolean, Boolean), }); -// let mut samples = iter::repeat_with(|| { (Field::::rand(rng), Field::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (Field::::rand(rng), Field::::rand(rng)) }); // bench_instruction!(samples, IsEq { (Field, Field), }); // bench_instruction!(samples, IsNeq { (Field, Field), }); -// let mut samples = iter::repeat_with(|| { (Group::::rand(rng), Group::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (Group::::rand(rng), Group::::rand(rng)) }); // bench_instruction!(samples, IsEq { (Group, Group), }); // bench_instruction!(samples, IsNeq { (Group, Group), }); -// let mut samples = iter::repeat_with(|| { (I8::::rand(rng), I8::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (I8::::rand(rng), I8::::rand(rng)) }); // bench_instruction!(samples, IsEq { (I8, I8), }); // bench_instruction!(samples, IsNeq { (I8, I8), }); -// let mut samples = iter::repeat_with(|| { (I16::::rand(rng), I16::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (I16::::rand(rng), I16::::rand(rng)) }); // bench_instruction!(samples, IsEq { (I16, I16), }); // bench_instruction!(samples, IsNeq { (I16, I16), }); -// let mut samples = iter::repeat_with(|| { (I32::::rand(rng), I32::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (I32::::rand(rng), I32::::rand(rng)) }); // bench_instruction!(samples, IsEq { (I32, I32), }); // bench_instruction!(samples, IsNeq { (I32, I32), }); -// let mut samples = iter::repeat_with(|| { (I64::::rand(rng), I64::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (I64::::rand(rng), I64::::rand(rng)) }); // bench_instruction!(samples, IsEq { (I64, I64), }); // bench_instruction!(samples, IsNeq { (I64, I64), }); -// let mut samples = iter::repeat_with(|| { (I128::::rand(rng), I128::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (I128::::rand(rng), I128::::rand(rng)) }); // bench_instruction!(samples, IsEq { (I128, I128), }); // bench_instruction!(samples, IsNeq { (I128, I128), }); -// let mut samples = iter::repeat_with(|| { (Scalar::::rand(rng), Scalar::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (Scalar::::rand(rng), Scalar::::rand(rng)) }); // bench_instruction!(samples, IsEq { (Scalar, Scalar), }); // bench_instruction!(samples, IsNeq { (Scalar, Scalar), }); -// let mut samples = iter::repeat_with(|| { (U8::::rand(rng), U8::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (U8::::rand(rng), U8::::rand(rng)) }); // bench_instruction!(samples, IsEq { (U8, U8), }); // bench_instruction!(samples, IsNeq { (U8, U8), }); -// let mut samples = iter::repeat_with(|| { (U16::::rand(rng), U16::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (U16::::rand(rng), U16::::rand(rng)) }); // bench_instruction!(samples, IsEq { (U16, U16), }); // bench_instruction!(samples, IsNeq { (U16, U16), }); -// let mut samples = iter::repeat_with(|| { (U32::::rand(rng), U32::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (U32::::rand(rng), U32::::rand(rng)) }); // bench_instruction!(samples, IsEq { (U32, U32), }); // bench_instruction!(samples, IsNeq { (U32, U32), }); -// let mut samples = iter::repeat_with(|| { (U64::::rand(rng), U64::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (U64::::rand(rng), U64::::rand(rng)) }); // bench_instruction!(samples, IsEq { (U64, U64), }); // bench_instruction!(samples, IsNeq { (U64, U64), }); -// let mut samples = iter::repeat_with(|| { (U128::::rand(rng), U128::::rand(rng)) }); +// let mut samples = iter::repeat_with(|| { (U128::::rand(rng), U128::::rand(rng)) }); // bench_instruction!(samples, IsEq { (U128, U128), }); // bench_instruction!(samples, IsNeq { (U128, U128), }); // @@ -651,25 +652,25 @@ // (Scalar, Group), // }); // // Use a custom sampling method for integer multiplication, since there is a high chance of overflow. -// let mut samples = iter::repeat((I8::::zero(), I8::::zero())); +// let mut samples = iter::repeat((I8::::zero(), I8::::zero())); // bench_instruction!(samples, Mul { (I8, I8), }); -// let mut samples = iter::repeat((I16::::zero(), I16::::zero())); +// let mut samples = iter::repeat((I16::::zero(), I16::::zero())); // bench_instruction!(samples, Mul { (I16, I16), }); -// let mut samples = iter::repeat((I32::::zero(), I32::::zero())); +// let mut samples = iter::repeat((I32::::zero(), I32::::zero())); // bench_instruction!(samples, Mul { (I32, I32), }); -// let mut samples = iter::repeat((I64::::zero(), I64::::zero())); +// let mut samples = iter::repeat((I64::::zero(), I64::::zero())); // bench_instruction!(samples, Mul { (I64, I64), }); -// let mut samples = iter::repeat((I128::::zero(), I128::::zero())); +// let mut samples = iter::repeat((I128::::zero(), I128::::zero())); // bench_instruction!(samples, Mul { (I128, I128), }); -// let mut samples = iter::repeat((U8::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U8::::zero(), U8::::zero())); // bench_instruction!(samples, Mul { (U8, U8), }); -// let mut samples = iter::repeat((U16::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U16::::zero(), U16::::zero())); // bench_instruction!(samples, Mul { (U16, U16), }); -// let mut samples = iter::repeat((U32::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U32::::zero(), U32::::zero())); // bench_instruction!(samples, Mul { (U32, U32), }); -// let mut samples = iter::repeat((U64::::zero(), U64::::zero())); +// let mut samples = iter::repeat((U64::::zero(), U64::::zero())); // bench_instruction!(samples, Mul { (U64, U64), }); -// let mut samples = iter::repeat((U128::::zero(), U128::::zero())); +// let mut samples = iter::repeat((U128::::zero(), U128::::zero())); // bench_instruction!(samples, Mul { (U128, U128), }); // // use console::prelude::MulWrapped; @@ -721,65 +722,65 @@ // (Field, Field), // }); // // Use a custom sampling method for integer exponentiation, since there is a high chance of overflow. -// let mut samples = iter::repeat((I8::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I8::::zero(), U8::::zero())); // bench_instruction!(samples, Pow { (I8, U8), }); -// let mut samples = iter::repeat((I8::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I8::::zero(), U16::::zero())); // bench_instruction!(samples, Pow { (I8, U16), }); -// let mut samples = iter::repeat((I8::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I8::::zero(), U32::::zero())); // bench_instruction!(samples, Pow { (I8, U32), }); -// let mut samples = iter::repeat((I16::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I16::::zero(), U8::::zero())); // bench_instruction!(samples, Pow { (I16, U8), }); -// let mut samples = iter::repeat((I16::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I16::::zero(), U16::::zero())); // bench_instruction!(samples, Pow { (I16, U16), }); -// let mut samples = iter::repeat((I16::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I16::::zero(), U32::::zero())); // bench_instruction!(samples, Pow { (I16, U32), }); -// let mut samples = iter::repeat((I32::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I32::::zero(), U8::::zero())); // bench_instruction!(samples, Pow { (I32, U8), }); -// let mut samples = iter::repeat((I32::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I32::::zero(), U16::::zero())); // bench_instruction!(samples, Pow { (I32, U16), }); -// let mut samples = iter::repeat((I32::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I32::::zero(), U32::::zero())); // bench_instruction!(samples, Pow { (I32, U32), }); -// let mut samples = iter::repeat((I64::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I64::::zero(), U8::::zero())); // bench_instruction!(samples, Pow { (I64, U8), }); -// let mut samples = iter::repeat((I64::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I64::::zero(), U16::::zero())); // bench_instruction!(samples, Pow { (I64, U16), }); -// let mut samples = iter::repeat((I64::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I64::::zero(), U32::::zero())); // bench_instruction!(samples, Pow { (I64, U32), }); -// let mut samples = iter::repeat((I128::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I128::::zero(), U8::::zero())); // bench_instruction!(samples, Pow { (I128, U8), }); -// let mut samples = iter::repeat((I128::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I128::::zero(), U16::::zero())); // bench_instruction!(samples, Pow { (I128, U16), }); -// let mut samples = iter::repeat((I128::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I128::::zero(), U32::::zero())); // bench_instruction!(samples, Pow { (I128, U32), }); -// let mut samples = iter::repeat((U8::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U8::::zero(), U8::::zero())); // bench_instruction!(samples, Pow { (U8, U8), }); -// let mut samples = iter::repeat((U8::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U8::::zero(), U16::::zero())); // bench_instruction!(samples, Pow { (U8, U16), }); -// let mut samples = iter::repeat((U8::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U8::::zero(), U32::::zero())); // bench_instruction!(samples, Pow { (U8, U32), }); -// let mut samples = iter::repeat((U16::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U16::::zero(), U8::::zero())); // bench_instruction!(samples, Pow { (U16, U8), }); -// let mut samples = iter::repeat((U16::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U16::::zero(), U16::::zero())); // bench_instruction!(samples, Pow { (U16, U16), }); -// let mut samples = iter::repeat((U16::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U16::::zero(), U32::::zero())); // bench_instruction!(samples, Pow { (U16, U32), }); -// let mut samples = iter::repeat((U32::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U32::::zero(), U8::::zero())); // bench_instruction!(samples, Pow { (U32, U8), }); -// let mut samples = iter::repeat((U32::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U32::::zero(), U16::::zero())); // bench_instruction!(samples, Pow { (U32, U16), }); -// let mut samples = iter::repeat((U32::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U32::::zero(), U32::::zero())); // bench_instruction!(samples, Pow { (U32, U32), }); -// let mut samples = iter::repeat((U64::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U64::::zero(), U8::::zero())); // bench_instruction!(samples, Pow { (U64, U8), }); -// let mut samples = iter::repeat((U64::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U64::::zero(), U16::::zero())); // bench_instruction!(samples, Pow { (U64, U16), }); -// let mut samples = iter::repeat((U64::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U64::::zero(), U32::::zero())); // bench_instruction!(samples, Pow { (U64, U32), }); -// let mut samples = iter::repeat((U128::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U128::::zero(), U8::::zero())); // bench_instruction!(samples, Pow { (U128, U8), }); -// let mut samples = iter::repeat((U128::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U128::::zero(), U16::::zero())); // bench_instruction!(samples, Pow { (U128, U16), }); -// let mut samples = iter::repeat((U128::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U128::::zero(), U32::::zero())); // bench_instruction!(samples, Pow { (U128, U32), }); // // use console::prelude::PowWrapped; @@ -845,65 +846,65 @@ // }); // // // Use a custom sampling method for left-shift, since there is a high chance of overflow. -// let mut samples = iter::repeat((I8::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I8::::zero(), U8::::zero())); // bench_instruction!(samples, Shl { (I8, U8), }); -// let mut samples = iter::repeat((I8::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I8::::zero(), U16::::zero())); // bench_instruction!(samples, Shl { (I8, U16), }); -// let mut samples = iter::repeat((I8::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I8::::zero(), U32::::zero())); // bench_instruction!(samples, Shl { (I8, U32), }); -// let mut samples = iter::repeat((I16::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I16::::zero(), U8::::zero())); // bench_instruction!(samples, Shl { (I16, U8), }); -// let mut samples = iter::repeat((I16::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I16::::zero(), U16::::zero())); // bench_instruction!(samples, Shl { (I16, U16), }); -// let mut samples = iter::repeat((I16::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I16::::zero(), U32::::zero())); // bench_instruction!(samples, Shl { (I16, U32), }); -// let mut samples = iter::repeat((I32::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I32::::zero(), U8::::zero())); // bench_instruction!(samples, Shl { (I32, U8), }); -// let mut samples = iter::repeat((I32::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I32::::zero(), U16::::zero())); // bench_instruction!(samples, Shl { (I32, U16), }); -// let mut samples = iter::repeat((I32::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I32::::zero(), U32::::zero())); // bench_instruction!(samples, Shl { (I32, U32), }); -// let mut samples = iter::repeat((I64::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I64::::zero(), U8::::zero())); // bench_instruction!(samples, Shl { (I64, U8), }); -// let mut samples = iter::repeat((I64::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I64::::zero(), U16::::zero())); // bench_instruction!(samples, Shl { (I64, U16), }); -// let mut samples = iter::repeat((I64::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I64::::zero(), U32::::zero())); // bench_instruction!(samples, Shl { (I64, U32), }); -// let mut samples = iter::repeat((I128::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I128::::zero(), U8::::zero())); // bench_instruction!(samples, Shl { (I128, U8), }); -// let mut samples = iter::repeat((I128::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I128::::zero(), U16::::zero())); // bench_instruction!(samples, Shl { (I128, U16), }); -// let mut samples = iter::repeat((I128::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I128::::zero(), U32::::zero())); // bench_instruction!(samples, Shl { (I128, U32), }); -// let mut samples = iter::repeat((U8::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U8::::zero(), U8::::zero())); // bench_instruction!(samples, Shl { (U8, U8), }); -// let mut samples = iter::repeat((U8::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U8::::zero(), U16::::zero())); // bench_instruction!(samples, Shl { (U8, U16), }); -// let mut samples = iter::repeat((U8::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U8::::zero(), U32::::zero())); // bench_instruction!(samples, Shl { (U8, U32), }); -// let mut samples = iter::repeat((U16::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U16::::zero(), U8::::zero())); // bench_instruction!(samples, Shl { (U16, U8), }); -// let mut samples = iter::repeat((U16::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U16::::zero(), U16::::zero())); // bench_instruction!(samples, Shl { (U16, U16), }); -// let mut samples = iter::repeat((U16::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U16::::zero(), U32::::zero())); // bench_instruction!(samples, Shl { (U16, U32), }); -// let mut samples = iter::repeat((U32::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U32::::zero(), U8::::zero())); // bench_instruction!(samples, Shl { (U32, U8), }); -// let mut samples = iter::repeat((U32::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U32::::zero(), U16::::zero())); // bench_instruction!(samples, Shl { (U32, U16), }); -// let mut samples = iter::repeat((U32::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U32::::zero(), U32::::zero())); // bench_instruction!(samples, Shl { (U32, U32), }); -// let mut samples = iter::repeat((U64::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U64::::zero(), U8::::zero())); // bench_instruction!(samples, Shl { (U64, U8), }); -// let mut samples = iter::repeat((U64::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U64::::zero(), U16::::zero())); // bench_instruction!(samples, Shl { (U64, U16), }); -// let mut samples = iter::repeat((U64::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U64::::zero(), U32::::zero())); // bench_instruction!(samples, Shl { (U64, U32), }); -// let mut samples = iter::repeat((U128::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U128::::zero(), U8::::zero())); // bench_instruction!(samples, Shl { (U128, U8), }); -// let mut samples = iter::repeat((U128::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U128::::zero(), U16::::zero())); // bench_instruction!(samples, Shl { (U128, U16), }); -// let mut samples = iter::repeat((U128::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U128::::zero(), U32::::zero())); // bench_instruction!(samples, Shl { (U128, U32), }); // // use console::prelude::ShlWrapped; @@ -941,65 +942,65 @@ // }); // // // Use a custom sampling method for left-shift, since there is a high chance of overflow. -// let mut samples = iter::repeat((I8::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I8::::zero(), U8::::zero())); // bench_instruction!(samples, Shr { (I8, U8), }); -// let mut samples = iter::repeat((I8::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I8::::zero(), U16::::zero())); // bench_instruction!(samples, Shr { (I8, U16), }); -// let mut samples = iter::repeat((I8::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I8::::zero(), U32::::zero())); // bench_instruction!(samples, Shr { (I8, U32), }); -// let mut samples = iter::repeat((I16::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I16::::zero(), U8::::zero())); // bench_instruction!(samples, Shr { (I16, U8), }); -// let mut samples = iter::repeat((I16::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I16::::zero(), U16::::zero())); // bench_instruction!(samples, Shr { (I16, U16), }); -// let mut samples = iter::repeat((I16::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I16::::zero(), U32::::zero())); // bench_instruction!(samples, Shr { (I16, U32), }); -// let mut samples = iter::repeat((I32::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I32::::zero(), U8::::zero())); // bench_instruction!(samples, Shr { (I32, U8), }); -// let mut samples = iter::repeat((I32::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I32::::zero(), U16::::zero())); // bench_instruction!(samples, Shr { (I32, U16), }); -// let mut samples = iter::repeat((I32::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I32::::zero(), U32::::zero())); // bench_instruction!(samples, Shr { (I32, U32), }); -// let mut samples = iter::repeat((I64::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I64::::zero(), U8::::zero())); // bench_instruction!(samples, Shr { (I64, U8), }); -// let mut samples = iter::repeat((I64::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I64::::zero(), U16::::zero())); // bench_instruction!(samples, Shr { (I64, U16), }); -// let mut samples = iter::repeat((I64::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I64::::zero(), U32::::zero())); // bench_instruction!(samples, Shr { (I64, U32), }); -// let mut samples = iter::repeat((I128::::zero(), U8::::zero())); +// let mut samples = iter::repeat((I128::::zero(), U8::::zero())); // bench_instruction!(samples, Shr { (I128, U8), }); -// let mut samples = iter::repeat((I128::::zero(), U16::::zero())); +// let mut samples = iter::repeat((I128::::zero(), U16::::zero())); // bench_instruction!(samples, Shr { (I128, U16), }); -// let mut samples = iter::repeat((I128::::zero(), U32::::zero())); +// let mut samples = iter::repeat((I128::::zero(), U32::::zero())); // bench_instruction!(samples, Shr { (I128, U32), }); -// let mut samples = iter::repeat((U8::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U8::::zero(), U8::::zero())); // bench_instruction!(samples, Shr { (U8, U8), }); -// let mut samples = iter::repeat((U8::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U8::::zero(), U16::::zero())); // bench_instruction!(samples, Shr { (U8, U16), }); -// let mut samples = iter::repeat((U8::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U8::::zero(), U32::::zero())); // bench_instruction!(samples, Shr { (U8, U32), }); -// let mut samples = iter::repeat((U16::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U16::::zero(), U8::::zero())); // bench_instruction!(samples, Shr { (U16, U8), }); -// let mut samples = iter::repeat((U16::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U16::::zero(), U16::::zero())); // bench_instruction!(samples, Shr { (U16, U16), }); -// let mut samples = iter::repeat((U16::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U16::::zero(), U32::::zero())); // bench_instruction!(samples, Shr { (U16, U32), }); -// let mut samples = iter::repeat((U32::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U32::::zero(), U8::::zero())); // bench_instruction!(samples, Shr { (U32, U8), }); -// let mut samples = iter::repeat((U32::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U32::::zero(), U16::::zero())); // bench_instruction!(samples, Shr { (U32, U16), }); -// let mut samples = iter::repeat((U32::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U32::::zero(), U32::::zero())); // bench_instruction!(samples, Shr { (U32, U32), }); -// let mut samples = iter::repeat((U64::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U64::::zero(), U8::::zero())); // bench_instruction!(samples, Shr { (U64, U8), }); -// let mut samples = iter::repeat((U64::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U64::::zero(), U16::::zero())); // bench_instruction!(samples, Shr { (U64, U16), }); -// let mut samples = iter::repeat((U64::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U64::::zero(), U32::::zero())); // bench_instruction!(samples, Shr { (U64, U32), }); -// let mut samples = iter::repeat((U128::::zero(), U8::::zero())); +// let mut samples = iter::repeat((U128::::zero(), U8::::zero())); // bench_instruction!(samples, Shr { (U128, U8), }); -// let mut samples = iter::repeat((U128::::zero(), U16::::zero())); +// let mut samples = iter::repeat((U128::::zero(), U16::::zero())); // bench_instruction!(samples, Shr { (U128, U16), }); -// let mut samples = iter::repeat((U128::::zero(), U32::::zero())); +// let mut samples = iter::repeat((U128::::zero(), U32::::zero())); // bench_instruction!(samples, Shr { (U128, U32), }); // // use console::prelude::ShrWrapped; diff --git a/synthesizer/program/src/bytes.rs b/synthesizer/program/src/bytes.rs index a8f9b0e544..ed4b83e846 100644 --- a/synthesizer/program/src/bytes.rs +++ b/synthesizer/program/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -142,9 +143,9 @@ impl, Command: CommandTrait> ToB mod tests { use super::*; use crate::Program; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { diff --git a/synthesizer/program/src/closure/bytes.rs b/synthesizer/program/src/closure/bytes.rs index 60d717bf30..a5c5d1483c 100644 --- a/synthesizer/program/src/closure/bytes.rs +++ b/synthesizer/program/src/closure/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -118,9 +119,9 @@ impl> ToBytes for ClosureCore Result<()> { diff --git a/synthesizer/program/src/closure/input/bytes.rs b/synthesizer/program/src/closure/input/bytes.rs index f11c4458db..2780202916 100644 --- a/synthesizer/program/src/closure/input/bytes.rs +++ b/synthesizer/program/src/closure/input/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/closure/input/mod.rs b/synthesizer/program/src/closure/input/mod.rs index bbf9d4d0e4..fc6958032e 100644 --- a/synthesizer/program/src/closure/input/mod.rs +++ b/synthesizer/program/src/closure/input/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -69,9 +70,9 @@ impl PartialOrd for Input { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_input_type_name() -> Result<()> { diff --git a/synthesizer/program/src/closure/input/parse.rs b/synthesizer/program/src/closure/input/parse.rs index 5a0f7c2481..015ff8edae 100644 --- a/synthesizer/program/src/closure/input/parse.rs +++ b/synthesizer/program/src/closure/input/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -94,9 +95,9 @@ impl Display for Input { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_input_parse() -> Result<()> { diff --git a/synthesizer/program/src/closure/mod.rs b/synthesizer/program/src/closure/mod.rs index aad825d1ea..79ba179b13 100644 --- a/synthesizer/program/src/closure/mod.rs +++ b/synthesizer/program/src/closure/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -154,7 +155,7 @@ mod tests { use crate::{Closure, Instruction}; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; #[test] fn test_add_input() { @@ -188,7 +189,7 @@ mod tests { // Ensure that an instruction can be added. let instruction = Instruction::::from_str("add r0 r1 into r2;").unwrap(); - assert!(closure.add_instruction(instruction.clone()).is_ok()); + assert!(closure.add_instruction(instruction).is_ok()); // Ensure that adding more than the maximum number of instructions will fail. for i in 3..CurrentNetwork::MAX_INSTRUCTIONS * 2 { @@ -209,7 +210,7 @@ mod tests { // Ensure that an output can be added. let output = Output::::from_str("output r0 as field;").unwrap(); - assert!(closure.add_output(output.clone()).is_ok()); + assert!(closure.add_output(output).is_ok()); // Ensure that adding more than the maximum number of outputs will fail. for i in 1..CurrentNetwork::MAX_OUTPUTS * 2 { diff --git a/synthesizer/program/src/closure/output/bytes.rs b/synthesizer/program/src/closure/output/bytes.rs index 466dfd5dc7..2d7c41c9cb 100644 --- a/synthesizer/program/src/closure/output/bytes.rs +++ b/synthesizer/program/src/closure/output/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/closure/output/mod.rs b/synthesizer/program/src/closure/output/mod.rs index c886fab747..2d9500a8dd 100644 --- a/synthesizer/program/src/closure/output/mod.rs +++ b/synthesizer/program/src/closure/output/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -54,9 +55,9 @@ impl TypeName for Output { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_output_type_name() { diff --git a/synthesizer/program/src/closure/output/parse.rs b/synthesizer/program/src/closure/output/parse.rs index b9e7fd444a..f0ce324cc5 100644 --- a/synthesizer/program/src/closure/output/parse.rs +++ b/synthesizer/program/src/closure/output/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -86,11 +87,11 @@ impl Display for Output { mod tests { use super::*; use console::{ - network::Testnet3, + network::MainnetV0, program::{Literal, Register, U8}, }; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_output_parse() -> Result<()> { diff --git a/synthesizer/program/src/closure/parse.rs b/synthesizer/program/src/closure/parse.rs index 4d9894b0d7..1854b7b145 100644 --- a/synthesizer/program/src/closure/parse.rs +++ b/synthesizer/program/src/closure/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -88,9 +89,9 @@ impl> Display for ClosureCore> ToBytes for FinalizeCore mod tests { use super::*; use crate::Finalize; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_finalize_bytes() -> Result<()> { diff --git a/synthesizer/program/src/finalize/input/bytes.rs b/synthesizer/program/src/finalize/input/bytes.rs index 1eaf8b5dfd..06ef0e3270 100644 --- a/synthesizer/program/src/finalize/input/bytes.rs +++ b/synthesizer/program/src/finalize/input/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/finalize/input/mod.rs b/synthesizer/program/src/finalize/input/mod.rs index 88848caedc..030ea03c24 100644 --- a/synthesizer/program/src/finalize/input/mod.rs +++ b/synthesizer/program/src/finalize/input/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -69,9 +70,9 @@ impl PartialOrd for Input { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_input_type_name() -> Result<()> { diff --git a/synthesizer/program/src/finalize/input/parse.rs b/synthesizer/program/src/finalize/input/parse.rs index e2601c9a26..0b1b0ac864 100644 --- a/synthesizer/program/src/finalize/input/parse.rs +++ b/synthesizer/program/src/finalize/input/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -88,9 +89,9 @@ impl Display for Input { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_input_parse() -> Result<()> { diff --git a/synthesizer/program/src/finalize/mod.rs b/synthesizer/program/src/finalize/mod.rs index 556022ad66..4c472b2f66 100644 --- a/synthesizer/program/src/finalize/mod.rs +++ b/synthesizer/program/src/finalize/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -168,7 +169,7 @@ mod tests { use crate::{Command, Finalize}; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; #[test] fn test_add_input() { @@ -202,7 +203,7 @@ mod tests { // Ensure that a command can be added. let command = Command::::from_str("add r0 r1 into r2;").unwrap(); - assert!(finalize.add_command(command.clone()).is_ok()); + assert!(finalize.add_command(command).is_ok()); // Ensure that adding more than the maximum number of commands will fail. for i in 3..CurrentNetwork::MAX_COMMANDS * 2 { diff --git a/synthesizer/program/src/finalize/parse.rs b/synthesizer/program/src/finalize/parse.rs index ba60af4d33..2aeb0faee7 100644 --- a/synthesizer/program/src/finalize/parse.rs +++ b/synthesizer/program/src/finalize/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -90,9 +91,9 @@ impl> Display for FinalizeCore mod tests { use super::*; use crate::Finalize; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_finalize_parse() { diff --git a/synthesizer/program/src/function/bytes.rs b/synthesizer/program/src/function/bytes.rs index 64ddf4938c..57ac395eb3 100644 --- a/synthesizer/program/src/function/bytes.rs +++ b/synthesizer/program/src/function/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -135,9 +136,9 @@ impl, Command: CommandTrait> ToB mod tests { use super::*; use crate::Function; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_function_bytes() -> Result<()> { diff --git a/synthesizer/program/src/function/input/bytes.rs b/synthesizer/program/src/function/input/bytes.rs index 331fcdf1ec..b4c3995bcd 100644 --- a/synthesizer/program/src/function/input/bytes.rs +++ b/synthesizer/program/src/function/input/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/function/input/mod.rs b/synthesizer/program/src/function/input/mod.rs index 193ae71141..f5b1f24c77 100644 --- a/synthesizer/program/src/function/input/mod.rs +++ b/synthesizer/program/src/function/input/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -69,9 +70,9 @@ impl PartialOrd for Input { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_input_type_name() -> Result<()> { diff --git a/synthesizer/program/src/function/input/parse.rs b/synthesizer/program/src/function/input/parse.rs index 991e6efbc8..b90430e9a5 100644 --- a/synthesizer/program/src/function/input/parse.rs +++ b/synthesizer/program/src/function/input/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -94,9 +95,9 @@ impl Display for Input { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_input_parse() -> Result<()> { diff --git a/synthesizer/program/src/function/mod.rs b/synthesizer/program/src/function/mod.rs index 9f03a3c4a9..caebf538b5 100644 --- a/synthesizer/program/src/function/mod.rs +++ b/synthesizer/program/src/function/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -27,7 +28,7 @@ use crate::{ }; use console::{ network::prelude::*, - program::{Identifier, Register, ValueType}, + program::{Identifier, Register, ValueType, Variant}, }; use indexmap::IndexSet; @@ -68,6 +69,11 @@ impl, Command: CommandTrait> Fun self.inputs.iter().map(|input| input.value_type()).cloned().collect() } + /// Returns the function input type variants. + pub fn input_variants(&self) -> Vec { + self.inputs.iter().map(|input| input.value_type().variant()).collect() + } + /// Returns the function instructions. pub fn instructions(&self) -> &[Instruction] { &self.instructions @@ -83,6 +89,11 @@ impl, Command: CommandTrait> Fun self.outputs.iter().map(|output| output.value_type()).cloned().collect() } + /// Returns the function output type variants. + pub fn output_variants(&self) -> Vec { + self.outputs.iter().map(|output| output.value_type().variant()).collect() + } + /// Returns the function finalize logic. pub const fn finalize_logic(&self) -> Option<&FinalizeCore> { self.finalize_logic.as_ref() @@ -208,7 +219,7 @@ mod tests { use crate::{Function, Instruction}; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; #[test] fn test_add_input() { @@ -242,7 +253,7 @@ mod tests { // Ensure that an instruction can be added. let instruction = Instruction::::from_str("add r0 r1 into r2;").unwrap(); - assert!(function.add_instruction(instruction.clone()).is_ok()); + assert!(function.add_instruction(instruction).is_ok()); // Ensure that adding more than the maximum number of instructions will fail. for i in 3..CurrentNetwork::MAX_INSTRUCTIONS * 2 { @@ -263,7 +274,7 @@ mod tests { // Ensure that an output can be added. let output = Output::::from_str("output r0 as field.private;").unwrap(); - assert!(function.add_output(output.clone()).is_ok()); + assert!(function.add_output(output).is_ok()); // Ensure that adding more than the maximum number of outputs will fail. for i in 1..CurrentNetwork::MAX_OUTPUTS * 2 { diff --git a/synthesizer/program/src/function/output/bytes.rs b/synthesizer/program/src/function/output/bytes.rs index a73eeeb333..32d01a4fa7 100644 --- a/synthesizer/program/src/function/output/bytes.rs +++ b/synthesizer/program/src/function/output/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/function/output/mod.rs b/synthesizer/program/src/function/output/mod.rs index 864affe4cf..902a1d0cdc 100644 --- a/synthesizer/program/src/function/output/mod.rs +++ b/synthesizer/program/src/function/output/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -54,9 +55,9 @@ impl TypeName for Output { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_output_type_name() { diff --git a/synthesizer/program/src/function/output/parse.rs b/synthesizer/program/src/function/output/parse.rs index 9f9328581f..394c85dcd9 100644 --- a/synthesizer/program/src/function/output/parse.rs +++ b/synthesizer/program/src/function/output/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -86,11 +87,11 @@ impl Display for Output { mod tests { use super::*; use console::{ - network::Testnet3, + network::MainnetV0, program::{Literal, Register, U8}, }; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_output_parse() -> Result<()> { diff --git a/synthesizer/program/src/function/parse.rs b/synthesizer/program/src/function/parse.rs index 7f65dc6fb2..1a83ca8dcf 100644 --- a/synthesizer/program/src/function/parse.rs +++ b/synthesizer/program/src/function/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -123,9 +124,9 @@ impl, Command: CommandTrait> Dis mod tests { use super::*; use crate::Function; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_function_parse() { diff --git a/synthesizer/program/src/import/bytes.rs b/synthesizer/program/src/import/bytes.rs index 6aea062cfd..c36eba061e 100644 --- a/synthesizer/program/src/import/bytes.rs +++ b/synthesizer/program/src/import/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/import/mod.rs b/synthesizer/program/src/import/mod.rs index f7baec62d5..e4288f3f0b 100644 --- a/synthesizer/program/src/import/mod.rs +++ b/synthesizer/program/src/import/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -66,16 +67,16 @@ impl Ord for Import { impl PartialOrd for Import { /// Ordering is determined by the NLD first, then the program name second. fn partial_cmp(&self, other: &Self) -> Option { - self.program_id.partial_cmp(&other.program_id) + Some(self.cmp(other)) } } #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_import_type_name() -> Result<()> { diff --git a/synthesizer/program/src/import/parse.rs b/synthesizer/program/src/import/parse.rs index 0f4e749e98..1681fb91c5 100644 --- a/synthesizer/program/src/import/parse.rs +++ b/synthesizer/program/src/import/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -71,9 +72,9 @@ impl Display for Import { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_import_parse() -> Result<()> { diff --git a/synthesizer/program/src/lib.rs b/synthesizer/program/src/lib.rs index 26f9b7c2b8..b9cad0e348 100644 --- a/synthesizer/program/src/lib.rs +++ b/synthesizer/program/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -48,24 +49,13 @@ mod serialize; use console::{ network::prelude::{ - alt, - anyhow, - bail, - de, - ensure, - error, - fmt, - many0, - many1, - map, - map_res, - tag, - take, Debug, Deserialize, Deserializer, Display, + Err, Error, + ErrorKind, Formatter, FromBytes, FromBytesDeserializer, @@ -83,6 +73,19 @@ use console::{ ToBytesSerializer, TypeName, Write, + anyhow, + bail, + de, + ensure, + error, + fmt, + make_error, + many0, + many1, + map, + map_res, + tag, + take, }, program::{Identifier, PlaintextType, ProgramID, RecordType, StructType}, }; @@ -265,13 +268,13 @@ impl, Command: CommandTrait> Pro /// Returns the function with the given name. pub fn get_function(&self, name: &Identifier) -> Result> { - self.get_function_ref(name).map(|function| function.clone()) + self.get_function_ref(name).cloned() } /// Returns a reference to the function with the given name. pub fn get_function_ref(&self, name: &Identifier) -> Result<&FunctionCore> { // Attempt to retrieve the function. - let function = self.functions.get(name).ok_or_else(|| anyhow!("Function '{name}' is not defined."))?; + let function = self.functions.get(name).ok_or(anyhow!("Function '{}/{name}' is not defined.", self.id))?; // Ensure the function name matches. ensure!(function.name() == name, "Expected function '{name}', but found function '{}'", function.name()); // Ensure the number of inputs is within the allowed range. @@ -295,6 +298,9 @@ impl, Command: CommandTrait> Pro // Retrieve the imported program name. let import_name = *import.name(); + // Ensure that the number of imports is within the allowed range. + ensure!(self.imports.len() < N::MAX_IMPORTS, "Program exceeds the maximum number of imports"); + // Ensure the import name is new. ensure!(self.is_unique_name(&import_name), "'{import_name}' is already in use."); // Ensure the import name is not a reserved opcode. @@ -359,6 +365,9 @@ impl, Command: CommandTrait> Pro // Retrieve the struct name. let struct_name = *struct_.name(); + // Ensure the program has not exceeded the maximum number of structs. + ensure!(self.structs.len() < N::MAX_STRUCTS, "Program exceeds the maximum number of structs."); + // Ensure the struct name is new. ensure!(self.is_unique_name(&struct_name), "'{struct_name}' is already in use."); // Ensure the struct name is not a reserved opcode. @@ -417,6 +426,9 @@ impl, Command: CommandTrait> Pro // Retrieve the record name. let record_name = *record.name(); + // Ensure the program has not exceeded the maximum number of records. + ensure!(self.records.len() < N::MAX_RECORDS, "Program exceeds the maximum number of records."); + // Ensure the record name is new. ensure!(self.is_unique_name(&record_name), "'{record_name}' is already in use."); // Ensure the record name is not a reserved opcode. @@ -477,6 +489,9 @@ impl, Command: CommandTrait> Pro // Retrieve the closure name. let closure_name = *closure.name(); + // Ensure the program has not exceeded the maximum number of closures. + ensure!(self.closures.len() < N::MAX_CLOSURES, "Program exceeds the maximum number of closures."); + // Ensure the closure name is new. ensure!(self.is_unique_name(&closure_name), "'{closure_name}' is already in use."); // Ensure the closure name is not a reserved opcode. @@ -575,6 +590,7 @@ impl, Command: CommandTrait> Pro "u64", "u128", "scalar", + "signature", "string", // Boolean "true", @@ -660,11 +676,11 @@ impl, Command: CommandTrait> Typ mod tests { use super::*; use console::{ - network::Testnet3, + network::MainnetV0, program::{Locator, ValueType}, }; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_program_mapping() -> Result<()> { @@ -792,9 +808,17 @@ function swap: assert_eq!(function.inputs().len(), 2); assert_eq!(function.input_types().len(), 2); + // Declare the expected input types. + let expected_input_type_1 = ValueType::ExternalRecord(Locator::from_str("eth.aleo/eth")?); + let expected_input_type_2 = ValueType::ExternalRecord(Locator::from_str("usdc.aleo/usdc")?); + // Ensure the inputs are external records. - assert_eq!(function.input_types()[0], ValueType::ExternalRecord(Locator::from_str("eth.aleo/eth")?)); - assert_eq!(function.input_types()[1], ValueType::ExternalRecord(Locator::from_str("usdc.aleo/usdc")?)); + assert_eq!(function.input_types()[0], expected_input_type_1); + assert_eq!(function.input_types()[1], expected_input_type_2); + + // Ensure the input variants are correct. + assert_eq!(function.input_types()[0].variant(), expected_input_type_1.variant()); + assert_eq!(function.input_types()[1].variant(), expected_input_type_2.variant()); // Ensure there are two instructions. assert_eq!(function.instructions().len(), 2); @@ -807,9 +831,17 @@ function swap: assert_eq!(function.outputs().len(), 2); assert_eq!(function.output_types().len(), 2); + // Declare the expected output types. + let expected_output_type_1 = ValueType::ExternalRecord(Locator::from_str("eth.aleo/eth")?); + let expected_output_type_2 = ValueType::ExternalRecord(Locator::from_str("usdc.aleo/usdc")?); + // Ensure the outputs are external records. - assert_eq!(function.output_types()[0], ValueType::ExternalRecord(Locator::from_str("eth.aleo/eth")?)); - assert_eq!(function.output_types()[1], ValueType::ExternalRecord(Locator::from_str("usdc.aleo/usdc")?)); + assert_eq!(function.output_types()[0], expected_output_type_1); + assert_eq!(function.output_types()[1], expected_output_type_2); + + // Ensure the output variants are correct. + assert_eq!(function.output_types()[0].variant(), expected_output_type_1.variant()); + assert_eq!(function.output_types()[1].variant(), expected_output_type_2.variant()); Ok(()) } diff --git a/synthesizer/program/src/logic/command/await_.rs b/synthesizer/program/src/logic/command/await_.rs index f7c43803ef..a0e2edebbe 100644 --- a/synthesizer/program/src/logic/command/await_.rs +++ b/synthesizer/program/src/logic/command/await_.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -114,9 +115,9 @@ impl ToBytes for Await { #[cfg(test)] mod tests { use super::*; - use console::{network::Testnet3, program::Register}; + use console::{network::MainnetV0, program::Register}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() { diff --git a/synthesizer/program/src/logic/command/branch.rs b/synthesizer/program/src/logic/command/branch.rs index a6ac651627..ff2a1f3ea8 100644 --- a/synthesizer/program/src/logic/command/branch.rs +++ b/synthesizer/program/src/logic/command/branch.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -167,11 +168,11 @@ impl ToBytes for Branch { mod tests { use super::*; use console::{ - network::Testnet3, + network::MainnetV0, program::{Identifier, Register}, }; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() { diff --git a/synthesizer/program/src/logic/command/contains.rs b/synthesizer/program/src/logic/command/contains.rs index 14e1618d89..375f56bdde 100644 --- a/synthesizer/program/src/logic/command/contains.rs +++ b/synthesizer/program/src/logic/command/contains.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,13 +14,14 @@ // limitations under the License. use crate::{ - traits::{FinalizeStoreTrait, RegistersLoad, RegistersStore, StackMatches, StackProgram}, + CallOperator, Opcode, Operand, + traits::{FinalizeStoreTrait, RegistersLoad, RegistersStore, StackMatches, StackProgram}, }; use console::{ network::prelude::*, - program::{Identifier, Literal, Register, Value}, + program::{Literal, Register, Value}, types::Boolean, }; @@ -28,7 +30,7 @@ use console::{ #[derive(Clone, PartialEq, Eq, Hash)] pub struct Contains { /// The mapping name. - mapping: Identifier, + mapping: CallOperator, /// The key to access the mapping. key: Operand, /// The destination register. @@ -48,9 +50,9 @@ impl Contains { vec![self.key.clone()] } - /// Returns the mapping name. + /// Returns the mapping. #[inline] - pub const fn mapping_name(&self) -> &Identifier { + pub const fn mapping(&self) -> &CallOperator { &self.mapping } @@ -76,16 +78,22 @@ impl Contains { store: &impl FinalizeStoreTrait, registers: &mut (impl RegistersLoad + RegistersStore), ) -> Result<()> { + // Determine the program ID and mapping name. + let (program_id, mapping_name) = match self.mapping { + CallOperator::Locator(locator) => (*locator.program_id(), *locator.resource()), + CallOperator::Resource(mapping_name) => (*stack.program_id(), mapping_name), + }; + // Ensure the mapping exists in storage. - if !store.contains_mapping_confirmed(stack.program_id(), &self.mapping)? { - bail!("Mapping '{}/{}' does not exist in storage", stack.program_id(), self.mapping); + if !store.contains_mapping_confirmed(&program_id, &mapping_name)? { + bail!("Mapping '{program_id}/{mapping_name}' does not exist in storage"); } // Load the operand as a plaintext. let key = registers.load_plaintext(stack, &self.key)?; // Determine if the key exists in the mapping. - let contains_key = store.contains_key_speculative(*stack.program_id(), self.mapping, &key)?; + let contains_key = store.contains_key_speculative(program_id, mapping_name, &key)?; // Assign the value to the destination register. registers.store(stack, &self.destination, Value::from(Literal::Boolean(Boolean::new(contains_key))))?; @@ -106,7 +114,7 @@ impl Parser for Contains { let (string, _) = Sanitizer::parse_whitespaces(string)?; // Parse the mapping name from the string. - let (string, mapping) = Identifier::parse(string)?; + let (string, mapping) = CallOperator::parse(string)?; // Parse the "[" from the string. let (string, _) = tag("[")(string)?; // Parse the whitespace from the string. @@ -177,7 +185,7 @@ impl FromBytes for Contains { /// Reads the command from a buffer. fn read_le(mut reader: R) -> IoResult { // Read the mapping name. - let mapping = Identifier::read_le(&mut reader)?; + let mapping = CallOperator::read_le(&mut reader)?; // Read the key operand. let key = Operand::read_le(&mut reader)?; // Read the destination register. @@ -202,17 +210,34 @@ impl ToBytes for Contains { #[cfg(test)] mod tests { use super::*; - use console::{network::Testnet3, program::Register}; + use console::{network::MainnetV0, program::Register}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() { let (string, contains) = Contains::::parse("contains account[r0] into r1;").unwrap(); assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); - assert_eq!(contains.mapping, Identifier::from_str("account").unwrap()); + assert_eq!(contains.mapping, CallOperator::from_str("account").unwrap()); assert_eq!(contains.operands().len(), 1, "The number of operands is incorrect"); assert_eq!(contains.key, Operand::Register(Register::Locator(0)), "The first operand is incorrect"); assert_eq!(contains.destination, Register::Locator(1), "The second operand is incorrect"); + + let (string, contains) = + Contains::::parse("contains credits.aleo/account[r0] into r1;").unwrap(); + assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); + assert_eq!(contains.mapping, CallOperator::from_str("credits.aleo/account").unwrap()); + assert_eq!(contains.operands().len(), 1, "The number of operands is incorrect"); + assert_eq!(contains.key, Operand::Register(Register::Locator(0)), "The first operand is incorrect"); + assert_eq!(contains.destination, Register::Locator(1), "The second operand is incorrect"); + } + + #[test] + fn test_from_bytes() { + let (string, contains) = Contains::::parse("contains account[r0] into r1;").unwrap(); + assert!(string.is_empty()); + let bytes_le = contains.to_bytes_le().unwrap(); + let result = Contains::::from_bytes_le(&bytes_le[..]); + assert!(result.is_ok()) } } diff --git a/synthesizer/program/src/logic/command/get.rs b/synthesizer/program/src/logic/command/get.rs index ac56eb92c0..9bcf7c2dce 100644 --- a/synthesizer/program/src/logic/command/get.rs +++ b/synthesizer/program/src/logic/command/get.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,123 +14,22 @@ // limitations under the License. use crate::{ - traits::{FinalizeStoreTrait, RegistersLoad, RegistersStore, StackMatches, StackProgram}, + CallOperator, Opcode, Operand, + traits::{FinalizeStoreTrait, RegistersLoad, RegistersStore, StackMatches, StackProgram}, }; use console::{ network::prelude::*, - program::{Identifier, Locator, Register, Value}, + program::{Register, Value}, }; -use std::io::{BufRead, BufReader}; - -/// The operator references a local or external mapping name. -#[derive(Clone, PartialEq, Eq, Hash)] -pub enum MappingLocator { - /// The reference to a non-local mapping name. - Locator(Locator), - /// The reference to a local mapping name. - Resource(Identifier), -} - -impl Parser for MappingLocator { - /// Parses a string into an operator. - #[inline] - fn parse(string: &str) -> ParserResult { - alt(( - map(Locator::parse, |locator| MappingLocator::Locator(locator)), - map(Identifier::parse, |identifier| MappingLocator::Resource(identifier)), - ))(string) - } -} - -impl FromStr for MappingLocator { - type Err = Error; - - /// Parses a string into an operator. - #[inline] - fn from_str(string: &str) -> Result { - match Self::parse(string) { - Ok((remainder, object)) => { - // Ensure the remainder is empty. - ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\""); - // Return the object. - Ok(object) - } - Err(error) => bail!("Failed to parse string. {error}"), - } - } -} - -impl Debug for MappingLocator { - /// Prints the operator as a string. - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - Display::fmt(self, f) - } -} - -impl Display for MappingLocator { - /// Prints the operator to a string. - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - MappingLocator::Locator(locator) => Display::fmt(locator, f), - MappingLocator::Resource(resource) => Display::fmt(resource, f), - } - } -} - -impl FromBytes for MappingLocator { - /// Reads the operation from a buffer. - fn read_le(mut reader: R) -> IoResult { - // Read the version. - let version = u8::read_le(&mut reader)?; - // Ensure the version is valid. - if version != 0 { - return Err(error("Failed to read MappingLocator. Invalid version.")); - } - // Read the variant. - let variant = u8::read_le(&mut reader)?; - // Match the variant. - match variant { - 0 => Ok(MappingLocator::Locator(Locator::read_le(&mut reader)?)), - 1 => Ok(MappingLocator::Resource(Identifier::read_le(&mut reader)?)), - _ => Err(error("Failed to read MappingLocator. Invalid variant.")), - } - } -} - -impl ToBytes for MappingLocator { - /// Writes the operation to a buffer. - fn write_le(&self, mut writer: W) -> IoResult<()> { - match self { - MappingLocator::Locator(locator) => { - // Write the version. - 0u8.write_le(&mut writer)?; - // Write the variant. - 0u8.write_le(&mut writer)?; - // Write the locator. - locator.write_le(&mut writer) - } - MappingLocator::Resource(resource) => { - // Write the version. - 0u8.write_le(&mut writer)?; - // Write the variant. - 1u8.write_le(&mut writer)?; - // Write the resource. - resource.write_le(&mut writer) - } - } - } -} - /// A get command, e.g. `get accounts[r0] into r1;`. /// Gets the value stored at `operand` in `mapping` and stores the result in `destination`. #[derive(Clone)] pub struct Get { /// The mapping. - // TODO (howardwu): For mainnet - Use `CallOperator`, delete the above `MappingLocator`. - mapping: MappingLocator, + mapping: CallOperator, /// The key to access the mapping. key: Operand, /// The destination register. @@ -171,7 +71,7 @@ impl Get { /// Returns the mapping. #[inline] - pub const fn mapping(&self) -> &MappingLocator { + pub const fn mapping(&self) -> &CallOperator { &self.mapping } @@ -199,8 +99,8 @@ impl Get { ) -> Result<()> { // Determine the program ID and mapping name. let (program_id, mapping_name) = match self.mapping { - MappingLocator::Locator(locator) => (*locator.program_id(), *locator.resource()), - MappingLocator::Resource(mapping_name) => (*stack.program_id(), mapping_name), + CallOperator::Locator(locator) => (*locator.program_id(), *locator.resource()), + CallOperator::Resource(mapping_name) => (*stack.program_id(), mapping_name), }; // Ensure the mapping exists in storage. @@ -239,7 +139,7 @@ impl Parser for Get { let (string, _) = Sanitizer::parse_whitespaces(string)?; // Parse the mapping name from the string. - let (string, mapping) = MappingLocator::parse(string)?; + let (string, mapping) = CallOperator::parse(string)?; // Parse the "[" from the string. let (string, _) = tag("[")(string)?; // Parse the whitespace from the string. @@ -308,22 +208,9 @@ impl Display for Get { impl FromBytes for Get { /// Reads the command from a buffer. - fn read_le(reader: R) -> IoResult { - // Peek at the first byte. - // TODO (howardwu): For mainnet - Read a `MappingLocator`. - let mut reader = BufReader::with_capacity(1, reader); - let first_byte = { - let buffer = reader.fill_buf()?; - match buffer.first() { - Some(byte) => *byte, - None => return Err(error("Failed to read `get`. Expected byte.")), - } - }; - // If the first byte is zero, then read a `MappingLocator`, otherwise read an `Identifier`. - let mapping = match first_byte { - 0u8 => MappingLocator::read_le(&mut reader)?, - _ => MappingLocator::Resource(Identifier::read_le(&mut reader)?), - }; + fn read_le(mut reader: R) -> IoResult { + // Read the mapping name. + let mapping = CallOperator::read_le(&mut reader)?; // Read the key operand. let key = Operand::read_le(&mut reader)?; // Read the destination register. @@ -334,14 +221,10 @@ impl FromBytes for Get { } impl ToBytes for Get { - /// Writes the operation to a buffer. + /// Writes the command to a buffer. fn write_le(&self, mut writer: W) -> IoResult<()> { // Write the mapping name. - // TODO (howardwu): For mainnet - Write `self.mapping` directly, instead of matching on the identifier case. - match &self.mapping { - MappingLocator::Locator(_) => self.mapping.write_le(&mut writer)?, - MappingLocator::Resource(identifier) => identifier.write_le(&mut writer)?, - } + self.mapping.write_le(&mut writer)?; // Write the key operand. self.key.write_le(&mut writer)?; // Write the destination register. @@ -352,42 +235,22 @@ impl ToBytes for Get { #[cfg(test)] mod tests { use super::*; - use console::{network::Testnet3, program::Register}; - - type CurrentNetwork = Testnet3; + use console::{network::MainnetV0, program::Register}; - struct OldGet { - mapping: Identifier, - key: Operand, - destination: Register, - } - - impl ToBytes for OldGet { - fn write_le(&self, mut writer: W) -> IoResult<()> - where - Self: Sized, - { - // Write the mapping name. - self.mapping.write_le(&mut writer)?; - // Write the key operand. - self.key.write_le(&mut writer)?; - // Write the destination register. - self.destination.write_le(&mut writer) - } - } + type CurrentNetwork = MainnetV0; #[test] fn test_parse() { let (string, get) = Get::::parse("get account[r0] into r1;").unwrap(); assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); - assert_eq!(get.mapping, MappingLocator::from_str("account").unwrap()); + assert_eq!(get.mapping, CallOperator::from_str("account").unwrap()); assert_eq!(get.operands().len(), 1, "The number of operands is incorrect"); assert_eq!(get.key, Operand::Register(Register::Locator(0)), "The first operand is incorrect"); assert_eq!(get.destination, Register::Locator(1), "The second operand is incorrect"); let (string, get) = Get::::parse("get token.aleo/balances[r0] into r1;").unwrap(); assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); - assert_eq!(get.mapping, MappingLocator::from_str("token.aleo/balances").unwrap()); + assert_eq!(get.mapping, CallOperator::from_str("token.aleo/balances").unwrap()); assert_eq!(get.operands().len(), 1, "The number of operands is incorrect"); assert_eq!(get.key, Operand::Register(Register::Locator(0)), "The first operand is incorrect"); assert_eq!(get.destination, Register::Locator(1), "The second operand is incorrect"); @@ -397,18 +260,8 @@ mod tests { fn test_from_bytes() { let (string, get) = Get::::parse("get account[r0] into r1;").unwrap(); assert!(string.is_empty()); - - let old_get = OldGet:: { - mapping: Identifier::from_str("account").unwrap(), - key: Operand::Register(Register::Locator(0)), - destination: Register::Locator(1), - }; - - let get_bytes = get.to_bytes_le().unwrap(); - let old_get_bytes = old_get.to_bytes_le().unwrap(); - - let first = Get::::from_bytes_le(&get_bytes[..]).unwrap(); - let second = Get::::from_bytes_le(&old_get_bytes[..]).unwrap(); - assert_eq!(first, second); + let bytes_le = get.to_bytes_le().unwrap(); + let result = Get::::from_bytes_le(&bytes_le[..]); + assert!(result.is_ok()) } } diff --git a/synthesizer/program/src/logic/command/get_or_use.rs b/synthesizer/program/src/logic/command/get_or_use.rs index 7c2ef6d7d7..fea8d94fc9 100644 --- a/synthesizer/program/src/logic/command/get_or_use.rs +++ b/synthesizer/program/src/logic/command/get_or_use.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,27 +14,23 @@ // limitations under the License. use crate::{ - traits::{FinalizeStoreTrait, RegistersLoad, RegistersStore, StackMatches, StackProgram}, - MappingLocator, + CallOperator, Opcode, Operand, + traits::{FinalizeStoreTrait, RegistersLoad, RegistersStore, StackMatches, StackProgram}, }; use console::{ network::prelude::*, program::{Register, Value}, }; -use console::program::Identifier; -use std::io::{BufRead, BufReader}; - /// A get command that uses the provided default in case of failure, e.g. `get.or_use accounts[r0] r1 into r2;`. /// Gets the value stored at `operand` in `mapping` and stores the result in `destination`. /// If the key is not present, `default` is stored in `destination`. #[derive(Clone)] pub struct GetOrUse { /// The mapping. - // TODO (howardwu): For mainnet - Use `CallOperator`, delete the above `MappingLocator`. - mapping: MappingLocator, + mapping: CallOperator, /// The key to access the mapping. key: Operand, /// The default value. @@ -79,7 +76,7 @@ impl GetOrUse { /// Returns the mapping. #[inline] - pub const fn mapping(&self) -> &MappingLocator { + pub const fn mapping(&self) -> &CallOperator { &self.mapping } @@ -113,8 +110,8 @@ impl GetOrUse { ) -> Result<()> { // Determine the program ID and mapping name. let (program_id, mapping_name) = match self.mapping { - MappingLocator::Locator(locator) => (*locator.program_id(), *locator.resource()), - MappingLocator::Resource(mapping_name) => (*stack.program_id(), mapping_name), + CallOperator::Locator(locator) => (*locator.program_id(), *locator.resource()), + CallOperator::Resource(mapping_name) => (*stack.program_id(), mapping_name), }; // Ensure the mapping exists in storage. @@ -154,7 +151,7 @@ impl Parser for GetOrUse { let (string, _) = Sanitizer::parse_whitespaces(string)?; // Parse the mapping name from the string. - let (string, mapping) = MappingLocator::parse(string)?; + let (string, mapping) = CallOperator::parse(string)?; // Parse the "[" from the string. let (string, _) = tag("[")(string)?; // Parse the whitespace from the string. @@ -227,22 +224,9 @@ impl Display for GetOrUse { impl FromBytes for GetOrUse { /// Reads the command from a buffer. - fn read_le(reader: R) -> IoResult { - // Peek at the first byte. - // TODO (howardwu): For mainnet - Read a `MappingLocator`. - let mut reader = BufReader::with_capacity(1, reader); - let first_byte = { - let buffer = reader.fill_buf()?; - match buffer.first() { - Some(byte) => *byte, - None => return Err(error("Failed to read `get.or_use`. Expected byte.")), - } - }; - // If the first byte is zero, then read a `MappingLocator`, otherwise read an `Identifier`. - let mapping = match first_byte { - 0u8 => MappingLocator::read_le(&mut reader)?, - _ => MappingLocator::Resource(Identifier::read_le(&mut reader)?), - }; + fn read_le(mut reader: R) -> IoResult { + // Read the mapping name. + let mapping = CallOperator::read_le(&mut reader)?; // Read the key operand. let key = Operand::read_le(&mut reader)?; // Read the default value. @@ -258,11 +242,7 @@ impl ToBytes for GetOrUse { /// Writes the operation to a buffer. fn write_le(&self, mut writer: W) -> IoResult<()> { // Write the mapping name. - // TODO (howardwu): For mainnet - Write the `self.mapping` directly, instead of matching on the identifier case. - match &self.mapping { - MappingLocator::Locator(_) => self.mapping.write_le(&mut writer)?, - MappingLocator::Resource(identifier) => identifier.write_le(&mut writer)?, - } + self.mapping.write_le(&mut writer)?; // Write the key operand. self.key.write_le(&mut writer)?; // Write the default value. @@ -275,35 +255,15 @@ impl ToBytes for GetOrUse { #[cfg(test)] mod tests { use super::*; - use console::{network::Testnet3, program::Register}; + use console::{network::MainnetV0, program::Register}; - type CurrentNetwork = Testnet3; - - pub struct OldGetOrUse { - pub mapping: Identifier, - pub key: Operand, - pub default: Operand, - pub destination: Register, - } - - impl ToBytes for OldGetOrUse { - fn write_le(&self, mut writer: W) -> IoResult<()> { - // Write the mapping name. - self.mapping.write_le(&mut writer)?; - // Write the key operand. - self.key.write_le(&mut writer)?; - // Write the default value. - self.default.write_le(&mut writer)?; - // Write the destination register. - self.destination.write_le(&mut writer) - } - } + type CurrentNetwork = MainnetV0; #[test] fn test_parse() { let (string, get_or_use) = GetOrUse::::parse("get.or_use account[r0] r1 into r2;").unwrap(); assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); - assert_eq!(get_or_use.mapping, MappingLocator::from_str("account").unwrap()); + assert_eq!(get_or_use.mapping, CallOperator::from_str("account").unwrap()); assert_eq!(get_or_use.operands().len(), 2, "The number of operands is incorrect"); assert_eq!(get_or_use.key, Operand::Register(Register::Locator(0)), "The first operand is incorrect"); assert_eq!(get_or_use.default, Operand::Register(Register::Locator(1)), "The second operand is incorrect"); @@ -312,7 +272,7 @@ mod tests { let (string, get_or_use) = GetOrUse::::parse("get.or_use token.aleo/balances[r0] r1 into r2;").unwrap(); assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'"); - assert_eq!(get_or_use.mapping, MappingLocator::from_str("token.aleo/balances").unwrap()); + assert_eq!(get_or_use.mapping, CallOperator::from_str("token.aleo/balances").unwrap()); assert_eq!(get_or_use.operands().len(), 2, "The number of operands is incorrect"); assert_eq!(get_or_use.key, Operand::Register(Register::Locator(0)), "The first operand is incorrect"); assert_eq!(get_or_use.default, Operand::Register(Register::Locator(1)), "The second operand is incorrect"); @@ -323,19 +283,8 @@ mod tests { fn test_from_bytes() { let (string, get_or_use) = GetOrUse::::parse("get.or_use account[r0] r1 into r2;").unwrap(); assert!(string.is_empty()); - - let old_get_or_use = OldGetOrUse:: { - mapping: Identifier::from_str("account").unwrap(), - key: Operand::Register(Register::Locator(0)), - default: Operand::Register(Register::Locator(1)), - destination: Register::Locator(2), - }; - - let get_or_use_bytes = get_or_use.to_bytes_le().unwrap(); - let old_get_or_use_bytes = old_get_or_use.to_bytes_le().unwrap(); - - let first = GetOrUse::::from_bytes_le(&get_or_use_bytes[..]).unwrap(); - let second = GetOrUse::::from_bytes_le(&old_get_or_use_bytes[..]).unwrap(); - assert_eq!(first, second); + let bytes_le = get_or_use.to_bytes_le().unwrap(); + let result = GetOrUse::::from_bytes_le(&bytes_le[..]); + assert!(result.is_ok()); } } diff --git a/synthesizer/program/src/logic/command/mod.rs b/synthesizer/program/src/logic/command/mod.rs index 5e5aa7c750..e31408db76 100644 --- a/synthesizer/program/src/logic/command/mod.rs +++ b/synthesizer/program/src/logic/command/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -40,6 +41,10 @@ mod set; pub use set::*; use crate::{ + CastType, + FinalizeOperation, + FinalizeRegistersState, + Instruction, traits::{ CommandTrait, FinalizeStoreTrait, @@ -49,10 +54,6 @@ use crate::{ StackMatches, StackProgram, }, - CastType, - FinalizeOperation, - FinalizeRegistersState, - Instruction, }; use console::{ network::prelude::*, @@ -357,9 +358,9 @@ impl Display for Command { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_command_bytes() { diff --git a/synthesizer/program/src/logic/command/position.rs b/synthesizer/program/src/logic/command/position.rs index d0fb251a43..7e26484e08 100644 --- a/synthesizer/program/src/logic/command/position.rs +++ b/synthesizer/program/src/logic/command/position.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -125,9 +126,9 @@ impl ToBytes for Position { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() { diff --git a/synthesizer/program/src/logic/command/rand_chacha.rs b/synthesizer/program/src/logic/command/rand_chacha.rs index 829bab7373..44aa938c97 100644 --- a/synthesizer/program/src/logic/command/rand_chacha.rs +++ b/synthesizer/program/src/logic/command/rand_chacha.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,15 +14,15 @@ // limitations under the License. use crate::{ - traits::{RegistersLoad, RegistersStore, StackMatches, StackProgram}, FinalizeRegistersState, Opcode, Operand, + traits::{RegistersLoad, RegistersStore, StackMatches, StackProgram}, }; use console::{ network::prelude::*, program::{Literal, LiteralType, Plaintext, Register, Value}, - types::{Address, Boolean, Field, Group, Scalar, I128, I16, I32, I64, I8, U128, U16, U32, U64, U8}, + types::{Address, Boolean, Field, Group, I8, I16, I32, I64, I128, Scalar, U8, U16, U32, U64, U128}, }; use rand::SeedableRng; @@ -288,9 +289,9 @@ impl ToBytes for RandChaCha { #[cfg(test)] mod tests { use super::*; - use console::{network::Testnet3, program::Register}; + use console::{network::MainnetV0, program::Register}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; fn valid_destination_types() -> &'static [LiteralType] { &[ diff --git a/synthesizer/program/src/logic/command/remove.rs b/synthesizer/program/src/logic/command/remove.rs index 52ce26629f..185a26048d 100644 --- a/synthesizer/program/src/logic/command/remove.rs +++ b/synthesizer/program/src/logic/command/remove.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,10 +14,10 @@ // limitations under the License. use crate::{ - traits::{FinalizeStoreTrait, RegistersLoad, StackMatches, StackProgram}, FinalizeOperation, Opcode, Operand, + traits::{FinalizeStoreTrait, RegistersLoad, StackMatches, StackProgram}, }; use console::{network::prelude::*, program::Identifier}; @@ -167,9 +168,9 @@ impl ToBytes for Remove { #[cfg(test)] mod tests { use super::*; - use console::{network::Testnet3, program::Register}; + use console::{network::MainnetV0, program::Register}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() { diff --git a/synthesizer/program/src/logic/command/set.rs b/synthesizer/program/src/logic/command/set.rs index 83d187dde7..68c5b9e96e 100644 --- a/synthesizer/program/src/logic/command/set.rs +++ b/synthesizer/program/src/logic/command/set.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,10 +14,10 @@ // limitations under the License. use crate::{ - traits::{FinalizeStoreTrait, RegistersLoad, StackMatches, StackProgram}, FinalizeOperation, Opcode, Operand, + traits::{FinalizeStoreTrait, RegistersLoad, StackMatches, StackProgram}, }; use console::{ network::prelude::*, @@ -199,9 +200,9 @@ impl ToBytes for Set { #[cfg(test)] mod tests { use super::*; - use console::{network::Testnet3, program::Register}; + use console::{network::MainnetV0, program::Register}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() { diff --git a/synthesizer/program/src/logic/finalize_global_state/mod.rs b/synthesizer/program/src/logic/finalize_global_state/mod.rs index 7bded83d09..20fe845a09 100644 --- a/synthesizer/program/src/logic/finalize_global_state/mod.rs +++ b/synthesizer/program/src/logic/finalize_global_state/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/logic/finalize_operation/bits.rs b/synthesizer/program/src/logic/finalize_operation/bits.rs index 504bbd9d15..7613f5711b 100644 --- a/synthesizer/program/src/logic/finalize_operation/bits.rs +++ b/synthesizer/program/src/logic/finalize_operation/bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -52,22 +53,20 @@ impl FromBits for FinalizeOperation { 2 => { // Read the mapping ID. let mapping_id = Field::from_bits_le(&next_bits(Field::::size_in_bits())?)?; - // Read the index. - let index = u64::from_bits_le(&next_bits(64)?)?; // Read the key ID. let key_id = Field::from_bits_le(&next_bits(Field::::size_in_bits())?)?; // Read the value ID. let value_id = Field::from_bits_le(&next_bits(Field::::size_in_bits())?)?; // Return the finalize operation. - Ok(Self::UpdateKeyValue(mapping_id, index, key_id, value_id)) + Ok(Self::UpdateKeyValue(mapping_id, key_id, value_id)) } 3 => { // Read the mapping ID. let mapping_id = Field::from_bits_le(&next_bits(Field::::size_in_bits())?)?; - // Read the index. - let index = u64::from_bits_le(&next_bits(64)?)?; + // Read the key ID. + let key_id = Field::from_bits_le(&next_bits(Field::::size_in_bits())?)?; // Return the finalize operation. - Ok(Self::RemoveKeyValue(mapping_id, index)) + Ok(Self::RemoveKeyValue(mapping_id, key_id)) } 4 => { // Read the mapping ID. @@ -122,22 +121,20 @@ impl FromBits for FinalizeOperation { 2 => { // Read the mapping ID. let mapping_id = Field::from_bits_be(&next_bits(Field::::size_in_bits())?)?; - // Read the index. - let index = u64::from_bits_be(&next_bits(64)?)?; // Read the key ID. let key_id = Field::from_bits_be(&next_bits(Field::::size_in_bits())?)?; // Read the value ID. let value_id = Field::from_bits_be(&next_bits(Field::::size_in_bits())?)?; // Return the finalize operation. - Ok(Self::UpdateKeyValue(mapping_id, index, key_id, value_id)) + Ok(Self::UpdateKeyValue(mapping_id, key_id, value_id)) } 3 => { // Read the mapping ID. let mapping_id = Field::from_bits_be(&next_bits(Field::::size_in_bits())?)?; - // Read the index. - let index = u64::from_bits_be(&next_bits(64)?)?; + // Read the key ID. + let key_id = Field::from_bits_be(&next_bits(Field::::size_in_bits())?)?; // Return the finalize operation. - Ok(Self::RemoveKeyValue(mapping_id, index)) + Ok(Self::RemoveKeyValue(mapping_id, key_id)) } 4 => { // Read the mapping ID. @@ -176,25 +173,23 @@ impl ToBits for FinalizeOperation { // Write the value ID. value_id.write_bits_le(vec); } - Self::UpdateKeyValue(mapping_id, index, key_id, value_id) => { + Self::UpdateKeyValue(mapping_id, key_id, value_id) => { // Write the variant. 2u8.write_bits_le(vec); // Write the mapping ID. mapping_id.write_bits_le(vec); - // Write the index. - index.write_bits_le(vec); // Write the key ID. key_id.write_bits_le(vec); // Write the value ID. value_id.write_bits_le(vec); } - Self::RemoveKeyValue(mapping_id, index) => { + Self::RemoveKeyValue(mapping_id, key_id) => { // Write the variant. 3u8.write_bits_le(vec); // Write the mapping ID. mapping_id.write_bits_le(vec); - // Write the index. - index.write_bits_le(vec); + // Write the key ID. + key_id.write_bits_le(vec); } Self::ReplaceMapping(mapping_id) => { // Write the variant. @@ -230,25 +225,23 @@ impl ToBits for FinalizeOperation { // Write the value ID. value_id.write_bits_be(vec); } - Self::UpdateKeyValue(mapping_id, index, key_id, value_id) => { + Self::UpdateKeyValue(mapping_id, key_id, value_id) => { // Write the variant. 2u8.write_bits_be(vec); // Write the mapping ID. mapping_id.write_bits_be(vec); - // Write the index. - index.write_bits_be(vec); // Write the key ID. key_id.write_bits_be(vec); // Write the value ID. value_id.write_bits_be(vec); } - Self::RemoveKeyValue(mapping_id, index) => { + Self::RemoveKeyValue(mapping_id, key_id) => { // Write the variant. 3u8.write_bits_be(vec); // Write the mapping ID. mapping_id.write_bits_be(vec); - // Write the index. - index.write_bits_be(vec); + // Write the key ID. + key_id.write_bits_be(vec); } Self::ReplaceMapping(mapping_id) => { // Write the variant. diff --git a/synthesizer/program/src/logic/finalize_operation/bytes.rs b/synthesizer/program/src/logic/finalize_operation/bytes.rs index a88e65a10c..85ec3b17cb 100644 --- a/synthesizer/program/src/logic/finalize_operation/bytes.rs +++ b/synthesizer/program/src/logic/finalize_operation/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -40,22 +41,20 @@ impl FromBytes for FinalizeOperation { 2 => { // Read the mapping ID. let mapping_id = Field::read_le(&mut reader)?; - // Read the index. - let index = u64::read_le(&mut reader)?; // Read the key ID. let key_id = Field::read_le(&mut reader)?; // Read the value ID. let value_id = Field::read_le(&mut reader)?; // Return the finalize operation. - Ok(Self::UpdateKeyValue(mapping_id, index, key_id, value_id)) + Ok(Self::UpdateKeyValue(mapping_id, key_id, value_id)) } 3 => { // Read the mapping ID. let mapping_id = Field::read_le(&mut reader)?; - // Read the index. - let index = u64::read_le(&mut reader)?; + // Read the key ID. + let key_id = Field::read_le(&mut reader)?; // Return the finalize operation. - Ok(Self::RemoveKeyValue(mapping_id, index)) + Ok(Self::RemoveKeyValue(mapping_id, key_id)) } 4 => { // Read the mapping ID. @@ -94,25 +93,23 @@ impl ToBytes for FinalizeOperation { // Write the value ID. value_id.write_le(&mut writer)?; } - Self::UpdateKeyValue(mapping_id, index, key_id, value_id) => { + Self::UpdateKeyValue(mapping_id, key_id, value_id) => { // Write the variant. 2u8.write_le(&mut writer)?; // Write the mapping ID. mapping_id.write_le(&mut writer)?; - // Write the index. - index.write_le(&mut writer)?; // Write the key ID. key_id.write_le(&mut writer)?; // Write the value ID. value_id.write_le(&mut writer)?; } - Self::RemoveKeyValue(mapping_id, index) => { + Self::RemoveKeyValue(mapping_id, key_id) => { // Write the variant. 3u8.write_le(&mut writer)?; // Write the mapping ID. mapping_id.write_le(&mut writer)?; - // Write the index. - index.write_le(&mut writer)?; + // Write the key ID. + key_id.write_le(&mut writer)?; } Self::ReplaceMapping(mapping_id) => { // Write the variant. diff --git a/synthesizer/program/src/logic/finalize_operation/mod.rs b/synthesizer/program/src/logic/finalize_operation/mod.rs index 15de98767d..5e4c2c2fd4 100644 --- a/synthesizer/program/src/logic/finalize_operation/mod.rs +++ b/synthesizer/program/src/logic/finalize_operation/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -27,12 +28,12 @@ pub enum FinalizeOperation { /// Inserts a key-value leaf into the mapping tree, /// as (`mapping ID`, `key ID`, `value ID`). InsertKeyValue(Field, Field, Field), - /// Updates the key-value leaf at the given index in the mapping tree, - /// as (`mapping ID`, `index`, `key ID`, `value ID`). - UpdateKeyValue(Field, u64, Field, Field), - /// Removes the key-value leaf at the given index in the mapping tree, - /// as (`mapping ID`, `index`). - RemoveKeyValue(Field, u64), + /// Updates the key-value leaf in the mapping tree, + /// as (`mapping ID`, `key ID`, `value ID`). + UpdateKeyValue(Field, Field, Field), + /// Removes the key-value leaf in the mapping tree, + /// as (`mapping ID`, `key ID`). + RemoveKeyValue(Field, Field), /// Replaces a mapping from the program tree, as (`mapping ID`). ReplaceMapping(Field), /// Removes a mapping from the program tree, as (`mapping ID`). @@ -42,9 +43,9 @@ pub enum FinalizeOperation { #[cfg(test)] pub(crate) mod test_helpers { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Samples a random `InitializeMapping`. pub(crate) fn sample_initialize_mapping(rng: &mut TestRng) -> FinalizeOperation { @@ -58,12 +59,12 @@ pub(crate) mod test_helpers { /// Samples a random `UpdateKeyValue`. pub(crate) fn sample_update_key_value(rng: &mut TestRng) -> FinalizeOperation { - FinalizeOperation::UpdateKeyValue(Uniform::rand(rng), rng.gen(), Uniform::rand(rng), Uniform::rand(rng)) + FinalizeOperation::UpdateKeyValue(Uniform::rand(rng), Uniform::rand(rng), Uniform::rand(rng)) } /// Samples a random `RemoveKeyValue`. pub(crate) fn sample_remove_key_value(rng: &mut TestRng) -> FinalizeOperation { - FinalizeOperation::RemoveKeyValue(Uniform::rand(rng), rng.gen()) + FinalizeOperation::RemoveKeyValue(Uniform::rand(rng), Uniform::rand(rng)) } /// Samples a random `ReplaceMapping`. diff --git a/synthesizer/program/src/logic/finalize_operation/serialize.rs b/synthesizer/program/src/logic/finalize_operation/serialize.rs index 1a128d3e94..18aff66762 100644 --- a/synthesizer/program/src/logic/finalize_operation/serialize.rs +++ b/synthesizer/program/src/logic/finalize_operation/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -35,20 +36,19 @@ impl Serialize for FinalizeOperation { operation.serialize_field("value_id", value_id)?; operation.end() } - Self::UpdateKeyValue(mapping_id, index, key_id, value_id) => { - let mut operation = serializer.serialize_struct("FinalizeOperation", 5)?; + Self::UpdateKeyValue(mapping_id, key_id, value_id) => { + let mut operation = serializer.serialize_struct("FinalizeOperation", 4)?; operation.serialize_field("type", "update_key_value")?; operation.serialize_field("mapping_id", mapping_id)?; - operation.serialize_field("index", index)?; operation.serialize_field("key_id", key_id)?; operation.serialize_field("value_id", value_id)?; operation.end() } - Self::RemoveKeyValue(mapping_id, index) => { + Self::RemoveKeyValue(mapping_id, key_id) => { let mut operation = serializer.serialize_struct("FinalizeOperation", 3)?; operation.serialize_field("type", "remove_key_value")?; operation.serialize_field("mapping_id", mapping_id)?; - operation.serialize_field("index", index)?; + operation.serialize_field("key_id", key_id)?; operation.end() } Self::ReplaceMapping(mapping_id) => { @@ -97,22 +97,20 @@ impl<'de, N: Network> Deserialize<'de> for FinalizeOperation { Some("update_key_value") => { // Deserialize the mapping ID. let mapping_id = DeserializeExt::take_from_value::(&mut operation, "mapping_id")?; - // Deserialize the index. - let index = DeserializeExt::take_from_value::(&mut operation, "index")?; // Deserialize the key ID. let key_id = DeserializeExt::take_from_value::(&mut operation, "key_id")?; // Deserialize the value ID. let value_id = DeserializeExt::take_from_value::(&mut operation, "value_id")?; // Return the operation. - Self::UpdateKeyValue(mapping_id, index, key_id, value_id) + Self::UpdateKeyValue(mapping_id, key_id, value_id) } Some("remove_key_value") => { // Deserialize the mapping ID. let mapping_id = DeserializeExt::take_from_value::(&mut operation, "mapping_id")?; - // Deserialize the index. - let index = DeserializeExt::take_from_value::(&mut operation, "index")?; + // Deserialize the key ID. + let key_id = DeserializeExt::take_from_value::(&mut operation, "key_id")?; // Return the operation. - Self::RemoveKeyValue(mapping_id, index) + Self::RemoveKeyValue(mapping_id, key_id) } Some("replace_mapping") => { // Deserialize the mapping ID. diff --git a/synthesizer/program/src/logic/finalize_operation/string.rs b/synthesizer/program/src/logic/finalize_operation/string.rs index 47a7051a54..080c151c37 100644 --- a/synthesizer/program/src/logic/finalize_operation/string.rs +++ b/synthesizer/program/src/logic/finalize_operation/string.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/logic/instruction/bytes.rs b/synthesizer/program/src/logic/instruction/bytes.rs index 0c0c35954a..04ba7f90e8 100644 --- a/synthesizer/program/src/logic/instruction/bytes.rs +++ b/synthesizer/program/src/logic/instruction/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -64,6 +65,8 @@ impl ToBytes for Instruction { let index = Instruction::::OPCODES.iter().position(|&opcode| $variant::::opcode() == opcode).unwrap(); // Serialize the instruction. + // Note that this cast is safe as the number of instructions is less than `u16::MAX`. + #[allow(clippy::cast_possible_truncation)] u16::write_le(&(index as u16),&mut $writer)?; instruction.write_le(&mut $writer)?; }),+ @@ -79,9 +82,9 @@ impl ToBytes for Instruction { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_bytes() -> Result<()> { diff --git a/synthesizer/program/src/logic/instruction/mod.rs b/synthesizer/program/src/logic/instruction/mod.rs index 930920ca5e..22b516e662 100644 --- a/synthesizer/program/src/logic/instruction/mod.rs +++ b/synthesizer/program/src/logic/instruction/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -38,13 +39,6 @@ use crate::traits::{ use console::{ network::Network, prelude::{ - alt, - bail, - ensure, - error, - fmt, - map, - tag, Debug, Display, Error, @@ -59,6 +53,13 @@ use console::{ Sanitizer, ToBytes, Write, + alt, + bail, + ensure, + error, + fmt, + map, + tag, }, program::{Register, RegisterType}, }; @@ -461,13 +462,14 @@ impl Display for Instruction { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_opcodes() { // Sanity check the number of instructions is unchanged. + // Note that the number of opcodes **MUST NOT** exceed u16::MAX. assert_eq!( 68, Instruction::::OPCODES.len(), diff --git a/synthesizer/program/src/logic/instruction/opcode/mod.rs b/synthesizer/program/src/logic/instruction/opcode/mod.rs index da08374972..d24ad6afae 100644 --- a/synthesizer/program/src/logic/instruction/opcode/mod.rs +++ b/synthesizer/program/src/logic/instruction/opcode/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/logic/instruction/operand/bytes.rs b/synthesizer/program/src/logic/instruction/operand/bytes.rs index 729fd26090..050cc63c9e 100644 --- a/synthesizer/program/src/logic/instruction/operand/bytes.rs +++ b/synthesizer/program/src/logic/instruction/operand/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -23,6 +24,7 @@ impl FromBytes for Operand { 3 => Ok(Self::Signer), 4 => Ok(Self::Caller), 5 => Ok(Self::BlockHeight), + 6 => Ok(Self::NetworkID), variant => Err(error(format!("Failed to deserialize operand variant {variant}"))), } } @@ -46,6 +48,7 @@ impl ToBytes for Operand { Self::Signer => 3u8.write_le(&mut writer), Self::Caller => 4u8.write_le(&mut writer), Self::BlockHeight => 5u8.write_le(&mut writer), + Self::NetworkID => 6u8.write_le(&mut writer), } } } diff --git a/synthesizer/program/src/logic/instruction/operand/mod.rs b/synthesizer/program/src/logic/instruction/operand/mod.rs index c7f180d4c9..2e05f39376 100644 --- a/synthesizer/program/src/logic/instruction/operand/mod.rs +++ b/synthesizer/program/src/logic/instruction/operand/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -40,6 +41,9 @@ pub enum Operand { /// The operand is the block height. /// Note: This variant is only accessible in the `finalize` scope. BlockHeight, + /// The operand is the network ID. + /// Note: This variant is only accessible in the `finalize` scope. + NetworkID, } impl From> for Operand { @@ -77,9 +81,9 @@ impl From<&Register> for Operand { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_operand_from_literal() -> Result<()> { diff --git a/synthesizer/program/src/logic/instruction/operand/parse.rs b/synthesizer/program/src/logic/instruction/operand/parse.rs index ccc699ee60..4a0c415714 100644 --- a/synthesizer/program/src/logic/instruction/operand/parse.rs +++ b/synthesizer/program/src/logic/instruction/operand/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -26,6 +27,7 @@ impl Parser for Operand { map(tag("self.signer"), |_| Self::Signer), map(tag("self.caller"), |_| Self::Caller), map(tag("block.height"), |_| Self::BlockHeight), + map(tag("network.id"), |_| Self::NetworkID), // Note that `Operand::ProgramID`s must be parsed before `Operand::Literal`s, since a program ID can be implicitly parsed as a literal address. // This ensures that the string representation of a program uses the `Operand::ProgramID` variant. map(ProgramID::parse, |program_id| Self::ProgramID(program_id)), @@ -76,6 +78,8 @@ impl Display for Operand { Self::Caller => write!(f, "self.caller"), // Prints the identifier for the block height, i.e. block.height Self::BlockHeight => write!(f, "block.height"), + // Prints the identifier for the network ID, i.e. network.id + Self::NetworkID => write!(f, "network.id"), } } } @@ -83,9 +87,9 @@ impl Display for Operand { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_operand_parse() -> Result<()> { @@ -110,6 +114,9 @@ mod tests { let operand = Operand::::parse("block.height").unwrap().1; assert_eq!(Operand::BlockHeight, operand); + let operand = Operand::::parse("network.id").unwrap().1; + assert_eq!(Operand::NetworkID, operand); + let operand = Operand::::parse("group::GEN").unwrap().1; assert_eq!(Operand::Literal(Literal::Group(Group::generator())), operand); diff --git a/synthesizer/program/src/logic/instruction/operation/assert.rs b/synthesizer/program/src/logic/instruction/operation/assert.rs index ee9a36b7ba..57b05b1a5c 100644 --- a/synthesizer/program/src/logic/instruction/operation/assert.rs +++ b/synthesizer/program/src/logic/instruction/operation/assert.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,9 +14,9 @@ // limitations under the License. use crate::{ - traits::{RegistersLoad, RegistersLoadCircuit, StackMatches, StackProgram}, Opcode, Operand, + traits::{RegistersLoad, RegistersLoadCircuit, StackMatches, StackProgram}, }; use console::{ network::prelude::*, @@ -263,9 +264,9 @@ impl ToBytes for AssertInstruction { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() { diff --git a/synthesizer/program/src/logic/instruction/operation/async_.rs b/synthesizer/program/src/logic/instruction/operation/async_.rs index 194fa8a5f9..b151dd7313 100644 --- a/synthesizer/program/src/logic/instruction/operation/async_.rs +++ b/synthesizer/program/src/logic/instruction/operation/async_.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,13 +14,13 @@ // limitations under the License. use crate::{ - traits::{RegistersLoad, StackMatches, StackProgram}, Opcode, Operand, RegistersLoadCircuit, RegistersStore, RegistersStoreCircuit, Result, + traits::{RegistersLoad, StackMatches, StackProgram}, }; use circuit::{Inject, Mode}; @@ -348,9 +349,9 @@ impl ToBytes for Async { mod tests { use super::*; // use circuit::AleoV0; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; // type CurrentAleo = AleoV0; // // /// Samples the stack. Note: Do not replicate this for real program use, it is insecure. diff --git a/synthesizer/program/src/logic/instruction/operation/call.rs b/synthesizer/program/src/logic/instruction/operation/call.rs index 12cc42168d..b5cbaf8d51 100644 --- a/synthesizer/program/src/logic/instruction/operation/call.rs +++ b/synthesizer/program/src/logic/instruction/operation/call.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,9 +14,9 @@ // limitations under the License. use crate::{ - traits::{RegistersLoad, RegistersLoadCircuit, StackMatches, StackProgram}, Opcode, Operand, + traits::{RegistersLoad, RegistersLoadCircuit, StackMatches, StackProgram}, }; use console::{ network::prelude::*, @@ -444,11 +445,11 @@ impl ToBytes for Call { mod tests { use super::*; use console::{ - network::Testnet3, + network::MainnetV0, program::{Access, Address, Identifier, Literal, U64}, }; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; const TEST_CASES: &[&str] = &[ "call foo", diff --git a/synthesizer/program/src/logic/instruction/operation/cast.rs b/synthesizer/program/src/logic/instruction/operation/cast.rs index a516daf425..fb24f67c2b 100644 --- a/synthesizer/program/src/logic/instruction/operation/cast.rs +++ b/synthesizer/program/src/logic/instruction/operation/cast.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,6 +14,8 @@ // limitations under the License. use crate::{ + Opcode, + Operand, traits::{ RegistersLoad, RegistersLoadCircuit, @@ -23,8 +26,6 @@ use crate::{ StackMatches, StackProgram, }, - Opcode, - Operand, }; use console::{ network::prelude::*, @@ -206,9 +207,12 @@ impl CastOperation { stack: &(impl StackMatches + StackProgram), registers: &mut (impl RegistersSigner + RegistersLoad + RegistersStore), ) -> Result<()> { - // TODO (howardwu & d0cd): Re-enable after stabilizing. + // If the variant is `cast.lossy`, then check that the `cast_type` is a `PlaintextType::Literal`. if VARIANT == CastVariant::CastLossy as u8 { - bail!("cast.lossy is not supported (yet)") + ensure!( + matches!(self.cast_type, CastType::Plaintext(PlaintextType::Literal(..))), + "`cast.lossy` is only supported for casting to a literal type" + ) } // Load the operands values. @@ -333,9 +337,12 @@ impl CastOperation { stack: &(impl StackMatches + StackProgram), registers: &mut (impl RegistersSignerCircuit + RegistersLoadCircuit + RegistersStoreCircuit), ) -> Result<()> { - // TODO (howardwu & d0cd): Re-enable after stabilizing. + // If the variant is `cast.lossy`, then check that the `cast_type` is a `PlaintextType::Literal`. if VARIANT == CastVariant::CastLossy as u8 { - bail!("cast.lossy is not supported (yet)") + ensure!( + matches!(self.cast_type, CastType::Plaintext(PlaintextType::Literal(..))), + "`cast.lossy` is only supported for casting to a literal type" + ) } use circuit::{Eject, Inject}; @@ -582,9 +589,12 @@ impl CastOperation { stack: &(impl StackMatches + StackProgram), registers: &mut (impl RegistersLoad + RegistersStore), ) -> Result<()> { - // TODO (howardwu & d0cd): Re-enable after stabilizing. + // If the variant is `cast.lossy`, then check that the `cast_type` is a `PlaintextType::Literal`. if VARIANT == CastVariant::CastLossy as u8 { - bail!("cast.lossy is not supported (yet)") + ensure!( + matches!(self.cast_type, CastType::Plaintext(PlaintextType::Literal(..))), + "`cast.lossy` is only supported for casting to a literal type" + ) } // Load the operands values. @@ -641,6 +651,14 @@ impl CastOperation { stack: &impl StackProgram, input_types: &[RegisterType], ) -> Result>> { + // If the variant is `cast.lossy`, then check that the `cast_type` is a `PlaintextType::Literal`. + if VARIANT == CastVariant::CastLossy as u8 { + ensure!( + matches!(self.cast_type, CastType::Plaintext(PlaintextType::Literal(..))), + "`cast.lossy` is only supported for casting to a literal type" + ) + } + // Ensure the number of operands is correct. ensure!( input_types.len() == self.operands.len(), @@ -1108,11 +1126,11 @@ impl ToBytes for CastOperation { mod tests { use super::*; use console::{ - network::Testnet3, + network::MainnetV0, program::{Access, Identifier}, }; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() { diff --git a/synthesizer/program/src/logic/instruction/operation/commit.rs b/synthesizer/program/src/logic/instruction/operation/commit.rs index ffc3320cd0..df86369984 100644 --- a/synthesizer/program/src/logic/instruction/operation/commit.rs +++ b/synthesizer/program/src/logic/instruction/operation/commit.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,9 +14,9 @@ // limitations under the License. use crate::{ - traits::{RegistersLoad, RegistersLoadCircuit, RegistersStore, RegistersStoreCircuit, StackMatches, StackProgram}, Opcode, Operand, + traits::{RegistersLoad, RegistersLoadCircuit, RegistersStore, RegistersStoreCircuit, StackMatches, StackProgram}, }; use console::{ network::prelude::*, @@ -349,9 +350,9 @@ impl ToBytes for CommitInstruction { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// **Attention**: When changing this, also update in `tests/instruction/commit.rs`. fn valid_destination_types() -> &'static [LiteralType] { diff --git a/synthesizer/program/src/logic/instruction/operation/hash.rs b/synthesizer/program/src/logic/instruction/operation/hash.rs index cd7954e887..7a7ef228f2 100644 --- a/synthesizer/program/src/logic/instruction/operation/hash.rs +++ b/synthesizer/program/src/logic/instruction/operation/hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,9 +14,9 @@ // limitations under the License. use crate::{ - traits::{RegistersLoad, RegistersLoadCircuit, RegistersStore, RegistersStoreCircuit, StackMatches, StackProgram}, Opcode, Operand, + traits::{RegistersLoad, RegistersLoadCircuit, RegistersStore, RegistersStoreCircuit, StackMatches, StackProgram}, }; use console::{ network::prelude::*, @@ -497,9 +498,9 @@ impl ToBytes for HashInstruction { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// **Attention**: When changing this, also update in `tests/instruction/hash.rs`. fn valid_destination_types() -> &'static [PlaintextType] { diff --git a/synthesizer/program/src/logic/instruction/operation/is.rs b/synthesizer/program/src/logic/instruction/operation/is.rs index aa56e93757..7a5aaa8243 100644 --- a/synthesizer/program/src/logic/instruction/operation/is.rs +++ b/synthesizer/program/src/logic/instruction/operation/is.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,9 +14,9 @@ // limitations under the License. use crate::{ - traits::{RegistersLoad, RegistersLoadCircuit, RegistersStore, RegistersStoreCircuit, StackMatches, StackProgram}, Opcode, Operand, + traits::{RegistersLoad, RegistersLoadCircuit, RegistersStore, RegistersStoreCircuit, StackMatches, StackProgram}, }; use console::{ network::prelude::*, @@ -275,9 +276,9 @@ impl ToBytes for IsInstruction { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() { diff --git a/synthesizer/program/src/logic/instruction/operation/literals.rs b/synthesizer/program/src/logic/instruction/operation/literals.rs index 9201e58ebe..c2b2c630dc 100644 --- a/synthesizer/program/src/logic/instruction/operation/literals.rs +++ b/synthesizer/program/src/logic/instruction/operation/literals.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,10 +14,10 @@ // limitations under the License. use crate::{ - traits::{RegistersLoad, RegistersLoadCircuit, RegistersStore, RegistersStoreCircuit, StackMatches, StackProgram}, Opcode, Operand, Operation, + traits::{RegistersLoad, RegistersLoadCircuit, RegistersStore, RegistersStoreCircuit, StackMatches, StackProgram}, }; use console::{ network::prelude::*, diff --git a/synthesizer/program/src/logic/instruction/operation/macros.rs b/synthesizer/program/src/logic/instruction/operation/macros.rs index e283e0945b..eeed6eef7d 100644 --- a/synthesizer/program/src/logic/instruction/operation/macros.rs +++ b/synthesizer/program/src/logic/instruction/operation/macros.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -95,7 +96,7 @@ macro_rules! operation { use console::types::*; // Prepare the environment. - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; type CurrentAleo = circuit::network::AleoV0; // Prepare the operator. @@ -150,7 +151,7 @@ macro_rules! operation { use console::types::*; // Prepare the environment. - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; type CurrentAleo = circuit::network::AleoV0; // Prepare the operator. @@ -774,7 +775,8 @@ mod tests { } // These indicators are later used in the for-loops below. is_shift_operator |= true; - shift_exceeds_bitwidth |= ((*b as u32) >= $input_a::::size_in_bits() as u32); + let input_a_size_in_bits = u32::try_from($input_a::::size_in_bits()).expect("Input size in bits exceeded u32::MAX"); + shift_exceeds_bitwidth |= ((*b as u32) >= input_a_size_in_bits); }; ("ensure divide by zero halts") => { should_succeed &= (*b) != *$input_b::::zero(); diff --git a/synthesizer/program/src/logic/instruction/operation/mod.rs b/synthesizer/program/src/logic/instruction/operation/mod.rs index 1f00110cc3..a86a0e6ebb 100644 --- a/synthesizer/program/src/logic/instruction/operation/mod.rs +++ b/synthesizer/program/src/logic/instruction/operation/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/logic/instruction/operation/sign_verify.rs b/synthesizer/program/src/logic/instruction/operation/sign_verify.rs index 22a9fb480a..2b9c829b7d 100644 --- a/synthesizer/program/src/logic/instruction/operation/sign_verify.rs +++ b/synthesizer/program/src/logic/instruction/operation/sign_verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,9 +14,9 @@ // limitations under the License. use crate::{ - traits::{RegistersLoad, RegistersLoadCircuit, RegistersStore, RegistersStoreCircuit, StackMatches, StackProgram}, Opcode, Operand, + traits::{RegistersLoad, RegistersLoadCircuit, RegistersStore, RegistersStoreCircuit, StackMatches, StackProgram}, }; use circuit::prelude::ToFields as CircuitToFields; use console::{ @@ -274,9 +275,9 @@ impl ToBytes for SignVerify { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() { diff --git a/synthesizer/program/src/logic/instruction/parse.rs b/synthesizer/program/src/logic/instruction/parse.rs index 7eba572702..f701b20d04 100644 --- a/synthesizer/program/src/logic/instruction/parse.rs +++ b/synthesizer/program/src/logic/instruction/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -85,9 +86,9 @@ impl FromStr for Instruction { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { diff --git a/synthesizer/program/src/logic/mod.rs b/synthesizer/program/src/logic/mod.rs index 26ba868d5e..811fef97a3 100644 --- a/synthesizer/program/src/logic/mod.rs +++ b/synthesizer/program/src/logic/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/mapping/bytes.rs b/synthesizer/program/src/mapping/bytes.rs index 323fdbc64f..e7497c9fcd 100644 --- a/synthesizer/program/src/mapping/bytes.rs +++ b/synthesizer/program/src/mapping/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -45,9 +46,9 @@ impl ToBytes for Mapping { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_mapping_bytes() -> Result<()> { diff --git a/synthesizer/program/src/mapping/key/bytes.rs b/synthesizer/program/src/mapping/key/bytes.rs index 244ca10357..0f3c4324ab 100644 --- a/synthesizer/program/src/mapping/key/bytes.rs +++ b/synthesizer/program/src/mapping/key/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/mapping/key/mod.rs b/synthesizer/program/src/mapping/key/mod.rs index 3132c8a251..7a89e69e48 100644 --- a/synthesizer/program/src/mapping/key/mod.rs +++ b/synthesizer/program/src/mapping/key/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -43,9 +44,9 @@ impl TypeName for MapKey { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_key_type_name() -> Result<()> { diff --git a/synthesizer/program/src/mapping/key/parse.rs b/synthesizer/program/src/mapping/key/parse.rs index 607a8f6c70..af2b57d5c2 100644 --- a/synthesizer/program/src/mapping/key/parse.rs +++ b/synthesizer/program/src/mapping/key/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -79,9 +80,9 @@ impl Display for MapKey { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_key_parse() -> Result<()> { diff --git a/synthesizer/program/src/mapping/mod.rs b/synthesizer/program/src/mapping/mod.rs index b7b6238626..1dfa0ebda6 100644 --- a/synthesizer/program/src/mapping/mod.rs +++ b/synthesizer/program/src/mapping/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/mapping/parse.rs b/synthesizer/program/src/mapping/parse.rs index e2dd389f8f..090ca5a074 100644 --- a/synthesizer/program/src/mapping/parse.rs +++ b/synthesizer/program/src/mapping/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -78,9 +79,9 @@ impl Display for Mapping { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_mapping_parse() { diff --git a/synthesizer/program/src/mapping/value/bytes.rs b/synthesizer/program/src/mapping/value/bytes.rs index 54355ac7f0..0412fb93ed 100644 --- a/synthesizer/program/src/mapping/value/bytes.rs +++ b/synthesizer/program/src/mapping/value/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/mapping/value/mod.rs b/synthesizer/program/src/mapping/value/mod.rs index c32207fdf6..15a3057747 100644 --- a/synthesizer/program/src/mapping/value/mod.rs +++ b/synthesizer/program/src/mapping/value/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -43,9 +44,9 @@ impl TypeName for MapValue { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_value_type_name() { diff --git a/synthesizer/program/src/mapping/value/parse.rs b/synthesizer/program/src/mapping/value/parse.rs index 280bf71788..dd945ee973 100644 --- a/synthesizer/program/src/mapping/value/parse.rs +++ b/synthesizer/program/src/mapping/value/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -79,9 +80,9 @@ impl Display for MapValue { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_value_parse() -> Result<()> { diff --git a/synthesizer/program/src/parse.rs b/synthesizer/program/src/parse.rs index 22d6cfa5bb..179c506321 100644 --- a/synthesizer/program/src/parse.rs +++ b/synthesizer/program/src/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -44,58 +45,70 @@ impl, Command: CommandTrait> Par // Parse the semicolon ';' keyword from the string. let (string, _) = tag(";")(string)?; + fn intermediate, Command: CommandTrait>( + string: &str, + ) -> ParserResult> { + // Parse the whitespace and comments from the string. + let (string, _) = Sanitizer::parse(string)?; + + if string.starts_with(Mapping::::type_name()) { + map(Mapping::parse, |mapping| P::::M(mapping))(string) + } else if string.starts_with(StructType::::type_name()) { + map(StructType::parse, |struct_| P::::I(struct_))(string) + } else if string.starts_with(RecordType::::type_name()) { + map(RecordType::parse, |record| P::::R(record))(string) + } else if string.starts_with(ClosureCore::::type_name()) { + map(ClosureCore::parse, |closure| P::::C(closure))(string) + } else if string.starts_with(FunctionCore::::type_name()) { + map(FunctionCore::parse, |function| P::::F(function))(string) + } else { + Err(Err::Error(make_error(string, ErrorKind::Alt))) + } + } + // Parse the struct or function from the string. - let (string, components) = many1(alt(( - map(Mapping::parse, |mapping| P::::M(mapping)), - map(StructType::parse, |struct_| P::::I(struct_)), - map(RecordType::parse, |record| P::::R(record)), - map(ClosureCore::parse, |closure| P::::C(closure)), - map(FunctionCore::parse, |function| P::::F(function)), - )))(string)?; + let (string, components) = many1(intermediate)(string)?; // Parse the whitespace and comments from the string. let (string, _) = Sanitizer::parse(string)?; - // Return the program. - map_res(take(0usize), move |_| { - // Initialize a new program. - let mut program = match ProgramCore::::new(id) { - Ok(program) => program, + // Initialize a new program. + let mut program = match ProgramCore::::new(id) { + Ok(program) => program, + Err(error) => { + eprintln!("{error}"); + return map_res(take(0usize), Err)(string); + } + }; + // Construct the program with the parsed components. + for component in components { + let result = match component { + P::M(mapping) => program.add_mapping(mapping), + P::I(struct_) => program.add_struct(struct_), + P::R(record) => program.add_record(record), + P::C(closure) => program.add_closure(closure), + P::F(function) => program.add_function(function), + }; + + match result { + Ok(_) => (), Err(error) => { eprintln!("{error}"); - return Err(error); - } - }; - // Construct the program with the parsed components. - for component in components.iter() { - let result = match component { - P::M(mapping) => program.add_mapping(mapping.clone()), - P::I(struct_) => program.add_struct(struct_.clone()), - P::R(record) => program.add_record(record.clone()), - P::C(closure) => program.add_closure(closure.clone()), - P::F(function) => program.add_function(function.clone()), - }; - - match result { - Ok(_) => (), - Err(error) => { - eprintln!("{error}"); - return Err(error); - } + return map_res(take(0usize), Err)(string); } } - // Lastly, add the imports (if any) to the program. - for import in imports.iter() { - match program.add_import(import.clone()) { - Ok(_) => (), - Err(error) => { - eprintln!("{error}"); - return Err(error); - } + } + // Lastly, add the imports (if any) to the program. + for import in imports { + match program.add_import(import) { + Ok(_) => (), + Err(error) => { + eprintln!("{error}"); + return map_res(take(0usize), Err)(string); } } - // Output the program. - Ok::<_, Error>(program) - })(string) + } + + Ok((string, program)) } } @@ -106,6 +119,9 @@ impl, Command: CommandTrait> Fro /// Returns a program from a string literal. fn from_str(string: &str) -> Result { + // Ensure the raw program string is less than MAX_PROGRAM_SIZE. + ensure!(string.len() <= N::MAX_PROGRAM_SIZE, "Program length exceeds N::MAX_PROGRAM_SIZE."); + match Self::parse(string) { Ok((remainder, object)) => { // Ensure the remainder is empty. @@ -127,56 +143,55 @@ impl, Command: CommandTrait> Deb } } -#[allow(clippy::format_push_string)] impl, Command: CommandTrait> Display for ProgramCore { /// Prints the program as a string. fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - // Initialize a string for the program. - let mut program = String::new(); - if !self.imports.is_empty() { // Print the imports. for import in self.imports.values() { - program.push_str(&format!("{import}\n")); + writeln!(f, "{import}")?; } // Print a newline. - program.push('\n'); + writeln!(f)?; } // Print the program name. - program += &format!("{} {};\n\n", Self::type_name(), self.id); + write!(f, "{} {};\n\n", Self::type_name(), self.id)?; - for (identifier, definition) in self.identifiers.iter() { + let mut identifier_iter = self.identifiers.iter().peekable(); + while let Some((identifier, definition)) = identifier_iter.next() { match definition { ProgramDefinition::Mapping => match self.mappings.get(identifier) { - Some(mapping) => program.push_str(&format!("{mapping}\n\n")), + Some(mapping) => writeln!(f, "{mapping}")?, None => return Err(fmt::Error), }, ProgramDefinition::Struct => match self.structs.get(identifier) { - Some(struct_) => program.push_str(&format!("{struct_}\n\n")), + Some(struct_) => writeln!(f, "{struct_}")?, None => return Err(fmt::Error), }, ProgramDefinition::Record => match self.records.get(identifier) { - Some(record) => program.push_str(&format!("{record}\n\n")), + Some(record) => writeln!(f, "{record}")?, None => return Err(fmt::Error), }, ProgramDefinition::Closure => match self.closures.get(identifier) { - Some(closure) => program.push_str(&format!("{closure}\n\n")), + Some(closure) => writeln!(f, "{closure}")?, None => return Err(fmt::Error), }, ProgramDefinition::Function => match self.functions.get(identifier) { - Some(function) => program.push_str(&format!("{function}\n\n")), + Some(function) => writeln!(f, "{function}")?, None => return Err(fmt::Error), }, } + // Omit the last newline. + if identifier_iter.peek().is_some() { + writeln!(f)?; + } } - // Remove the last newline. - program.pop(); - write!(f, "{program}") + Ok(()) } } @@ -184,9 +199,9 @@ impl, Command: CommandTrait> Dis mod tests { use super::*; use crate::Program; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_program_parse() -> Result<()> { @@ -255,4 +270,127 @@ function compute: Ok(()) } + + #[test] + fn test_program_size() { + // Define variable name for easy experimentation with program sizes. + let var_name = "a"; + + // Helper function to generate imports. + let gen_import_string = |n: usize| -> String { + let mut s = String::new(); + for i in 0..n { + s.push_str(&format!("import foo{i}.aleo;\n")); + } + s + }; + + // Helper function to generate large structs. + let gen_struct_string = |n: usize| -> String { + let mut s = String::with_capacity(CurrentNetwork::MAX_PROGRAM_SIZE); + for i in 0..n { + s.push_str(&format!("struct m{}:\n", i)); + for j in 0..10 { + s.push_str(&format!(" {}{} as u128;\n", var_name, j)); + } + } + s + }; + + // Helper function to generate large records. + let gen_record_string = |n: usize| -> String { + let mut s = String::with_capacity(CurrentNetwork::MAX_PROGRAM_SIZE); + for i in 0..n { + s.push_str(&format!("record r{}:\n owner as address.private;\n", i)); + for j in 0..10 { + s.push_str(&format!(" {}{} as u128.private;\n", var_name, j)); + } + } + s + }; + + // Helper function to generate large mappings. + let gen_mapping_string = |n: usize| -> String { + let mut s = String::with_capacity(CurrentNetwork::MAX_PROGRAM_SIZE); + for i in 0..n { + s.push_str(&format!( + "mapping {}{}:\n key as field.public;\n value as field.public;\n", + var_name, i + )); + } + s + }; + + // Helper function to generate large closures. + let gen_closure_string = |n: usize| -> String { + let mut s = String::with_capacity(CurrentNetwork::MAX_PROGRAM_SIZE); + for i in 0..n { + s.push_str(&format!("closure c{}:\n input r0 as u128;\n", i)); + for j in 0..10 { + s.push_str(&format!(" add r0 r0 into r{};\n", j)); + } + s.push_str(&format!(" output r{} as u128;\n", 4000)); + } + s + }; + + // Helper function to generate large functions. + let gen_function_string = |n: usize| -> String { + let mut s = String::with_capacity(CurrentNetwork::MAX_PROGRAM_SIZE); + for i in 0..n { + s.push_str(&format!("function f{}:\n add 1u128 1u128 into r0;\n", i)); + for j in 0..10 { + s.push_str(&format!(" add r0 r0 into r{j};\n")); + } + } + s + }; + + // Helper function to generate and parse a program. + let test_parse = |imports: &str, body: &str, should_succeed: bool| { + let program = format!("{imports}\nprogram to_parse.aleo;\n\n{body}"); + let result = Program::::from_str(&program); + if result.is_ok() != should_succeed { + println!("Program failed to parse: {program}"); + } + assert_eq!(result.is_ok(), should_succeed); + }; + + // A program with MAX_IMPORTS should succeed. + test_parse(&gen_import_string(CurrentNetwork::MAX_IMPORTS), &gen_struct_string(1), true); + // A program with more than MAX_IMPORTS should fail. + test_parse(&gen_import_string(CurrentNetwork::MAX_IMPORTS + 1), &gen_struct_string(1), false); + // A program with MAX_STRUCTS should succeed. + test_parse("", &gen_struct_string(CurrentNetwork::MAX_STRUCTS), true); + // A program with more than MAX_STRUCTS should fail. + test_parse("", &gen_struct_string(CurrentNetwork::MAX_STRUCTS + 1), false); + // A program with MAX_RECORDS should succeed. + test_parse("", &gen_record_string(CurrentNetwork::MAX_RECORDS), true); + // A program with more than MAX_RECORDS should fail. + test_parse("", &gen_record_string(CurrentNetwork::MAX_RECORDS + 1), false); + // A program with MAX_MAPPINGS should succeed. + test_parse("", &gen_mapping_string(CurrentNetwork::MAX_MAPPINGS), true); + // A program with more than MAX_MAPPINGS should fail. + test_parse("", &gen_mapping_string(CurrentNetwork::MAX_MAPPINGS + 1), false); + // A program with MAX_CLOSURES should succeed. + test_parse("", &gen_closure_string(CurrentNetwork::MAX_CLOSURES), true); + // A program with more than MAX_CLOSURES should fail. + test_parse("", &gen_closure_string(CurrentNetwork::MAX_CLOSURES + 1), false); + // A program with MAX_FUNCTIONS should succeed. + test_parse("", &gen_function_string(CurrentNetwork::MAX_FUNCTIONS), true); + // A program with more than MAX_FUNCTIONS should fail. + test_parse("", &gen_function_string(CurrentNetwork::MAX_FUNCTIONS + 1), false); + + // Initialize a program which is too big. + let program_too_big = format!( + "{} {} {} {} {}", + gen_struct_string(CurrentNetwork::MAX_STRUCTS), + gen_record_string(CurrentNetwork::MAX_RECORDS), + gen_mapping_string(CurrentNetwork::MAX_MAPPINGS), + gen_closure_string(CurrentNetwork::MAX_CLOSURES), + gen_function_string(CurrentNetwork::MAX_FUNCTIONS) + ); + // A program which is too big should fail. + test_parse("", &program_too_big, false); + } } diff --git a/synthesizer/program/src/resources/credits.aleo b/synthesizer/program/src/resources/credits.aleo index 534bb4ce86..4e1b606f43 100644 --- a/synthesizer/program/src/resources/credits.aleo +++ b/synthesizer/program/src/resources/credits.aleo @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,6 +13,39 @@ // See the License for the specific language governing permissions and // limitations under the License. +/********************************************** INVARIANTS ************************************************************/ + +// 1. contains committee[r0] => +// a. contains delegated[r0] +// - The set of delegated addresses is superset of active validators. +// 2. delegated[*] >= 10,000 +// a. contain bonded[*].microcredits >= 10,000 +// - Delegators can bond to any address with the 10,000 credit minimum +// 3. delegated[r0] < 10,000,000 => +// a. !contain committee[r0] +// - If the delegated total (which includes the self bond) is less than 10,000,000 credits, it won't be in the committee +// 4. bond[r0].validator == r0 => +// a. contains committee[r0] +// - Self bonded addresses are always active validators. Delegators **can** force validators to unbond by removing sufficient delegation +// 5. committee[r0] => +// a. bonded[r0].microcredits >= 100 credits +// - Self bonded addresses are always active validators with at least 100 credits self bonded +// b. delegated[r0] >= 10,000,000 credits +// - The total delegated amount for an active validator is at least 10,000,000 credits +// 6. delegated[r0] == sum bond[*].microcredits by bond[].validator == r0 +// 7. bond[r0].microcredits < 10,000 => +// a. bond[r0].validator == r0 +// b. contains committee[r0] +// - A bond value < 10,000 implies self-bonded active validator. +// 8. bond[r0].validator != r0 => +// a. bond[r0].microcredits >= 10,000 +// 9. count bonded[] - count committee[] == metadata[aleo1qgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqanmpl0] +// - Delegator count consistent with metadata. +// 10. count committee[] == metadata[aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc] +// 11. 100,000 + count committee[] >= count bonded[] >= count delegated[] >= count committee[] +// 12. bond[*].microcredits > 100 + + /**********************************************************************************************************************/ program credits.aleo; @@ -25,12 +59,35 @@ mapping committee: // The value represents the committee state of the validator. value as committee_state.public; -// The `committee_state` struct tracks the total stake of the validator, and whether they are open to stakers. +// The `committee_state` struct tracks the total stake of the validator, and whether they are open to new stakers. struct committee_state: - // The amount of microcredits bonded to the validator, by the validator and its delegators. - microcredits as u64; - // The boolean flag indicating if the validator is open to stakers. + // The boolean flag indicating if the validator is open to new stakers. is_open as boolean; + // The percentage amount (from 0 to 100, inclusive) of rewards that retained by the validator. + commission as u8; + +/**********************************************************************************************************************/ + +// The `delegated` mapping tracks the total amount of microcredits that are prebonded and bonded to validator addresses. +// Note: The mapping includes both prebonded and bonded microcredits. However, it does not contain unbonding microcredits. +mapping delegated: + // The key represents the address of the validator. + key as address.public; + // The value represents the amount of microcredits bonded to the validator, by the validator and its delegators. + value as u64.public; + +/**********************************************************************************************************************/ + +/// The `metadata` mapping stores: +/// - The number of members in the committee. +/// - The number of delegators. +mapping metadata: + // The key represents the index at which the count is stored. + // - This address (aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc) stores the number of **members** in the committee. + // - This address (aleo1qgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqanmpl0) stores the number of **delegators**. + key as address.public; + // The value represents the count. + value as u32.public; /**********************************************************************************************************************/ @@ -75,6 +132,15 @@ mapping account: /**********************************************************************************************************************/ +// The `withdraw` mapping contains the staking address and their corresponding withdrawal address. +mapping withdraw: + // The key represents the staking address of the owner. + key as address.public; + // The value represents the withdrawal address of the owner. + value as address.public; + +/**********************************************************************************************************************/ + // The `credits` record is used to store credits privately. record credits: // The address of the owner. @@ -84,494 +150,588 @@ record credits: /**********************************************************************************************************************/ -// This function allows any staker to bond their microcredits to a validator. -// The corresponding functions for 'bond_public' are 'unbond_public' and 'claim_unbond_public'. -function bond_public: - // Input the validator's address. +// This function allows a validator to bond their microcredits to themselves and specify a withdrawal address +// and commission percentage. +// +// The commission percentage is the portion of rewards that the validator may claim for itself. +// Note: Setting the commission percentage to 100 results in all rewards being retained for the validator. +// +// The corresponding functions for 'bond_validator' are 'unbond_public' and 'claim_unbond_public'. +function bond_validator: + // Input the withdrawal address. input r0 as address.public; // Input the amount of microcredits to bond. input r1 as u64.public; + // Input the commission percentage. + input r2 as u8.public; - // Determine if the amount is at least one credit. - gte r1 1_000_000u64 into r2; - // Enforce the amount is at least one credit. - assert.eq r2 true; + // Ensure the withdrawal address is not the validator address. + assert.neq self.signer r0; + + // Determine if the amount is at least 1 credit. + gte r1 1_000_000u64 into r3; + // Enforce the amount is at least 1 credit. + assert.eq r3 true; + + // Ensure the commission percentage does not exceed 100%. + gt r2 100u8 into r4; + assert.neq r4 true; // Bond the specified amount of microcredits to the specified validator. - async bond_public self.caller r0 r1 into r3; + async bond_validator self.signer r0 r1 r2 into r5; // Output the finalize future. - output r3 as credits.aleo/bond_public.future; + output r5 as credits.aleo/bond_validator.future; -finalize bond_public: - // Input the staker's address. - input r0 as address.public; +finalize bond_validator: // Input the validator's address. + input r0 as address.public; + // Input the withdrawal address. input r1 as address.public; // Input the amount of microcredits to bond. input r2 as u64.public; + // Input the commission percentage. + input r3 as u8.public; - // Determine whether the caller is a validator. - is.eq r0 r1 into r3; - // If the caller is a validator, jump to the `bond_validator` logic. - branch.eq r3 true to bond_validator; - // If the caller is not a validator, jump to the `bond_delegator` logic. - branch.eq r3 false to bond_delegator; - - /******* Bond Validator *******/ - - // Starts the `bond_validator` logic. - position bond_validator; - - /* Committee */ + // Retrieve the withdrawal address for the validator. + get.or_use withdraw[r0] r1 into r4; + // Ensure that the withdrawal address is consistent. + assert.eq r1 r4; // Construct the initial committee state. // Note: We set the initial 'is_open' state to 'true'. - cast 0u64 true into r4 as committee_state; + cast true r3 into r5 as committee_state; // Retrieve the committee state of the specified validator. - get.or_use committee[r0] r4 into r5; - // Ensure that the validator is open to stakers. - assert.eq r5.is_open true; + get.or_use committee[r0] r5 into r6; - // Increment the stake for the specified validator. - add r5.microcredits r2 into r6; - // Construct the updated committee state. - cast r6 r5.is_open into r7 as committee_state; + // Ensure the commission percentage remains unchanged. + // Note: The commission percentage can only be set when the validator bonds for the first time. + assert.eq r3 r6.commission; /* Bonded */ // Construct the initial bond state. - cast r1 0u64 into r8 as bond_state; - // Get the bond state for the caller, or default to the initial bond state. - get.or_use bonded[r0] r8 into r9; + cast r0 0u64 into r7 as bond_state; + // Get the bond state for the signer, or default to the initial bond state. + get.or_use bonded[r0] r7 into r8; // Enforce the validator matches in the bond state. - assert.eq r9.validator r1; - - // Increment the microcredits in the bond state. - add r9.microcredits r2 into r10; - // Determine if the amount is at least one million credits. - gte r10 1_000_000_000_000u64 into r11; - // Enforce the amount is at least one million credits. - assert.eq r11 true; + assert.eq r8.validator r0; + // Increment the amount of microcredits for the bond state. + add r8.microcredits r2 into r9; // Construct the updated bond state. - cast r1 r10 into r12 as bond_state; + cast r0 r9 into r10 as bond_state; + + /* Delegated */ + + // Include total pre-delegated amount when deciding if validator has enough credits to join committee. + // First get the current delegated amount, or start with 0 if none delegated. + get.or_use delegated[r0] 0u64 into r11; + // Self-bond amount + existing delegated amount = total bond. + add r2 r11 into r12; + // Determine if the amount is at least 10 million credits. + gte r12 10_000_000_000_000u64 into r13; + // Enforce the amount is at least 10 million credits. + assert.eq r13 true; /* Account */ - // Get the balance of the caller. + // Get the balance of the signer. // If the account does not exist, this finalize scope will fail. - get account[r0] into r13; - // Decrement the balance of the caller. - sub r13 r2 into r14; + get account[r0] into r14; + // Decrement the balance of the signer. + sub r14 r2 into r15; /* Writes */ - // Update the committee state of the specified validator. - set r7 into committee[r0]; - // Update the bond state for the caller. - set r12 into bonded[r0]; - // Update the balance of the caller. - set r14 into account[r0]; + // if (new_validator) + contains committee[r0] into r16; + branch.eq r16 true to validator_in_committee; + // { + // Set the withdrawal address. + // Note: This operation is only necessary on the first time for a validator entry, in order to initialize the value. + set r4 into withdraw[r0]; + + // Check if the initial bond amount is at least 100 credits. + gte r2 100_000_000u64 into r17; + // Ensure that the initial bond is at least 100 credits. + assert.eq r17 true; + + // Get the committee size. + get.or_use metadata[aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc] 0u32 into r18; + // Increment the committee size by one. + add r18 1u32 into r19; + // Set the new committee size. + set r19 into metadata[aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc]; + + // Check if the validator exists in the unbonding state. + contains unbonding[r0] into r20; + // Ensure the validator currently is not unbonding. + assert.eq r20 false; + // } + + position validator_in_committee; - // Ends the `bond_validator` logic. - branch.eq true true to end; + // Update the committee state of the specified validator. + set r6 into committee[r0]; + // Update the delegated amount. + set r12 into delegated[r0]; + // Update the bond state for the signer. + set r10 into bonded[r0]; + // Update the balance of the signer. + set r15 into account[r0]; - /******* Bond Delegator *******/ +/**********************************************************************************************************************/ - // Starts the `bond_delegator` logic. - position bond_delegator; +// This function allows any delegator to bond their microcredits to a validator and specify a withdrawal address. +// +// The declared validator is **not** required to be in the committee yet, however it may **not** be unbonding. +// This function enforces a minimum of 10,000 credits for each delegator. +// The maximum number of delegators allowed in the committee is 100,000 delegator addresses. +// +// The corresponding functions for 'bond_public' are 'bond_validator', 'unbond_public', and 'claim_unbond_public'. +function bond_public: + // Input the validator's address. + input r0 as address.public; + // Input the withdrawal address. + input r1 as address.public; + // Input the amount of microcredits to bond. + input r2 as u64.public; - /* Committee */ + // Determine if the amount is at least one credit. + gte r2 1_000_000u64 into r3; + // Enforce the amount is at least one credit. + assert.eq r3 true; - // Check if the caller is a validator. - contains committee[r0] into r15; - // Enforce the caller is *not* a validator. - assert.eq r15 false; + // Do not allow self-bonding. Validators start with bond_validator. + assert.neq self.caller r0; - // Get the stake for the specified validator. - // If the validator does not exist, this finalize scope will fail. - get committee[r1] into r16; - // Ensure that the validator is open to stakers. - assert.eq r16.is_open true; + // Bond the specified amount of microcredits to the specified validator. + async bond_public self.caller r0 r1 r2 into r4; + // Output the finalize future. + output r4 as credits.aleo/bond_public.future; - // Increment the stake for the specified validator. - add r16.microcredits r2 into r17; - // Construct the updated committee state. - cast r17 r16.is_open into r18 as committee_state; +finalize bond_public: + // Input the staker's address. + input r0 as address.public; + // Input the validator's address. + input r1 as address.public; + // Input the withdrawal address. + input r2 as address.public; + // Input the amount of microcredits to bond. + input r3 as u64.public; + + // Retrieve the withdrawal address for the staker. + get.or_use withdraw[r0] r2 into r4; + // Ensure that the withdrawal address is consistent. + assert.eq r2 r4; + + // Check if the delegator is already bonded to the validator. + contains bonded[r0] into r5; + branch.eq r5 true to continue_bond_delegator; + // { + // Set the withdrawal address. + // Note: This operation is only necessary on the first time for a staker entry, in order to initialize the value. + set r2 into withdraw[r0]; + + // Ensure that the validator is open to new stakers. By default, `is_open` is set to `true`. + cast true 0u8 into r6 as committee_state; + get.or_use committee[r1] r6 into r7; + assert.eq r7.is_open true; + + // Get the number of delegators. + get.or_use metadata[aleo1qgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqanmpl0] 0u32 into r8; + // Increment the number of bonded delegators by one. + add r8 1u32 into r9; + // Determine if the number of delegators is less than or equal to 100_000. + lte r9 100_000u32 into r10; + // Enforce that the number of delegators is less than or equal to 100_000. + assert.eq r10 true; + // Set the new number of delegators. + set r9 into metadata[aleo1qgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqanmpl0]; + // } + + position continue_bond_delegator; /* Bonded */ // Construct the initial bond state. - cast r1 0u64 into r19 as bond_state; + cast r1 0u64 into r11 as bond_state; // Get the bond state for the caller, or default to the initial bond state. - get.or_use bonded[r0] r19 into r20; + get.or_use bonded[r0] r11 into r12; // Enforce the validator matches in the bond state. - assert.eq r20.validator r1; + assert.eq r12.validator r1; // Increment the microcredits in the bond state. - add r20.microcredits r2 into r21; - // Determine if the amount is at least 10 credits. - gte r21 10_000_000u64 into r22; - // Enforce the amount is at least 10 credits. - assert.eq r22 true; + add r12.microcredits r3 into r13; + + // Determine if the amount is at least 10 thousand credits. + gte r13 10_000_000_000u64 into r14; + // Enforce the amount is at least 10 thousand credits. + assert.eq r14 true; // Construct the updated bond state. - cast r1 r21 into r23 as bond_state; + cast r1 r13 into r15 as bond_state; /* Account */ // Get the balance of the caller. // If the account does not exist, this finalize scope will fail. - get account[r0] into r24; + get account[r0] into r16; // Decrement the balance of the caller. - sub r24 r2 into r25; + sub r16 r3 into r17; + + /* Delegated */ + + // Get current total delegated amount. + get.or_use delegated[r1] 0u64 into r18; + // Add new bond amount to current delegation. + add r3 r18 into r19; + + /* Unbonding */ + + // Check if the validator exists in the unbonding state. + contains unbonding[r1] into r20; + // Ensure the validator currently is not unbonding. + assert.eq r20 false; /* Writes */ - // Update the committee state for the specified validator. - set r18 into committee[r1]; // Update the bond state for the caller. - set r23 into bonded[r0]; + set r15 into bonded[r0]; // Update the balance of the caller. - set r25 into account[r0]; - - // The terminus. - position end; + set r17 into account[r0]; + // Update delegated amount. + set r19 into delegated[r1]; /**********************************************************************************************************************/ -// This function allows any staker to unbond their microcredits from a validator. -// The corresponding functions for 'unbond_public' is 'claim_unbond_public'. +// This function allows any staker to unbond their microcredits from a validator, +// callable only by using the withdrawal address of the staker or the validator. +// +// **Validators**: It will remove the validator if the self bonded balance falls below 100 credits +// or the total delegated balance falls below 10M credits. +// **Delegators**: It will remove the validator if the total delegated balance falls below 10M credits. +// It will remove the entire bond_state of the delegator if it falls below 10,000 credits. +// +// Validators are permitted to fully unbond any of their delegators. When a validator unbonds a delegator, +// the entire bonded balance is unbonded, regardless of the amount of microcredits and may end up removing the validator +// from the committee if the total delegated balance falls below 10M credits. +// +// The corresponding function for 'unbond_public' is 'claim_unbond_public'. function unbond_public: + // Input the staker's address. + input r0 as address.public; // Input the amount of microcredits to unbond. - input r0 as u64.public; + input r1 as u64.public; - // Unbond the specified amount of microcredits to the caller. - async unbond_public self.caller r0 into r1; + // Unbond the specified amount of microcredits for the specified validator. + async unbond_public self.caller r0 r1 into r2; // Output the finalize future. - output r1 as credits.aleo/unbond_public.future; + output r2 as credits.aleo/unbond_public.future; finalize unbond_public: - // Input the staker's address. + // Input the caller's address. input r0 as address.public; + // Input the staker's address. + input r1 as address.public; // Input the amount of microcredits to unbond. - input r1 as u64.public; - - // Construct the initial unbond state. - cast 0u64 0u32 into r2 as unbond_state; - // Get the unbond state for the caller, or default to the initial unbond state. - get.or_use unbonding[r0] r2 into r3; - - // Compute the height at which the unbonding will be complete, starting from the current block. - // Note: Calling unbond across multiple blocks before the unbonding is complete will reset the height each time. - add block.height 360u32 into r4; - - // Determine if the caller is a validator or delegator. - contains committee[r0] into r5; - - // If the caller is a validator, jump to the `unbond_validator` logic. - branch.eq r5 true to unbond_validator; - // If the caller is not a validator, jump to the `unbond_delegator` logic. - branch.eq r5 false to unbond_delegator; - - /******* Unbond Validator *******/ + input r2 as u64.public; - // Starts the `unbond_validator` logic. + // Set the default unbonding state. + add block.height 360u32 into r3; + // Construct the default unbonding state. + cast 0u64 r3 into r4 as unbond_state; + + // Retrieve the staker's bond state. + // Note: If the bonded state does not exist, reject the transition. + get bonded[r1] into r5; + + /* Check Caller's Permission */ + + // Get the staker's withdrawal address. + get withdraw[r1] into r6; + // Check if the caller's address equals the staker's withdrawal address. + is.eq r0 r6 into r7; + + // Check if the validator's withdrawal address has been set. + // Note: This contains check must use `withdraw` and **not** `committee` to ensure the validator + // can unbond delegators even when the validator is not in the committee. Of course, if the validator is + // in the committee, then the validator must be able to unbond its delegators. + contains withdraw[r5.validator] into r8; + // Get the validator's withdrawal address from the bond state, using the zero address as the default. + get.or_use withdraw[r5.validator] aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc into r9; + // Check if the validator's withdrawal address matches the caller. + is.eq r0 r9 into r10; + // AND the withdraw address has been set (to prevent an edge case where a validator uses the zero address as a withdrawal address). + and r8 r10 into r11; + + // Either the caller is the staker's withdrawal address OR the validator's withdrawal address is set to the caller. + or r7 r11 into r12; + // Enforce the permission as `true`. + assert.eq r12 true; + + // Check if bonded to self (validator) or to a different address (delegator). + is.eq r5.validator r1 into r13; + branch.eq r13 true to unbond_validator; + + /* Unbond the Delegator */ + // { + // Retrieve or initialize the unbonding state. + get.or_use unbonding[r1] r4 into r14; + // Retrieve the delegated amount in microcredits for the validator. + get delegated[r5.validator] into r15; + + // Calculate new bonded microcredits. + // Note: If the subtraction underflows, reject the transition. + sub r5.microcredits r2 into r16; + + // Check if the delegator will fall below 10,000 bonded credits. + lt r16 10_000_000_000u64 into r17; + + // If the validator is forcing the delegator to unbond OR the delegator will fall below 10,000 bonded credits. + or r11 r17 into r18; + + // Determine the amount to unbond: requested amount if >= 10,000 credits, otherwise the full bonded amount. + ternary r18 r5.microcredits r2 into r19; + + /* Unbonding */ + + // Increment existing unbond amount by the new unbond amount. + // Note: If the addition overflows, reject the transition. + add r14.microcredits r19 into r20; + // Construct the updated unbond state. + cast r20 r3 into r21 as unbond_state; + // Store the new unbonding state. + set r21 into unbonding[r1]; + + /* Delegated */ + + // Calculate the new delegated total for the validator. + // Note: If the subtraction underflows, reject the transition. + sub r15 r19 into r22; + // Store the new delegated total. + set r22 into delegated[r5.validator]; + + // Check if the new bonded state is falling below 10,000 credits, or if the validator is forcing an unbond on the delegator. + branch.eq r18 true to remove_delegator; + + /* Decrement the Delegator */ + // { + /* Bonded */ + + // Construct the new bond state. + cast r5.validator r16 into r23 as bond_state; + // Set the new bond state. + set r23 into bonded[r1]; + + // Jump to the end of the unbond delegator process. + branch.eq true true to end_unbond_delegator; + // } + + position remove_delegator; + // { + /* Bonded */ + + // Remove the bonded state. + remove bonded[r1]; + + /* Metadata */ + + // Retrieve the current number of delegators. + get metadata[aleo1qgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqanmpl0] into r24; + // Decrement the number of delegators by one. + sub r24 1u32 into r25; + // Store the new number of delegators. + set r25 into metadata[aleo1qgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqanmpl0]; + // } Intentionally fall through to end_unbond_delegator + + position end_unbond_delegator; + // { + // Check if the new delegated total is at least 10M credits. + gte r22 10_000_000_000_000u64 into r26; + // Jump to end if the delegated total is at least 10M credits. + branch.eq r26 true to end; + // } + // If the delegated total is below 10M credits, continue to unbonding the validator. + //} + + /* Unbond the Validator */ position unbond_validator; - - /* Committee */ - - // Get the committee state for the specified validator. - get committee[r0] into r6; - // Decrement the stake for the specified validator. - sub r6.microcredits r1 into r7; - - /* Bonded */ - - // Get the bond state for the validator, or fail if it does not exist. - get bonded[r0] into r8; - // Ensure that the validator matches in the bond state. - assert.eq r8.validator r0; - // Decrement the microcredits in the bond state. - sub r8.microcredits r1 into r9; - - // Determine if the remaining bond is at least one million credits. - gte r9 1_000_000_000_000u64 into r10; - - // If the remaining balance is at least 1 million credits, jump to the `decrement_validator` logic. - branch.eq r10 true to decrement_validator; - // If the remaining balance is less than 1 million credits, jump to the `remove_validator` logic. - branch.eq r10 false to remove_validator; - - /*** Decrement Validator ***/ - - // Starts the `decrement_validator` logic. - position decrement_validator; - - /* Committee */ - - // Construct the updated committee state. - cast r7 r6.is_open into r11 as committee_state; - // Update the committee state for the validator. - set r11 into committee[r0]; - - /* Bonded */ - - // Construct the updated bond state. - cast r0 r9 into r12 as bond_state; - // Update the bond state for the validator. - set r12 into bonded[r0]; - - /* Unbonding */ - - // Increment the microcredits in the unbond state. - add r3.microcredits r1 into r13; - - // Construct the updated unbond state. - cast r13 r4 into r14 as unbond_state; - // Update the unbond state for the caller. - set r14 into unbonding[r0]; - - // Ends the `decrement_validator` logic. - branch.eq true true to end; - - /*** Remove Validator ***/ - - // Starts the `remove_validator` logic. + // { + // Check if the committee contains the validator. + contains committee[r5.validator] into r27; + // Determine if the delegator unbonding from a validator is not in the committee. + nor r13 r27 into r28; + // Jump to the end, if the delegator unbonding from a validator is not in the committee. + branch.eq r28 true to end; + + // Retrieve the committee state. + // Note: If the committee state does not exist, reject the transition. + get committee[r5.validator] into r29; + // Retrieve the bond state of the validator. + // Note: If the bonded state does not exist, reject the transition. + get bonded[r5.validator] into r30; + // Retrieve the total delegated balance for the validator. + // Note: If the delegated state does not exist, reject the transition. + get delegated[r5.validator] into r31; + + // Check if the current delegated amount is below 10M credits. + // Note: This will only be `true` if a delegator unbond caused the validator to fall below 10M credits. + lt r31 10_000_000_000_000u64 into r32; + branch.eq r32 true to remove_validator; + + // Calculate the updated delegated total after unbonding. + // Note: If the subtraction underflows, reject the transition. + sub r31 r2 into r33; + + // Calculate the updated amount of microcredits after unbonding. + sub r30.microcredits r2 into r34; + + // Check if the new bond state is below the required minimums. + gte r34 100_000_000u64 into r35; // Minimum self bond requirement: 100 credits. + gte r33 10_000_000_000_000u64 into r36; // Minimum total delegated requirement: 10M credits. + + // If either bond state is below the thresholds, remove the validator from the committee. + and r35 r36 into r37; + branch.eq r37 false to remove_validator; + + /* Unbonding */ + + // Retrieve or initialize the unbonding state. + get.or_use unbonding[r5.validator] r4 into r38; + // Increment the unbond amount. + // Note: If the addition overflows, reject the transition. + add r38.microcredits r2 into r39; + // Set the updated unbond state. + cast r39 r3 into r40 as unbond_state; + // Store the new unbonding state. + set r40 into unbonding[r5.validator]; + + /* Delegated */ + + // Store the new delegated total. + set r33 into delegated[r5.validator]; + + /* Bonded */ + + // Construct and store the new bond state. + cast r5.validator r34 into r41 as bond_state; + set r41 into bonded[r5.validator]; + + // Jump to end. + branch.eq true true to end; + //} + + /* Remove the Validator from the Committee */ position remove_validator; + // { + /* Committee */ - // Ensure that the validator has no delegators. - assert.eq r6.microcredits r8.microcredits; - - /* Committee */ - - // Remove the validator from the committee. - remove committee[r0]; - - /* Bonded */ - - // Remove the bond state for the validator. - remove bonded[r0]; - - /* Unbonding */ - - // Increment the microcredits in the unbond state. - add r3.microcredits r8.microcredits into r15; - - // Construct the updated unbond state. - cast r15 r4 into r16 as unbond_state; - // Update the unbond state for the caller. - set r16 into unbonding[r0]; - - // Ends the `remove_validator` logic. - branch.eq true true to end; - - /******* Unbond Delegator *******/ - - // Starts the `unbond_delegator` logic. - position unbond_delegator; - - // Get the bond state for the caller, or fail if it does not exist. - get bonded[r0] into r17; - // Decrement the microcredits in the bond state. - sub r17.microcredits r1 into r18; - - // Determine if the remaining bond is at least 10 credits. - gte r18 10_000_000u64 into r19; - - // If the remaining balance is at least 10 credits, jump to the `decrement_delegator` logic. - branch.eq r19 true to decrement_delegator; - // If the remaining balance is less than 10 credits, jump to the `remove_delegator` logic. - branch.eq r19 false to remove_delegator; - - /*** Decrement Delegator ***/ - - // Starts the `decrement_delegator` logic. - position decrement_delegator; - - /* Committee */ - - // Get the stake for the specified validator. - // If the validator does not exist, this finalize scope will fail. - get committee[r17.validator] into r20; - // Decrement the stake for the specified validator. - sub r20.microcredits r1 into r21; - // Construct the updated committee state. - cast r21 r20.is_open into r22 as committee_state; - // Update the stake for the specified validator. - set r22 into committee[r17.validator]; - - /* Bonded */ - - // Construct the updated bond state. - cast r17.validator r18 into r23 as bond_state; - // Update the bond state for the caller. - set r23 into bonded[r0]; - - /* Unbonding */ - - // Increment the microcredits in the unbond state. - add r3.microcredits r1 into r24; - - // Construct the updated unbond state. - cast r24 r4 into r25 as unbond_state; - // Update the unbond state for the caller. - set r25 into unbonding[r0]; - - // Ends the `decrement_delegator` logic. - branch.eq true true to end; - - /*** Remove Delegator ***/ + // Remove the validator from the committee. + remove committee[r5.validator]; - // Starts the `remove_delegator` logic. - position remove_delegator; + /* Metadata */ - /* Committee */ + // Retrieve the current committee size. + get metadata[aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc] into r42; + // Decrement the committee size by one. + sub r42 1u32 into r43; + // Store the new committee size. + set r43 into metadata[aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc]; - // Get the stake for the specified validator. - // If the validator does not exist, this finalize scope will fail. - get committee[r17.validator] into r26; - // Decrement the stake for the specified validator. - sub r26.microcredits r17.microcredits into r27; - // Construct the updated committee state. - cast r27 r26.is_open into r28 as committee_state; - // Update the stake for the specified validator. - set r28 into committee[r17.validator]; + /* Delegated */ - /* Bonded */ + // Decrease the delegated total by the bonded amount. + sub r31 r30.microcredits into r44; + // Store the new delegated total. + set r44 into delegated[r5.validator]; - // Remove the caller from the bonded mapping. - remove bonded[r0]; + /* Bonded */ - /* Unbonding */ + // Remove the bonded state. + remove bonded[r5.validator]; - // Increment the microcredits in the unbond state. - add r3.microcredits r17.microcredits into r29; + /* Unbonding */ - // Construct the updated unbond state. - cast r29 r4 into r30 as unbond_state; - // Update the unbond state for the caller. - set r30 into unbonding[r0]; + // Retrieve or initialize the unbonding state. + get.or_use unbonding[r5.validator] r4 into r45; + // Increment the unbond amount by the full bonded amount. + // Note: If the addition overflows, reject the transition. + add r30.microcredits r45.microcredits into r46; + // Construct the updated unbond state. + cast r46 r3 into r47 as unbond_state; + // Store the new unbonding state. + set r47 into unbonding[r5.validator]; + //} - // The terminus. position end; /**********************************************************************************************************************/ -// This function allows a validator to unbond any delegator that is bonded to them. -function unbond_delegator_as_validator: - // Input the delegator's address. - input r0 as address.public; - - // Unbond the delegator as the validator. - async unbond_delegator_as_validator self.caller r0 into r1; - // Output the finalize future. - output r1 as credits.aleo/unbond_delegator_as_validator.future; - -finalize unbond_delegator_as_validator: - // Input the validator's address. +// The `claim_unbond_public` function allows any staker to claim their microcredits +// to their withdrawal address after the unbonding period. +// +// Note: Please be advised that this function is callable by any user for any staker. +// +// This function also removes the staker's withdrawal address if the staker no longer has any bonded balance. +function claim_unbond_public: + // Input the staker's address. input r0 as address.public; - // Input the delegator's address. - input r1 as address.public; - - /* Start Committee */ - - // Get the committee state for the specified validator. - // If the validator does not exist, this finalize scope will fail. - get committee[r0] into r2; - // Enforce that the validator is closed to stakers. - assert.eq r2.is_open false; - - // Check if the delegator is a validator. - contains committee[r1] into r3; - // Enforce the delegator is *not* a validator. - assert.eq r3 false; - - /* End Committee */ - - /* Start Bonded */ - - // Get the bond state for the delegator, or fail if it does not exist. - get bonded[r1] into r4; - // Enforce that the delegator is bonded to the validator. - assert.eq r4.validator r0; - - /* End Bonded */ - - /* Start Committee */ - // Decrement the stake for the specified validator. - sub r2.microcredits r4.microcredits into r5; - // Construct the updated committee state. - cast r5 r2.is_open into r6 as committee_state; - - /* End Committee */ - - /* Start Unbond */ - - // Construct the initial unbond state. - cast 0u64 0u32 into r7 as unbond_state; - // Get the unbond state for the delegator, or default to the initial unbond state. - get.or_use unbonding[r1] r7 into r8; - - // Increment the microcredits in the unbond state. - add r8.microcredits r4.microcredits into r9; - // Compute the height at which the unbonding will be complete, starting from the current block. - // Note: Calling unbond across multiple blocks before the unbonding is complete will reset the height each time. - add block.height 360u32 into r10; - - // Construct the updated unbond state. - cast r9 r10 into r11 as unbond_state; - - /* End Unbond */ - - /* Start Writes */ - - // Update the committee state for the specified validator. - set r6 into committee[r0]; - // Remove the bond state for the delegator. - remove bonded[r1]; - // Update the unbond state for the delegator. - set r11 into unbonding[r1]; - - /* End Writes */ - -/**********************************************************************************************************************/ - -// This function allows any staker to claim their microcredits after the unbonding period. -function claim_unbond_public: // Claim the unbonded microcredits. - async claim_unbond_public self.caller into r0; + async claim_unbond_public r0 into r1; // Output the finalize future. - output r0 as credits.aleo/claim_unbond_public.future; + output r1 as credits.aleo/claim_unbond_public.future; finalize claim_unbond_public: // Input the staker's address. input r0 as address.public; - // Get the unbond state for the caller, or fail if it does not exist. + // Get the unbond state for the address, or fail if it does not exist. get unbonding[r0] into r1; // Determine if unbonding is complete. gte block.height r1.height into r2; // Enforce the unbonding is complete. assert.eq r2 true; - // Add the unbonded amount to the stakers's public balance. - // Increments `account[r0]` by `r1`. - // If `account[r0]` does not exist, 0u64 is used. - // If `account[r0] + r2` overflows, `claim_unbond_public` is reverted. - get.or_use account[r0] 0u64 into r3; - add r1.microcredits r3 into r4; - set r4 into account[r0]; + /* Withdraw */ + + // Get the withdrawal address for the address. + get withdraw[r0] into r3; + + /* Account */ + + // Add the unbonded amount to the withdrawal address public balance. + // Increments `account[r3]` by `r1.microcredits`. + // If `account[r3]` does not exist, 0u64 is used. + // If `account[r3] + r1.microcredits` overflows, `claim_unbond_public` is reverted. + get.or_use account[r3] 0u64 into r4; + add r1.microcredits r4 into r5; + set r5 into account[r3]; - // Remove the unbond state for the caller. + /* Unbonding */ + + // Remove the unbond state for the staker. remove unbonding[r0]; + // Check if the staker is still bonded. + contains bonded[r0] into r6; + // Ends the `claim_unbond_public` logic. + branch.eq r6 true to end; + + /* Withdraw */ + + // If the caller is no longer bonded, remove the withdrawal address. + remove withdraw[r0]; + + // The terminus. + position end; + /**********************************************************************************************************************/ -// This function allows a validator to set their state to be either opened or closed to stakers. -// When the validator is open to stakers, any staker (including the validator) can bond or unbond from the validator. -// When the validator is closed to stakers, all stakers can only unbond from the validator. +// This function allows a validator to set their state to be either opened or closed to new stakers. +// When the validator is open to new stakers, any staker (including the validator) can bond or unbond from the validator. +// When the validator is closed to new stakers, existing stakers can still bond or unbond from the validator, but new stakers cannot bond. // // This function serves two primary purposes: // 1. Allow a validator to leave the committee, by closing themselves to stakers and then unbonding all of their stakers. @@ -579,7 +739,7 @@ finalize claim_unbond_public: function set_validator_state: // Input the 'is_open' state. input r0 as boolean.public; - // Set the validator to be either open or closed to stakers. + // Set the validator to be either open or closed to new stakers. async set_validator_state self.caller r0 into r1; // Output the finalize future. output r1 as credits.aleo/set_validator_state.future; @@ -595,14 +755,14 @@ finalize set_validator_state: get committee[r0] into r2; // Construct the updated committee state. - cast r2.microcredits r1 into r3 as committee_state; + cast r1 r2.commission into r3 as committee_state; // Update the committee state for the specified validator. set r3 into committee[r0]; /**********************************************************************************************************************/ // The `transfer_public` function sends the specified amount -// from the sender's `account` to the receiver's `account`. +// from the caller's `account` to the receiver's `account`. function transfer_public: // Input the receiver. input r0 as address.public; @@ -614,7 +774,7 @@ function transfer_public: output r2 as credits.aleo/transfer_public.future; finalize transfer_public: - // Input the sender. + // Input the caller. input r0 as address.public; // Input the receiver. input r1 as address.public; @@ -634,6 +794,39 @@ finalize transfer_public: /**********************************************************************************************************************/ +// The `transfer_public_as_signer` function sends the specified amount +// from the signer's `account` to the receiver's `account`. +function transfer_public_as_signer: + // Input the receiver. + input r0 as address.public; + // Input the amount. + input r1 as u64.public; + // Transfer the credits publicly. + async transfer_public_as_signer self.signer r0 r1 into r2; + // Output the finalize future. + output r2 as credits.aleo/transfer_public_as_signer.future; + +finalize transfer_public_as_signer: + // Input the signer. + input r0 as address.public; + // Input the receiver. + input r1 as address.public; + // Input the amount. + input r2 as u64.public; + // Decrements `account[r0]` by `r2`. + // If `account[r0] - r2` underflows, `transfer_public_as_signer` is reverted. + get account[r0] into r3; + sub r3 r2 into r4; + set r4 into account[r0]; + // Increments `account[r1]` by `r2`. + // If `account[r1]` does not exist, 0u64 is used. + // If `account[r1] + r2` overflows, `transfer_public_as_signer` is reverted. + get.or_use account[r1] 0u64 into r5; + add r5 r2 into r6; + set r6 into account[r1]; + +/**********************************************************************************************************************/ + // The `transfer_private` function sends the specified amount // from the sender's record to the receiver in a record. function transfer_private: @@ -824,7 +1017,7 @@ function fee_public: // Add the fee and priority fee amounts. add r0 r1 into r3; // Decrement the balance of the sender publicly. - async fee_public self.caller r3 into r4; + async fee_public self.signer r3 into r4; // Output the finalize future. output r4 as credits.aleo/fee_public.future; @@ -843,9 +1036,3 @@ finalize fee_public: set r3 into account[r0]; /**********************************************************************************************************************/ - -// Open Questions: -// fn bond -// - if the bond is now 33% or more, close the validator. (determine how hard to impl this) - -/**********************************************************************************************************************/ diff --git a/synthesizer/program/src/serialize.rs b/synthesizer/program/src/serialize.rs index 4e23a291a4..bfd64d05e0 100644 --- a/synthesizer/program/src/serialize.rs +++ b/synthesizer/program/src/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -42,9 +43,9 @@ impl<'de, N: Network, Instruction: InstructionTrait, Command: CommandTrait mod tests { use super::*; use crate::Program; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_serde_json() -> Result<()> { diff --git a/synthesizer/program/src/traits/command.rs b/synthesizer/program/src/traits/command.rs index 8a50676db4..65469ba2a7 100644 --- a/synthesizer/program/src/traits/command.rs +++ b/synthesizer/program/src/traits/command.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/traits/finalize_store.rs b/synthesizer/program/src/traits/finalize_store.rs index e7496df456..17f2a4eb97 100644 --- a/synthesizer/program/src/traits/finalize_store.rs +++ b/synthesizer/program/src/traits/finalize_store.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/traits/instruction.rs b/synthesizer/program/src/traits/instruction.rs index e65e96694c..d600ee201c 100644 --- a/synthesizer/program/src/traits/instruction.rs +++ b/synthesizer/program/src/traits/instruction.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/traits/mod.rs b/synthesizer/program/src/traits/mod.rs index 2e112e8535..122ad6b5f0 100644 --- a/synthesizer/program/src/traits/mod.rs +++ b/synthesizer/program/src/traits/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/src/traits/stack_and_registers.rs b/synthesizer/program/src/traits/stack_and_registers.rs index 1decf4c9d7..459a064b39 100644 --- a/synthesizer/program/src/traits/stack_and_registers.rs +++ b/synthesizer/program/src/traits/stack_and_registers.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,7 +19,7 @@ use crate::{FinalizeGlobalState, Function, Operand, Program}; use console::{ account::Group, network::Network, - prelude::{bail, Result}, + prelude::{Result, bail}, program::{ Future, Identifier, @@ -65,6 +66,9 @@ pub trait StackProgram { /// Returns the program ID. fn program_id(&self) -> &ProgramID; + /// Returns the program depth. + fn program_depth(&self) -> usize; + /// Returns `true` if the stack contains the external record. fn contains_external_record(&self, locator: &Locator) -> bool; @@ -77,6 +81,9 @@ pub trait StackProgram { /// Returns `true` if the stack contains the external record. fn get_external_record(&self, locator: &Locator) -> Result<&RecordType>; + /// Returns the expected finalize cost for the given function name. + fn get_finalize_cost(&self, function_name: &Identifier) -> Result; + /// Returns the function with the given function name. fn get_function(&self, function_name: &Identifier) -> Result>; @@ -122,6 +129,12 @@ pub trait RegistersSigner { /// Sets the transition signer. fn set_signer(&mut self, signer: Address); + /// Returns the root transition view key. + fn root_tvk(&self) -> Result>; + + /// Sets the root transition view key. + fn set_root_tvk(&mut self, root_tvk: Field); + /// Returns the transition caller. fn caller(&self) -> Result>; @@ -142,6 +155,12 @@ pub trait RegistersSignerCircuit> { /// Sets the transition signer, as a circuit. fn set_signer_circuit(&mut self, signer_circuit: circuit::Address); + /// Returns the root transition view key, as a circuit. + fn root_tvk_circuit(&self) -> Result>; + + /// Sets the root transition view key, as a circuit. + fn set_root_tvk_circuit(&mut self, root_tvk_circuit: circuit::Field); + /// Returns the transition caller, as a circuit. fn caller_circuit(&self) -> Result>; diff --git a/synthesizer/program/tests/helpers/macros.rs b/synthesizer/program/tests/helpers/macros.rs index 48f6333fc3..7656195b4a 100644 --- a/synthesizer/program/tests/helpers/macros.rs +++ b/synthesizer/program/tests/helpers/macros.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/tests/helpers/mod.rs b/synthesizer/program/tests/helpers/mod.rs index 13354d9c07..6afa4164cc 100644 --- a/synthesizer/program/tests/helpers/mod.rs +++ b/synthesizer/program/tests/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/tests/helpers/sample.rs b/synthesizer/program/tests/helpers/sample.rs index c7587d03ea..4f6395125b 100644 --- a/synthesizer/program/tests/helpers/sample.rs +++ b/synthesizer/program/tests/helpers/sample.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,17 +15,17 @@ use circuit::AleoV0; use console::{ - network::Testnet3, + network::MainnetV0, prelude::*, program::{Identifier, Literal, Plaintext, Register, Value}, }; use snarkvm_synthesizer_program::{ - traits::{RegistersStore, RegistersStoreCircuit}, FinalizeGlobalState, + traits::{RegistersStore, RegistersStoreCircuit}, }; use synthesizer_process::{Authorization, CallStack, FinalizeRegisters, Registers, Stack, StackProgramTypes}; -type CurrentNetwork = Testnet3; +type CurrentNetwork = MainnetV0; type CurrentAleo = AleoV0; /// Samples the registers. Note: Do not replicate this for real program use, it is insecure. diff --git a/synthesizer/program/tests/instruction/assert.rs b/synthesizer/program/tests/instruction/assert.rs index bd3216a7c7..6c06918b23 100644 --- a/synthesizer/program/tests/instruction/assert.rs +++ b/synthesizer/program/tests/instruction/assert.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,17 +19,17 @@ use crate::helpers::sample::{sample_finalize_registers, sample_registers}; use circuit::AleoV0; use console::{ - network::Testnet3, + network::MainnetV0, prelude::*, program::{Identifier, Literal, LiteralType, Register}, }; use snarkvm_synthesizer_program::{AssertEq, AssertInstruction, AssertNeq, Opcode, Operand, Program}; use synthesizer_process::{Process, Stack}; -type CurrentNetwork = Testnet3; +type CurrentNetwork = MainnetV0; type CurrentAleo = AleoV0; -const ITERATIONS: usize = 100; +const ITERATIONS: usize = 25; /// Samples the stack. Note: Do not replicate this for real program use, it is insecure. fn sample_stack( diff --git a/synthesizer/program/tests/instruction/commit.rs b/synthesizer/program/tests/instruction/commit.rs index 22bd82fdae..c22f362f11 100644 --- a/synthesizer/program/tests/instruction/commit.rs +++ b/synthesizer/program/tests/instruction/commit.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,18 +19,18 @@ use crate::helpers::sample::{sample_finalize_registers, sample_registers}; use circuit::{AleoV0, Eject}; use console::{ - network::Testnet3, + network::MainnetV0, prelude::*, program::{Identifier, Literal, LiteralType, Plaintext, Register, Value}, }; use snarkvm_synthesizer_program::{ - CommitBHP1024, CommitBHP256, CommitBHP512, CommitBHP768, + CommitBHP1024, CommitInstruction, - CommitPED128, CommitPED64, + CommitPED128, Opcode, Operand, Program, @@ -38,10 +39,10 @@ use snarkvm_synthesizer_program::{ }; use synthesizer_process::{Process, Stack}; -type CurrentNetwork = Testnet3; +type CurrentNetwork = MainnetV0; type CurrentAleo = AleoV0; -const ITERATIONS: usize = 50; +const ITERATIONS: usize = 25; /// **Attention**: When changing this, also update in `src/logic/instruction/commit.rs`. fn valid_destination_types() -> &'static [LiteralType] { diff --git a/synthesizer/program/tests/instruction/hash.rs b/synthesizer/program/tests/instruction/hash.rs index bef9a9d312..106474e978 100644 --- a/synthesizer/program/tests/instruction/hash.rs +++ b/synthesizer/program/tests/instruction/hash.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,21 +19,21 @@ use crate::helpers::sample::{sample_finalize_registers, sample_registers}; use circuit::{AleoV0, Eject}; use console::{ - network::Testnet3, + network::MainnetV0, prelude::*, program::{Identifier, Literal, LiteralType, Plaintext, PlaintextType, Register, Value}, }; use snarkvm_synthesizer_program::{ - HashBHP1024, HashBHP256, HashBHP512, HashBHP768, + HashBHP1024, HashInstruction, HashKeccak256, HashKeccak384, HashKeccak512, - HashPED128, HashPED64, + HashPED128, HashPSD2, HashPSD4, HashPSD8, @@ -47,10 +48,10 @@ use snarkvm_synthesizer_program::{ }; use synthesizer_process::{Process, Stack}; -type CurrentNetwork = Testnet3; +type CurrentNetwork = MainnetV0; type CurrentAleo = AleoV0; -const ITERATIONS: usize = 50; +const ITERATIONS: usize = 25; /// **Attention**: When changing this, also update in `src/logic/instruction/hash.rs`. fn valid_destination_types() -> &'static [PlaintextType] { diff --git a/synthesizer/program/tests/instruction/is.rs b/synthesizer/program/tests/instruction/is.rs index ba22a6e01c..1d58f84cdd 100644 --- a/synthesizer/program/tests/instruction/is.rs +++ b/synthesizer/program/tests/instruction/is.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,7 +19,7 @@ use crate::helpers::sample::{sample_finalize_registers, sample_registers}; use circuit::AleoV0; use console::{ - network::Testnet3, + network::MainnetV0, prelude::*, program::{Identifier, Literal, LiteralType, Register}, }; @@ -34,10 +35,10 @@ use snarkvm_synthesizer_program::{ }; use synthesizer_process::{Process, Stack}; -type CurrentNetwork = Testnet3; +type CurrentNetwork = MainnetV0; type CurrentAleo = AleoV0; -const ITERATIONS: usize = 100; +const ITERATIONS: usize = 25; /// Samples the stack. Note: Do not replicate this for real program use, it is insecure. #[allow(clippy::type_complexity)] diff --git a/synthesizer/program/tests/instruction/mod.rs b/synthesizer/program/tests/instruction/mod.rs index 715fdb7c64..777ba1fffc 100644 --- a/synthesizer/program/tests/instruction/mod.rs +++ b/synthesizer/program/tests/instruction/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/program/tests/lib.rs b/synthesizer/program/tests/lib.rs index dc13bcd7b4..646af98135 100644 --- a/synthesizer/program/tests/lib.rs +++ b/synthesizer/program/tests/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/snark/Cargo.toml b/synthesizer/snark/Cargo.toml index 1d63ac19fb..5f704bac36 100644 --- a/synthesizer/snark/Cargo.toml +++ b/synthesizer/snark/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-synthesizer-snark" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "SNARK wrappers for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -33,18 +33,18 @@ wasm = [ "console/wasm", "snarkvm-algorithms/wasm" ] [dependencies.circuit] package = "snarkvm-circuit" path = "../../circuit" -version = "=0.16.19" +version = "=1.1.0" [dependencies.console] package = "snarkvm-console" path = "../../console" -version = "=0.16.19" +version = "=1.1.0" default-features = false features = [ "network" ] [dependencies.snarkvm-algorithms] path = "../../algorithms" -version = "=0.16.19" +version = "=1.1.0" [dependencies.bincode] version = "1" diff --git a/synthesizer/snark/src/certificate/bytes.rs b/synthesizer/snark/src/certificate/bytes.rs index df0ebfecef..fb5270d5b2 100644 --- a/synthesizer/snark/src/certificate/bytes.rs +++ b/synthesizer/snark/src/certificate/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/snark/src/certificate/mod.rs b/synthesizer/snark/src/certificate/mod.rs index 0e16febfd9..adbc4ca00c 100644 --- a/synthesizer/snark/src/certificate/mod.rs +++ b/synthesizer/snark/src/certificate/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -67,6 +68,7 @@ impl Certificate { let fiat_shamir = N::varuna_fs_parameters(); // Verify the certificate. + #[allow(clippy::manual_unwrap_or_default)] match Varuna::::verify_vk(universal_verifier, fiat_shamir, assignment, verifying_key, self) { Ok(is_valid) => { #[cfg(feature = "aleo-cli")] diff --git a/synthesizer/snark/src/certificate/parse.rs b/synthesizer/snark/src/certificate/parse.rs index 40aa1414d2..0bb7ee9f95 100644 --- a/synthesizer/snark/src/certificate/parse.rs +++ b/synthesizer/snark/src/certificate/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -74,9 +75,9 @@ impl Display for Certificate { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { diff --git a/synthesizer/snark/src/certificate/serialize.rs b/synthesizer/snark/src/certificate/serialize.rs index 3b74b8e7ca..893cba2427 100644 --- a/synthesizer/snark/src/certificate/serialize.rs +++ b/synthesizer/snark/src/certificate/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/snark/src/lib.rs b/synthesizer/snark/src/lib.rs index c5063edf4f..4abcb2b580 100644 --- a/synthesizer/snark/src/lib.rs +++ b/synthesizer/snark/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -17,7 +18,7 @@ #![warn(clippy::cast_possible_truncation)] #![cfg_attr(not(feature = "aleo-cli"), allow(unused_variables))] -use console::network::{prelude::*, FiatShamir}; +use console::network::{FiatShamir, prelude::*}; use snarkvm_algorithms::{snark::varuna, traits::SNARK}; use once_cell::sync::OnceCell; @@ -50,11 +51,11 @@ pub(crate) mod test_helpers { environment::{Assignment, Circuit, Eject, Environment, Inject, Mode, One}, types::Field, }; - use console::{network::Testnet3, prelude::One as _}; + use console::{network::MainnetV0, prelude::One as _}; use once_cell::sync::OnceCell; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; /// Compute 2^EXPONENT - 1, in a purposefully constraint-inefficient manner for testing. fn create_example_circuit() -> Field { @@ -138,9 +139,9 @@ pub(crate) mod test_helpers { mod test { use super::*; use circuit::environment::{Circuit, Environment}; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_varuna() { @@ -160,4 +161,53 @@ mod test { println!("\nShould not verify (i.e. verifier messages should print below):"); assert!(!verifying_key.verify("test", &[one, one + one], &proof)); } + + #[test] + fn test_varuna_verify_public_input_size() { + /// Creates a simple circuit: a * b. + fn create_assignment() -> circuit::Assignment<::Field> { + use circuit::{Inject, environment::Mode, types::Field}; + + // Ensure the circuit environment is clean. + Circuit::reset(); + + // Inject a field element. + let console_field = console::types::Field::::one(); + let circuit_field_0 = Field::::new(Mode::Private, console_field); + + // Inject another field element. + let console_field = console_field.double(); + let circuit_field_1 = Field::::new(Mode::Private, console_field); + + // Multiply the two field elements. + let _circuit_field_2 = circuit_field_0 * circuit_field_1; + + // Eject the assignment. + Circuit::eject_assignment_and_reset() + } + + let assignment = create_assignment(); + assert_eq!(assignment.num_public(), 1); + assert_eq!(assignment.num_private(), 3); + + let srs = UniversalSRS::::load().unwrap(); + let (proving_key, verifying_key) = srs.to_circuit_key("test", &assignment).unwrap(); + println!("Called circuit setup"); + + let proof = proving_key.prove("test", &assignment, &mut TestRng::default()).unwrap(); + println!("Called prover"); + + // Should pass. + let one = ::BaseField::one(); + assert!(verifying_key.verify("test", &[one], &proof)); + + // Should fail. + assert!(!verifying_key.verify("test", &[one, one], &proof)); + assert!(!verifying_key.verify("test", &[one, one + one], &proof)); + assert!(!verifying_key.verify("test", &[one, one, one], &proof)); + assert!(!verifying_key.verify("test", &[one, one, one + one], &proof)); + assert!(!verifying_key.verify("test", &[one, one, one, one], &proof)); + + println!("Called verifier"); + } } diff --git a/synthesizer/snark/src/proof/bytes.rs b/synthesizer/snark/src/proof/bytes.rs index e343178603..447253a317 100644 --- a/synthesizer/snark/src/proof/bytes.rs +++ b/synthesizer/snark/src/proof/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/snark/src/proof/mod.rs b/synthesizer/snark/src/proof/mod.rs index 745e087c07..a31302e07d 100644 --- a/synthesizer/snark/src/proof/mod.rs +++ b/synthesizer/snark/src/proof/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/snark/src/proof/parse.rs b/synthesizer/snark/src/proof/parse.rs index 9ce603dfc0..ab234a66f8 100644 --- a/synthesizer/snark/src/proof/parse.rs +++ b/synthesizer/snark/src/proof/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -72,9 +73,9 @@ impl Display for Proof { #[cfg(test)] mod tests { use super::*; - use console::network::Testnet3; + use console::network::MainnetV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_parse() -> Result<()> { diff --git a/synthesizer/snark/src/proof/serialize.rs b/synthesizer/snark/src/proof/serialize.rs index 2accff2e6e..bce458518d 100644 --- a/synthesizer/snark/src/proof/serialize.rs +++ b/synthesizer/snark/src/proof/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/snark/src/proving_key/bytes.rs b/synthesizer/snark/src/proving_key/bytes.rs index c47536b6ba..85221ed5fc 100644 --- a/synthesizer/snark/src/proving_key/bytes.rs +++ b/synthesizer/snark/src/proving_key/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/snark/src/proving_key/mod.rs b/synthesizer/snark/src/proving_key/mod.rs index 07b3cd9d8e..6113878c16 100644 --- a/synthesizer/snark/src/proving_key/mod.rs +++ b/synthesizer/snark/src/proving_key/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -65,10 +66,12 @@ impl ProvingKey { let timer = std::time::Instant::now(); // Prepare the instances. + let num_expected_instances = assignments.len(); let instances: BTreeMap<_, _> = assignments .iter() .map(|(proving_key, assignments)| (proving_key.deref(), assignments.as_slice())) .collect(); + ensure!(instances.len() == num_expected_instances, "Incorrect number of proving keys for batch proof"); // Retrieve the proving parameters. let universal_prover = N::varuna_universal_prover(); diff --git a/synthesizer/snark/src/proving_key/parse.rs b/synthesizer/snark/src/proving_key/parse.rs index 3d47a1e5ed..f48a363696 100644 --- a/synthesizer/snark/src/proving_key/parse.rs +++ b/synthesizer/snark/src/proving_key/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/snark/src/proving_key/serialize.rs b/synthesizer/snark/src/proving_key/serialize.rs index 2a7ac7250e..5af18f0741 100644 --- a/synthesizer/snark/src/proving_key/serialize.rs +++ b/synthesizer/snark/src/proving_key/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/snark/src/universal_srs.rs b/synthesizer/snark/src/universal_srs.rs index 0748242411..b9993a2dde 100644 --- a/synthesizer/snark/src/universal_srs.rs +++ b/synthesizer/snark/src/universal_srs.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -40,7 +41,10 @@ impl UniversalSRS { #[cfg(feature = "aleo-cli")] println!("{}", format!(" • Built '{function_name}' (in {} ms)", timer.elapsed().as_millis()).dimmed()); - Ok((ProvingKey::new(Arc::new(proving_key)), VerifyingKey::new(Arc::new(verifying_key)))) + Ok(( + ProvingKey::new(Arc::new(proving_key)), + VerifyingKey::new(Arc::new(verifying_key), assignment.num_variables()), + )) } } diff --git a/synthesizer/snark/src/verifying_key/bytes.rs b/synthesizer/snark/src/verifying_key/bytes.rs index efe5df38b4..19db5d0f2a 100644 --- a/synthesizer/snark/src/verifying_key/bytes.rs +++ b/synthesizer/snark/src/verifying_key/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -25,8 +26,10 @@ impl FromBytes for VerifyingKey { } // Read the verifying key. let verifying_key = Arc::new(FromBytes::read_le(&mut reader)?); + // Read the number of variables. + let num_variables = u64::read_le(&mut reader)?; // Return the verifying key. - Ok(Self { verifying_key }) + Ok(Self { verifying_key, num_variables }) } } @@ -35,7 +38,9 @@ impl ToBytes for VerifyingKey { fn write_le(&self, mut writer: W) -> IoResult<()> { // Write the version. 1u8.write_le(&mut writer)?; - // Write the bytes. - self.verifying_key.write_le(&mut writer) + // Write the verifying key. + self.verifying_key.write_le(&mut writer)?; + // Write the number of variables. + self.num_variables.write_le(&mut writer) } } diff --git a/synthesizer/snark/src/verifying_key/mod.rs b/synthesizer/snark/src/verifying_key/mod.rs index 700d791080..293c532083 100644 --- a/synthesizer/snark/src/verifying_key/mod.rs +++ b/synthesizer/snark/src/verifying_key/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -24,12 +25,19 @@ use std::collections::BTreeMap; pub struct VerifyingKey { /// The verifying key for the function. verifying_key: Arc>, + /// The number of constant, public, and private variables for the circuit. + num_variables: u64, } impl VerifyingKey { /// Initializes a new verifying key. - pub const fn new(verifying_key: Arc>) -> Self { - Self { verifying_key } + pub const fn new(verifying_key: Arc>, num_variables: u64) -> Self { + Self { verifying_key, num_variables } + } + + /// Returns the number of constant, public, and private variables for the circuit. + pub fn num_variables(&self) -> u64 { + self.num_variables } /// Returns `true` if the proof is valid for the given public inputs. @@ -42,6 +50,7 @@ impl VerifyingKey { let fiat_shamir = N::varuna_fs_parameters(); // Verify the proof. + #[allow(clippy::manual_unwrap_or_default)] match Varuna::::verify(universal_verifier, fiat_shamir, self, inputs, proof) { Ok(is_valid) => { #[cfg(feature = "aleo-cli")] @@ -61,13 +70,19 @@ impl VerifyingKey { /// Returns `true` if the batch proof is valid for the given public inputs. #[allow(clippy::type_complexity)] - pub fn verify_batch(locator: &str, inputs: Vec<(VerifyingKey, Vec>)>, proof: &Proof) -> bool { + pub fn verify_batch( + locator: &str, + inputs: Vec<(VerifyingKey, Vec>)>, + proof: &Proof, + ) -> Result<()> { #[cfg(feature = "aleo-cli")] let timer = std::time::Instant::now(); // Convert the instances. + let num_expected_keys = inputs.len(); let keys_to_inputs: BTreeMap<_, _> = inputs.iter().map(|(verifying_key, inputs)| (verifying_key.deref(), inputs.as_slice())).collect(); + ensure!(keys_to_inputs.len() == num_expected_keys, "Incorrect number of verifying keys for batch proof"); // Retrieve the verification parameters. let universal_verifier = N::varuna_universal_verifier(); @@ -77,13 +92,16 @@ impl VerifyingKey { match Varuna::::verify_batch(universal_verifier, fiat_shamir, &keys_to_inputs, proof) { Ok(is_valid) => { #[cfg(feature = "aleo-cli")] - println!("{}", format!(" • Verified '{locator}' (in {} ms)", timer.elapsed().as_millis()).dimmed()); - is_valid + println!( + "{}", + format!(" • Verified '{locator}': {is_valid} (in {} ms)", timer.elapsed().as_millis()).dimmed() + ); + if is_valid { Ok(()) } else { bail!("'verify_batch' failed") } } Err(error) => { #[cfg(feature = "aleo-cli")] println!("{}", format!(" • Verifier failed: {error}").dimmed()); - false + bail!(error) } } } diff --git a/synthesizer/snark/src/verifying_key/parse.rs b/synthesizer/snark/src/verifying_key/parse.rs index eff9515eee..374bfed621 100644 --- a/synthesizer/snark/src/verifying_key/parse.rs +++ b/synthesizer/snark/src/verifying_key/parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/snark/src/verifying_key/serialize.rs b/synthesizer/snark/src/verifying_key/serialize.rs index 84c2ddb11c..9903f58704 100644 --- a/synthesizer/snark/src/verifying_key/serialize.rs +++ b/synthesizer/snark/src/verifying_key/serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/src/lib.rs b/synthesizer/src/lib.rs index febf14df98..be4c9595ec 100644 --- a/synthesizer/src/lib.rs +++ b/synthesizer/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -32,6 +33,11 @@ pub use crate::process::{Authorization, CallMetrics, Process, Stack, Trace}; #[cfg(feature = "program")] pub use crate::program::{Closure, Command, Finalize, Function, Instruction, Program}; +#[cfg(all(feature = "process", feature = "program", feature = "snark"))] +mod restrictions; +#[cfg(all(feature = "process", feature = "program", feature = "snark"))] +pub use restrictions::*; + #[cfg(all(feature = "process", feature = "program", feature = "snark"))] pub mod vm; #[cfg(all(feature = "process", feature = "program", feature = "snark"))] diff --git a/synthesizer/src/restrictions/helpers/argument_locator.rs b/synthesizer/src/restrictions/helpers/argument_locator.rs new file mode 100644 index 0000000000..7e7fbcafc9 --- /dev/null +++ b/synthesizer/src/restrictions/helpers/argument_locator.rs @@ -0,0 +1,208 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 console::network::prelude::*; + +/// A locator for a function argument of the form `{is_input}/{index}`. +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub struct ArgumentLocator { + /// The `is_input` flag is `true` if the argument is an input, otherwise it is an output. + is_input: bool, + /// The (zero-based) index of the argument. + index: u16, +} + +impl ArgumentLocator { + /// Initializes a new argument locator. + pub const fn new(is_input: bool, index: u16) -> Self { + Self { is_input, index } + } + + /// Returns the `is_input` flag. + pub const fn is_input(&self) -> bool { + self.is_input + } + + /// Returns the index. + pub const fn index(&self) -> u16 { + self.index + } +} + +impl Parser for ArgumentLocator { + /// Parses a string into an argument locator of the form `{is_input}/{index}`. + #[inline] + fn parse(string: &str) -> ParserResult { + // Parse the `is_input` from the string. + let (string, is_input) = alt((map(tag("true"), |_| true), map(tag("false"), |_| false)))(string)?; + // Parse the `/` from the string. + let (string, _) = tag("/")(string)?; + // Parse the `index` from the string. + let (string, index) = + map_res(recognize(many1(one_of("0123456789"))), |string: &str| string.parse::())(string)?; + + // Return the argument locator. + Ok((string, Self { is_input, index })) + } +} + +impl FromStr for ArgumentLocator { + type Err = Error; + + /// Parses a string into an argument locator. + #[inline] + fn from_str(string: &str) -> Result { + match Self::parse(string) { + Ok((remainder, object)) => { + // Ensure the remainder is empty. + ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\""); + // Return the object. + Ok(object) + } + Err(error) => bail!("Failed to parse string. {error}"), + } + } +} + +impl Debug for ArgumentLocator { + /// Prints the argument locator as a string. + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(self, f) + } +} + +impl Display for ArgumentLocator { + /// Prints the argument locator as a string. + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{is_input}/{index}", is_input = self.is_input, index = self.index) + } +} + +impl FromBytes for ArgumentLocator { + /// Reads the argument locator from a buffer. + fn read_le(mut reader: R) -> IoResult { + let is_input = FromBytes::read_le(&mut reader)?; + let index = FromBytes::read_le(&mut reader)?; + Ok(Self { is_input, index }) + } +} + +impl ToBytes for ArgumentLocator { + /// Writes the argument locator to a buffer. + fn write_le(&self, mut writer: W) -> IoResult<()> { + self.is_input.write_le(&mut writer)?; + self.index.write_le(&mut writer) + } +} + +impl Serialize for ArgumentLocator { + /// Serializes the locator into string or bytes. + fn serialize(&self, serializer: S) -> Result { + match serializer.is_human_readable() { + true => serializer.collect_str(self), + false => ToBytesSerializer::serialize_with_size_encoding(self, serializer), + } + } +} + +impl<'de> Deserialize<'de> for ArgumentLocator { + /// Deserializes the locator from a string or bytes. + fn deserialize>(deserializer: D) -> Result { + match deserializer.is_human_readable() { + true => FromStr::from_str(&String::deserialize(deserializer)?).map_err(de::Error::custom), + false => FromBytesDeserializer::::deserialize_with_size_encoding(deserializer, "argument locator"), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const ITERATIONS: usize = 1000; + + pub(crate) fn sample_argument_locator(rng: &mut R) -> ArgumentLocator { + ArgumentLocator::new(rng.gen(), rng.gen_range(0..16)) + } + + fn check_serde_json< + T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes, + >( + expected: T, + ) { + // Serialize + let expected_string = &expected.to_string(); + let candidate_string = serde_json::to_string(&expected).unwrap(); + assert_eq!(expected_string, serde_json::Value::from_str(&candidate_string).unwrap().as_str().unwrap()); + + // Deserialize + assert_eq!(expected, T::from_str(expected_string).unwrap_or_else(|_| panic!("FromStr: {expected_string}"))); + assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap()); + } + + fn check_bincode< + T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes, + >( + expected: T, + ) { + // Serialize + let expected_bytes = expected.to_bytes_le().unwrap(); + let expected_bytes_with_size_encoding = bincode::serialize(&expected).unwrap(); + assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]); + + // Deserialize + assert_eq!(expected, T::read_le(&expected_bytes[..]).unwrap()); + assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..]).unwrap()); + } + + #[test] + fn test_serde_json() { + let rng = &mut TestRng::default(); + + for _ in 0..ITERATIONS { + let expected = sample_argument_locator(rng); + check_serde_json(expected); + } + } + + #[test] + fn test_bincode() { + let rng = &mut TestRng::default(); + + for _ in 0..ITERATIONS { + let expected = sample_argument_locator(rng); + check_bincode(expected); + } + } + + #[test] + fn test_import_parse() { + let rng = &mut TestRng::default(); + + for _ in 0..ITERATIONS { + let expected = sample_argument_locator(rng); + + // Test the parser. + let argument_locator = ArgumentLocator::parse(&expected.to_string()).unwrap().1; + assert_eq!(expected.is_input(), argument_locator.is_input()); + assert_eq!(expected.index(), argument_locator.index()); + + // Test the from_str. + let argument_locator = ArgumentLocator::from_str(&expected.to_string()).unwrap(); + assert_eq!(expected.is_input(), argument_locator.is_input()); + assert_eq!(expected.index(), argument_locator.index()); + } + } +} diff --git a/synthesizer/src/restrictions/helpers/block_range.rs b/synthesizer/src/restrictions/helpers/block_range.rs new file mode 100644 index 0000000000..9c84bcef6a --- /dev/null +++ b/synthesizer/src/restrictions/helpers/block_range.rs @@ -0,0 +1,319 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 console::{ + network::Network, + prelude::{Deserialize, Deserializer, EnumAccess, One, Result, Serialize, Serializer, VariantAccess, Visitor, de}, + types::Field, +}; + +use core::{ + fmt, + ops::{Range, RangeFrom, RangeInclusive, RangeTo}, +}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum BlockRange { + Range(Range), + RangeFrom(RangeFrom), + RangeTo(RangeTo), + RangeInclusive(RangeInclusive), + FullRange, +} + +impl BlockRange { + /// Returns `true` if the block range contains the specified block height. + pub fn contains(&self, height: u32) -> bool { + match self { + BlockRange::Range(range) => range.contains(&height), + BlockRange::RangeFrom(range) => range.contains(&height), + BlockRange::RangeTo(range) => range.contains(&height), + BlockRange::RangeInclusive(range) => range.contains(&height), + BlockRange::FullRange => true, + } + } +} + +impl BlockRange { + /// Returns a unique field element encoding of the block range. + pub fn to_fields(&self) -> Result>> { + match self { + BlockRange::Range(range) => { + Ok(vec![Field::from_u8(0), Field::from_u32(range.start), Field::from_u32(range.end)]) + } + BlockRange::RangeFrom(range) => Ok(vec![Field::from_u8(1), Field::from_u32(range.start), -Field::one()]), + BlockRange::RangeTo(range) => Ok(vec![Field::from_u8(2), -Field::one(), Field::from_u32(range.end)]), + BlockRange::RangeInclusive(range) => { + Ok(vec![Field::from_u8(3), Field::from_u32(*range.start()), Field::from_u32(*range.end())]) + } + BlockRange::FullRange => Ok(vec![Field::from_u8(4), -Field::one(), -Field::one()]), + } + } +} + +impl Serialize for BlockRange { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + BlockRange::Range(range) => { + serializer.serialize_newtype_variant("BlockRange", 0, "Range", &(range.start, range.end)) + } + BlockRange::RangeFrom(range) => { + serializer.serialize_newtype_variant("BlockRange", 1, "RangeFrom", &range.start) + } + BlockRange::RangeTo(range) => serializer.serialize_newtype_variant("BlockRange", 2, "RangeTo", &range.end), + BlockRange::RangeInclusive(range) => { + serializer.serialize_newtype_variant("BlockRange", 3, "RangeInclusive", &(range.start(), range.end())) + } + BlockRange::FullRange => serializer.serialize_newtype_variant("BlockRange", 4, "FullRange", &()), + } + } +} + +impl<'de> Deserialize<'de> for BlockRange { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + enum Field { + Range, + RangeFrom, + RangeTo, + RangeInclusive, + FullRange, + } + + impl<'de> Deserialize<'de> for Field { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`Range`, `RangeFrom`, `RangeTo`, `RangeInclusive`, or `FullRange`") + } + + fn visit_str(self, value: &str) -> Result + where + E: de::Error, + { + match value { + "Range" => Ok(Field::Range), + "RangeFrom" => Ok(Field::RangeFrom), + "RangeTo" => Ok(Field::RangeTo), + "RangeInclusive" => Ok(Field::RangeInclusive), + "FullRange" => Ok(Field::FullRange), + _ => Err(de::Error::unknown_field(value, FIELDS)), + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + struct BlockRangeVisitor; + + impl<'de> Visitor<'de> for BlockRangeVisitor { + type Value = BlockRange; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("struct BlockRange") + } + + fn visit_enum(self, data: A) -> Result + where + A: EnumAccess<'de>, + { + let (field, variant) = data.variant()?; + match field { + Field::Range => { + let (start, end): (u32, u32) = variant.newtype_variant()?; + Ok(BlockRange::Range(start..end)) + } + Field::RangeFrom => { + let start: u32 = variant.newtype_variant()?; + Ok(BlockRange::RangeFrom(RangeFrom { start })) + } + Field::RangeTo => { + let end: u32 = variant.newtype_variant()?; + Ok(BlockRange::RangeTo(RangeTo { end })) + } + Field::RangeInclusive => { + let (start, end): (u32, u32) = variant.newtype_variant()?; + Ok(BlockRange::RangeInclusive(RangeInclusive::new(start, end))) + } + Field::FullRange => { + variant.unit_variant()?; + Ok(BlockRange::FullRange) + } + } + } + } + + const FIELDS: &[&str] = &["Range", "RangeFrom", "RangeTo", "RangeInclusive", "FullRange"]; + deserializer.deserialize_enum("BlockRange", FIELDS, BlockRangeVisitor) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + type CurrentNetwork = console::network::MainnetV0; + + #[test] + fn test_serialize_range() { + let range = BlockRange::Range(1..10); + let serialized = serde_json::to_string(&range).unwrap(); + assert_eq!(serialized, r#"{"Range":[1,10]}"#); + } + + #[test] + fn test_deserialize_range() { + let serialized = r#"{"Range":[1,10]}"#; + let deserialized: BlockRange = serde_json::from_str(serialized).unwrap(); + assert_eq!(deserialized, BlockRange::Range(1..10)); + } + + #[test] + fn test_serialize_range_from() { + let range = BlockRange::RangeFrom(RangeFrom { start: 5 }); + let serialized = serde_json::to_string(&range).unwrap(); + assert_eq!(serialized, r#"{"RangeFrom":5}"#); + } + + #[test] + fn test_deserialize_range_from() { + let serialized = r#"{"RangeFrom":5}"#; + let deserialized: BlockRange = serde_json::from_str(serialized).unwrap(); + assert_eq!(deserialized, BlockRange::RangeFrom(RangeFrom { start: 5 })); + } + + #[test] + fn test_serialize_range_to() { + let range = BlockRange::RangeTo(RangeTo { end: 8 }); + let serialized = serde_json::to_string(&range).unwrap(); + assert_eq!(serialized, r#"{"RangeTo":8}"#); + } + + #[test] + fn test_deserialize_range_to() { + let serialized = r#"{"RangeTo":8}"#; + let deserialized: BlockRange = serde_json::from_str(serialized).unwrap(); + assert_eq!(deserialized, BlockRange::RangeTo(RangeTo { end: 8 })); + } + + #[test] + fn test_serialize_range_inclusive() { + let range = BlockRange::RangeInclusive(RangeInclusive::new(2, 9)); + let serialized = serde_json::to_string(&range).unwrap(); + assert_eq!(serialized, r#"{"RangeInclusive":[2,9]}"#); + } + + #[test] + fn test_deserialize_range_inclusive() { + let serialized = r#"{"RangeInclusive":[2,9]}"#; + let deserialized: BlockRange = serde_json::from_str(serialized).unwrap(); + assert_eq!(deserialized, BlockRange::RangeInclusive(RangeInclusive::new(2, 9))); + } + + #[test] + fn test_serialize_full_range() { + let range = BlockRange::FullRange; + let serialized = serde_json::to_string(&range).unwrap(); + assert_eq!(serialized, r#"{"FullRange":null}"#); + } + + #[test] + fn test_deserialize_full_range() { + let serialized = r#"{"FullRange":null}"#; + let deserialized: BlockRange = serde_json::from_str(serialized).unwrap(); + assert_eq!(deserialized, BlockRange::FullRange); + } + + #[test] + fn test_deserialize_error() { + let serialized = r#"{"InvalidRange":[1,2]}"#; + let result: Result = serde_json::from_str(serialized); + assert!(result.is_err()); + } + + #[test] + fn test_deserialize_missing_field() { + let serialized = r#"{}"#; + let result: Result = serde_json::from_str(serialized); + assert!(result.is_err()); + } + + #[test] + fn test_contains() { + let range = BlockRange::Range(1..10); + assert!(range.contains(1)); + assert!(range.contains(5)); + assert!(range.contains(9)); + assert!(!range.contains(10)); + + let range = BlockRange::RangeFrom(RangeFrom { start: 5 }); + assert!(!range.contains(4)); + assert!(range.contains(5)); + assert!(range.contains(6)); + + let range = BlockRange::RangeTo(RangeTo { end: 8 }); + assert!(range.contains(7)); + assert!(!range.contains(8)); + assert!(!range.contains(9)); + + let range = BlockRange::RangeInclusive(RangeInclusive::new(2, 9)); + assert!(!range.contains(1)); + assert!(range.contains(2)); + assert!(range.contains(9)); + assert!(!range.contains(10)); + + let range = BlockRange::FullRange; + assert!(range.contains(0)); + assert!(range.contains(1)); + assert!(range.contains(1000)); + } + + #[test] + fn test_to_fields() { + let range = BlockRange::Range(1..10); + let fields = range.to_fields::().unwrap(); + assert_eq!(fields, vec![Field::from_u8(0), Field::from_u32(1), Field::from_u32(10)]); + + let range = BlockRange::RangeFrom(RangeFrom { start: 5 }); + let fields = range.to_fields::().unwrap(); + assert_eq!(fields, vec![Field::from_u8(1), Field::from_u32(5), -Field::one()]); + + let range = BlockRange::RangeTo(RangeTo { end: 8 }); + let fields = range.to_fields::().unwrap(); + assert_eq!(fields, vec![Field::from_u8(2), -Field::one(), Field::from_u32(8)]); + + let range = BlockRange::RangeInclusive(RangeInclusive::new(2, 9)); + let fields = range.to_fields::().unwrap(); + assert_eq!(fields, vec![Field::from_u8(3), Field::from_u32(2), Field::from_u32(9)]); + + let range = BlockRange::FullRange; + let fields = range.to_fields::().unwrap(); + assert_eq!(fields, vec![Field::from_u8(4), -Field::one(), -Field::one()]); + } +} diff --git a/synthesizer/src/restrictions/helpers/mod.rs b/synthesizer/src/restrictions/helpers/mod.rs new file mode 100644 index 0000000000..62ecb40d57 --- /dev/null +++ b/synthesizer/src/restrictions/helpers/mod.rs @@ -0,0 +1,20 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +mod argument_locator; +pub use argument_locator::*; + +mod block_range; +pub use block_range::*; diff --git a/synthesizer/src/restrictions/mod.rs b/synthesizer/src/restrictions/mod.rs new file mode 100644 index 0000000000..b9e5db26fc --- /dev/null +++ b/synthesizer/src/restrictions/mod.rs @@ -0,0 +1,387 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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. + +mod helpers; +pub use helpers::*; + +mod serialize; +mod string; + +use console::{ + network::prelude::*, + program::{Identifier, Literal, Locator, Plaintext, ProgramID}, + types::Field, +}; +use ledger_block::{Execution, Input, Output, Transition}; + +use indexmap::IndexMap; + +#[derive(Clone, PartialEq, Eq)] +pub struct Restrictions { + /// The restrictions ID, for the current state of the `Restrictions` list. + restrictions_id: Field, + /// The set of program IDs that are restricted from being executed. + /// e.g. `restricted.aleo` => `..` (all blocks) + /// e.g. `restricted.aleo` => `10..` (from block 10 onwards) + /// e.g. `restricted.aleo` => `..10` (up to block 10) + /// e.g. `restricted.aleo` => `10..20` (from block 10 to block 20) + programs: IndexMap, BlockRange>, + /// The set of `(program ID, function name)` pairs that are restricted from being executed. + /// e.g. `restricted.aleo/foo` => `..` (all blocks) + /// e.g. `restricted.aleo/foo` => `10..` (from block 10 onwards) + /// e.g. `restricted.aleo/foo` => `..10` (up to block 10) + /// e.g. `restricted.aleo/foo` => `10..20` (from block 10 to block 20) + functions: IndexMap, BlockRange>, + /// The set of `(program ID, function name, argument)` triples that are restricted from being executed. + /// e.g. `restricted.aleo/bar _ aleo1zkpxxxxx _ _` => `..` (all blocks) + /// e.g. `restricted.aleo/bar _ aleo1zkpxxxxx _ _` => `10..` (from block 10 onwards) + /// e.g. `restricted.aleo/bar _ aleo1zkpxxxxx _ _` => `..10` (up to block 10) + /// e.g. `restricted.aleo/bar _ aleo1zkpxxxxx _ _` => `10..20` (from block 10 to block 20) + /// + /// Note: This design intentionally minimizes the number of total lookups required to check + /// for restrictions when a transition matches the described profile. In summary: + /// - When a transition does not match the program ID or function name, the total lookup cost is `O(1)`. + /// - When a transition matches the program ID & function name, the initial lookup cost is `O(num_inputs + num_outputs)`. + /// - If an input or output index does not match, the additional lookup cost is `0`. + /// - If an input or output index matches, the additional lookup cost is `O(n)` for `n` restricted arguments with the same index. + arguments: IndexMap, IndexMap, BlockRange>>>, +} + +impl Restrictions { + /// Initializes the `Restrictions` instance for the current network. + pub fn load() -> Result { + // Load the restrictions list from the network. + let restrictions = Self::from_str(N::restrictions_list_as_str())?; + // Ensure the restrictions ID matches the computed value. + let expected_restrictions_id = + Self::compute_restrictions_id(&restrictions.programs, &restrictions.functions, &restrictions.arguments)?; + if restrictions.restrictions_id != expected_restrictions_id { + bail!( + "The restrictions ID does not match the computed value upon initialization (expected - {expected_restrictions_id})" + ); + } + // Return the restrictions. + Ok(restrictions) + } + + /// Initializes a new `Restrictions` instance. + pub fn new_blank() -> Result { + Ok(Self { + restrictions_id: Self::compute_restrictions_id(&IndexMap::new(), &IndexMap::new(), &IndexMap::new())?, + programs: IndexMap::new(), + functions: IndexMap::new(), + arguments: IndexMap::new(), + }) + } +} + +impl Restrictions { + /// Returns the restrictions ID, for the current state of the `Restrictions` list. + pub const fn restrictions_id(&self) -> Field { + self.restrictions_id + } + + /// Returns the set of program IDs that are restricted from being executed. + pub const fn programs(&self) -> &IndexMap, BlockRange> { + &self.programs + } + + /// Returns the set of `(program ID, function ID)` pairs that are restricted from being executed. + pub const fn functions(&self) -> &IndexMap, BlockRange> { + &self.functions + } + + /// Returns the set of `(program ID, function ID, argument)` triples that are restricted from being executed. + pub const fn arguments( + &self, + ) -> &IndexMap, IndexMap, BlockRange>>> { + &self.arguments + } +} + +impl Restrictions { + /// Returns `true` if the given program ID is restricted from being executed. + pub fn is_program_restricted(&self, program_id: &ProgramID, block_height: u32) -> bool { + self.programs.get(program_id).map_or(false, |range| range.contains(block_height)) + } + + /// Returns `true` if the given `(program ID, function name)` pair is restricted from being executed. + pub fn is_function_restricted( + &self, + program_id: &ProgramID, + function_name: &Identifier, + block_height: u32, + ) -> bool { + self.functions + .get(&Locator::new(*program_id, *function_name)) + .map_or(false, |range| range.contains(block_height)) + } + + /// Returns `true` if the given `(program ID, function ID, argument)` triple is restricted from being executed. + pub fn is_argument_restricted(&self, transition: &Transition, block_height: u32) -> bool { + self.arguments.get(&Locator::new(*transition.program_id(), *transition.function_name())).map_or( + false, + |entries| { + // Check if any argument is restricted and return `true` if one is found. + for (argument_locator, arguments) in entries { + match argument_locator.is_input() { + true => { + if let Some(argument) = transition.inputs().get(argument_locator.index() as usize) { + match argument { + Input::Constant(_, Some(plaintext)) | Input::Public(_, Some(plaintext)) => { + match plaintext { + Plaintext::Literal(literal, _) => { + if let Some(range) = arguments.get(literal) { + if range.contains(block_height) { + return true; + } + } + } + Plaintext::Struct(..) | Plaintext::Array(..) => continue, + } + } + _ => continue, + } + } + } + false => { + if let Some(argument) = transition.outputs().get(argument_locator.index() as usize) { + match argument { + Output::Constant(_, Some(plaintext)) | Output::Public(_, Some(plaintext)) => { + match plaintext { + Plaintext::Literal(literal, _) => { + if let Some(range) = arguments.get(literal) { + if range.contains(block_height) { + return true; + } + } + } + Plaintext::Struct(..) | Plaintext::Array(..) => continue, + } + } + _ => continue, + } + } + } + } + } + // Otherwise, return `false`. + false + }, + ) + } +} + +impl Restrictions { + /// Returns `true` if the given execution contains any restricted transitions for the given block height. + pub fn contains_restricted_transitions(&self, execution: &Execution, block_height: u32) -> bool { + // Check if any transition is restricted. + execution.transitions().any(|transition| { + // Retrieve the program ID. + let program_id = transition.program_id(); + // Retrieve the function name. + let function_name = transition.function_name(); + + // If the program is restricted, then the transition is restricted. + if self.is_program_restricted(program_id, block_height) { + return true; + } + // If the function is restricted, then the transition is restricted. + if self.is_function_restricted(program_id, function_name, block_height) { + return true; + } + // If any argument is restricted, then the transition is restricted. + if self.is_argument_restricted(transition, block_height) { + return true; + } + // Otherwise, the transition is not restricted. + false + }) + } +} + +impl Restrictions { + /// Returns the restrictions ID. + pub fn compute_restrictions_id( + programs: &IndexMap, BlockRange>, + functions: &IndexMap, BlockRange>, + arguments: &IndexMap, IndexMap, BlockRange>>>, + ) -> Result> { + // Prepare the preimage data. + let mut preimage = Vec::new(); + + // Append the number of programs. + preimage.push(Field::from_u64(programs.len() as u64)); + // Encode the programs. + for (program_id, range) in programs { + preimage.extend_from_slice(&program_id.to_fields()?); + preimage.extend_from_slice(&range.to_fields()?); + } + + // Append the number of functions. + preimage.push(Field::from_u64(functions.len() as u64)); + // Encode the functions. + for (locator, range) in functions { + preimage.extend_from_slice(&locator.program_id().to_fields()?); + preimage.push(locator.resource().to_field()?); + preimage.extend_from_slice(&range.to_fields()?); + } + + // Append the number of arguments. + preimage.push(Field::from_u64(arguments.len() as u64)); + // Encode the arguments. + for (locator, entries) in arguments { + preimage.extend_from_slice(&locator.program_id().to_fields()?); + preimage.push(locator.resource().to_field()?); + // Append the number of argument entries. + preimage.push(Field::from_u64(entries.len() as u64)); + // Encode the argument entries. + for (argument_locator, arguments) in entries { + preimage.push(if argument_locator.is_input() { Field::one() } else { Field::zero() }); + preimage.push(Field::from_u16(argument_locator.index())); + // Append the number of arguments. + preimage.push(Field::from_u64(arguments.len() as u64)); + // Encode the arguments. + for (literal, range) in arguments { + // Encode the literal. + preimage.extend_from_slice(&Plaintext::from(literal).to_fields()?); + // Encode the range. + preimage.extend_from_slice(&range.to_fields()?); + } + } + } + + // Hash the preimage data. + // Note: This call must be collision-resistant, and so we use BHP-1024. + N::hash_bhp1024(&preimage.to_bits_le()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use console::types::I8; + + use indexmap::indexmap; + use ledger_block::Input; + + type CurrentNetwork = console::network::MainnetV0; + + #[test] + fn test_restrictions_program_restricted() { + let mut restrictions = Restrictions::::new_blank().unwrap(); + let program_id = ProgramID::from_str("restricted.aleo").unwrap(); + let range = BlockRange::Range(10..20); + restrictions.programs.insert(program_id, range); + assert!(!restrictions.is_program_restricted(&program_id, 5)); + assert!(restrictions.is_program_restricted(&program_id, 10)); + assert!(restrictions.is_program_restricted(&program_id, 15)); + assert!(!restrictions.is_program_restricted(&program_id, 20)); + assert!(!restrictions.is_program_restricted(&program_id, 25)); + } + + #[test] + fn test_restrictions_function_restricted() { + let mut restrictions = Restrictions::::new_blank().unwrap(); + let program_id = ProgramID::from_str("restricted.aleo").unwrap(); + let function_id = Identifier::from_str("foo").unwrap(); + let range = BlockRange::Range(10..20); + restrictions.functions.insert(Locator::new(program_id, function_id), range); + assert!(!restrictions.is_function_restricted(&program_id, &function_id, 5)); + assert!(restrictions.is_function_restricted(&program_id, &function_id, 10)); + assert!(restrictions.is_function_restricted(&program_id, &function_id, 15)); + assert!(!restrictions.is_function_restricted(&program_id, &function_id, 20)); + assert!(!restrictions.is_function_restricted(&program_id, &function_id, 25)); + } + + #[test] + fn test_restrictions_argument_restricted() { + let rng = &mut TestRng::default(); + + let mut restrictions = Restrictions::::new_blank().unwrap(); + let program_id = ProgramID::from_str("restricted.aleo").unwrap(); + let function_id = Identifier::from_str("bar").unwrap(); + let range = BlockRange::Range(10..20); + + let literal = Literal::I8(I8::new(42)); + let index = 0; + restrictions.arguments.insert( + Locator::new(program_id, function_id), + indexmap!( ArgumentLocator::new(true, index) => indexmap!( literal.clone() => range )), + ); + + let input = Input::Public(rng.gen(), Some(literal.into())); + let transition = + Transition::new(program_id, function_id, vec![input], vec![], rng.gen(), rng.gen(), rng.gen()).unwrap(); + assert!(!restrictions.is_argument_restricted(&transition, 5)); + assert!(restrictions.is_argument_restricted(&transition, 10)); + assert!(restrictions.is_argument_restricted(&transition, 15)); + assert!(!restrictions.is_argument_restricted(&transition, 20)); + assert!(!restrictions.is_argument_restricted(&transition, 25)); + } + + /// **Attention**: This method is used to auto-generate the restrictions lists for each network + /// to be used by the `snarkvm_parameters` crate. + #[test] + fn test_restrictions_list_comparison() { + #[rustfmt::skip] + macro_rules! check_restrictions { + ($restrictions:expr, $network:ident) => {{ + // Write the restrictions to a JSON-compatible string. + let restrictions_string = $restrictions.to_string(); + // Compute the restrictions ID. + let restrictions_id = $restrictions.restrictions_id(); + // Print out the restrictions list. + println!("========\n Restrictions for '{}' ({restrictions_id})\n========\n{restrictions_string}", Network::NAME); + // Compare the restrictions list. + assert_eq!( + restrictions_string, + Restrictions::<$network>::load().unwrap().to_string(), + "Ensure 'snarkvm_parameters/src/NETWORK/resources/restrictions.json' matches 'restrictions_string' in this test" + ); + }}; + } + + // Attention: The 'restrictions' variable **must match** the 'restrictions.json' in 'snarkvm_parameters' for each network. + { + // Set the network. + type Network = console::network::MainnetV0; + // Initialize the restrictions. + let restrictions = Restrictions::::new_blank().unwrap(); + // Check the restrictions. + check_restrictions!(restrictions, Network); + } + + // Attention: The 'restrictions' variable **must match** the 'restrictions.json' in 'snarkvm_parameters' for each network. + { + // Set the network. + type Network = console::network::TestnetV0; + // Initialize the restrictions. + let restrictions = Restrictions::::new_blank().unwrap(); + // Check the restrictions. + check_restrictions!(restrictions, Network); + } + + // Attention: The 'restrictions' variable **must match** the 'restrictions.json' in 'snarkvm_parameters' for each network. + { + // Set the network. + type Network = console::network::CanaryV0; + // Initialize the restrictions. + let restrictions = Restrictions::::new_blank().unwrap(); + // Check the restrictions. + check_restrictions!(restrictions, Network); + } + } +} diff --git a/synthesizer/src/restrictions/serialize.rs b/synthesizer/src/restrictions/serialize.rs new file mode 100644 index 0000000000..81898fe6c7 --- /dev/null +++ b/synthesizer/src/restrictions/serialize.rs @@ -0,0 +1,169 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +use utilities::DeserializeExt; + +impl Serialize for Restrictions { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_struct("Restrictions", 4)?; + state.serialize_field("restrictions_id", &self.restrictions_id)?; + state.serialize_field("programs", &self.programs)?; + state.serialize_field("functions", &self.functions)?; + state.serialize_field("arguments", &self.arguments)?; + state.end() + } +} + +impl<'de, N: Network> Deserialize<'de> for Restrictions { + /// Deserializes the restrictions from a JSON-string. + fn deserialize>(deserializer: D) -> Result { + let mut restrictions = serde_json::Value::deserialize(deserializer)?; + + // Recover the restrictions. + Ok(Self { + restrictions_id: DeserializeExt::take_from_value::(&mut restrictions, "restrictions_id")?, + programs: DeserializeExt::take_from_value::(&mut restrictions, "programs")?, + functions: DeserializeExt::take_from_value::(&mut restrictions, "functions")?, + arguments: DeserializeExt::take_from_value::(&mut restrictions, "arguments")?, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use console::types::Address; + + use rand::seq::SliceRandom; + + type CurrentNetwork = console::network::MainnetV0; + + const ITERATIONS: usize = 100; + + const TEST_PROGRAM_CASES: &[&str] = &["testing.aleo", "hello.aleo", "abc_def.aleo", "a1234.aleo"]; + const TEST_FUNCTION_CASES: &[&str] = &["testing", "transfer", "hello", "foo", "bar"]; + + /// Randomly select a program ID from the given test cases. + fn sample_program_id(rng: &mut R) -> ProgramID { + ProgramID::from_str(TEST_PROGRAM_CASES.choose(rng).unwrap()).unwrap() + } + + /// Randomly select a program and function name from the given test cases. + fn sample_locator(rng: &mut R) -> Locator { + let program_id = ProgramID::from_str(TEST_PROGRAM_CASES.choose(rng).unwrap()).unwrap(); + let function_name = Identifier::from_str(TEST_FUNCTION_CASES.choose(rng).unwrap()).unwrap(); + Locator::new(program_id, function_name) + } + + /// Randomly sample a block range. + fn sample_block_range(rng: &mut R) -> BlockRange { + let variant = rng.gen_range(0..5); + match variant { + 0 => { + let start = rng.gen(); + let end = rng.gen_range(start..=u32::MAX); + BlockRange::Range(start..end) + } + 1 => BlockRange::RangeFrom(rng.gen()..), + 2 => BlockRange::RangeTo(..rng.gen()), + 3 => { + let start = rng.gen(); + let end = rng.gen_range(start..=u32::MAX); + BlockRange::RangeInclusive(start..=end) + } + 4 => BlockRange::FullRange, + _ => unreachable!(), + } + } + + /// Randomly sample a set of restrictions. + fn sample_restrictions(rng: &mut R) -> Restrictions { + const NUM_RESTRICTIONS: usize = 10; + + let mut restrictions = Restrictions::::new_blank().unwrap(); + // Add the program restrictions. + for _ in 0..NUM_RESTRICTIONS { + let program_id = sample_program_id(rng); + let range = sample_block_range(rng); + restrictions.programs.insert(program_id, range); + } + // Add the function restrictions. + for _ in 0..NUM_RESTRICTIONS { + let locator = sample_locator(rng); + let range = sample_block_range(rng); + restrictions.functions.insert(locator, range); + } + // Add the argument restrictions. + for _ in 0..NUM_RESTRICTIONS { + let locator = sample_locator(rng); + + // Add the argument locators. + let mut arguments = IndexMap::new(); + for _ in 0..NUM_RESTRICTIONS { + let argument_locator = ArgumentLocator::new(rng.gen(), rng.gen_range(0..16)); + + // Add the literals. + let mut literals = IndexMap::new(); + for _ in 0..NUM_RESTRICTIONS { + let literal = Literal::Address(Address::rand(rng)); + let range = sample_block_range(rng); + literals.insert(literal, range); + } + arguments.insert(argument_locator, literals); + } + restrictions.arguments.insert(locator, arguments); + } + // Set the restrictions ID. + restrictions.restrictions_id = Restrictions::compute_restrictions_id( + &restrictions.programs, + &restrictions.functions, + &restrictions.arguments, + ) + .unwrap(); + // Return the restrictions. + restrictions + } + + fn check_serde_json Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr>( + expected: T, + ) { + // Serialize + let expected_string = expected.to_string(); + let candidate_string = serde_json::to_string_pretty(&expected).unwrap(); + let candidate = serde_json::from_str::(&candidate_string).unwrap(); + assert_eq!(expected, candidate); + assert_eq!(expected_string, candidate_string); + assert_eq!(expected_string, candidate.to_string()); + + // Deserialize + assert_eq!(expected, T::from_str(&expected_string).unwrap_or_else(|_| panic!("FromStr: {expected_string}"))); + assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap()); + } + + #[test] + fn test_serde_json() { + let rng = &mut TestRng::default(); + + for _ in 0..ITERATIONS { + let expected = sample_restrictions(rng); + check_serde_json(expected); + } + } +} diff --git a/synthesizer/src/restrictions/string.rs b/synthesizer/src/restrictions/string.rs new file mode 100644 index 0000000000..293ae079d5 --- /dev/null +++ b/synthesizer/src/restrictions/string.rs @@ -0,0 +1,39 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 super::*; + +impl FromStr for Restrictions { + type Err = Error; + + /// Initializes the restrictions from a JSON-string. + fn from_str(restrictions: &str) -> Result { + Ok(serde_json::from_str(restrictions)?) + } +} + +impl Debug for Restrictions { + /// Prints the restrictions as a JSON-string. + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(self, f) + } +} + +impl Display for Restrictions { + /// Displays the restrictions as a JSON-string. + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{}", serde_json::to_string_pretty(self).map_err::(ser::Error::custom)?) + } +} diff --git a/synthesizer/src/vm/authorize.rs b/synthesizer/src/vm/authorize.rs index 75aed8d4c4..4e51e88813 100644 --- a/synthesizer/src/vm/authorize.rs +++ b/synthesizer/src/vm/authorize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/src/vm/deploy.rs b/synthesizer/src/vm/deploy.rs index e080ba54d9..e8104291ea 100644 --- a/synthesizer/src/vm/deploy.rs +++ b/synthesizer/src/vm/deploy.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -40,7 +41,7 @@ impl> VM { let owner = ProgramOwner::new(private_key, deployment_id, rng)?; // Compute the minimum deployment cost. - let (minimum_deployment_cost, (_, _)) = deployment_cost(&deployment)?; + let (minimum_deployment_cost, _) = deployment_cost(&deployment)?; // Authorize the fee. let fee_authorization = match fee_record { Some(record) => self.authorize_fee_private( diff --git a/synthesizer/src/vm/execute.rs b/synthesizer/src/vm/execute.rs index 31a2111188..97ab70d379 100644 --- a/synthesizer/src/vm/execute.rs +++ b/synthesizer/src/vm/execute.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -45,7 +46,12 @@ impl> VM { let fee = match is_fee_required || is_priority_fee_declared { true => { // Compute the minimum execution cost. - let (minimum_execution_cost, (_, _)) = execution_cost(self, &execution)?; + let query = query.clone().unwrap_or(Query::VM(self.block_store().clone())); + let block_height = query.current_block_height()?; + let (minimum_execution_cost, (_, _)) = match block_height < N::CONSENSUS_V2_HEIGHT { + true => execution_cost_v1(&self.process().read(), &execution)?, + false => execution_cost_v2(&self.process().read(), &execution)?, + }; // Compute the execution ID. let execution_id = execution.to_execution_id()?; // Authorize the fee. @@ -67,7 +73,7 @@ impl> VM { )?, }; // Execute the fee. - Some(self.execute_fee_authorization_raw(authorization, query, rng)?) + Some(self.execute_fee_authorization_raw(authorization, Some(query), rng)?) } false => None, }; @@ -206,18 +212,21 @@ impl> VM { #[cfg(test)] mod tests { use super::*; + use console::{ account::{Address, ViewKey}, - network::Testnet3, + network::MainnetV0, program::{Ciphertext, Value}, types::Field, }; use ledger_block::Transition; use ledger_store::helpers::memory::ConsensusMemory; + use synthesizer_process::{ConsensusFeeVersion, cost_per_command, execution_cost_v2}; + use synthesizer_program::StackProgram; use indexmap::IndexMap; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; fn prepare_vm( rng: &mut TestRng, @@ -242,6 +251,293 @@ mod tests { Ok((vm, records)) } + #[test] + fn test_bond_validator_transaction_size() { + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let validator_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + let withdrawal_private_key = PrivateKey::::new(rng).unwrap(); + let withdrawal_address = Address::try_from(&withdrawal_private_key).unwrap(); + + // Prepare the VM and records. + let (vm, _) = prepare_vm(rng).unwrap(); + + // Prepare the inputs. + let inputs = [ + Value::::from_str(&withdrawal_address.to_string()).unwrap(), + Value::::from_str("1_000_000u64").unwrap(), + Value::::from_str("5u8").unwrap(), + ] + .into_iter(); + + // Execute. + let transaction = + vm.execute(&validator_private_key, ("credits.aleo", "bond_validator"), inputs, None, 0, None, rng).unwrap(); + + // Ensure the transaction is a bond public transition. + assert_eq!(transaction.transitions().count(), 2); + assert!(transaction.transitions().take(1).next().unwrap().is_bond_validator()); + + // Assert the size of the transaction. + let transaction_size_in_bytes = transaction.to_bytes_le().unwrap().len(); + assert_eq!(2914, transaction_size_in_bytes, "Update me if serialization has changed"); + + // Assert the size of the execution. + assert!(matches!(transaction, Transaction::Execute(_, _, _))); + if let Transaction::Execute(_, execution, _) = &transaction { + let execution_size_in_bytes = execution.to_bytes_le().unwrap().len(); + assert_eq!(1463, execution_size_in_bytes, "Update me if serialization has changed"); + } + } + + #[test] + fn test_bond_public_transaction_size() { + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let validator_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + let validator_address = Address::try_from(&validator_private_key).unwrap(); + let delegator_private_key = PrivateKey::::new(rng).unwrap(); + let delegator_address = Address::try_from(&delegator_private_key).unwrap(); + + // Prepare the VM and records. + let (vm, _) = prepare_vm(rng).unwrap(); + + // Prepare the inputs. + let inputs = [ + Value::::from_str(&validator_address.to_string()).unwrap(), + Value::::from_str(&delegator_address.to_string()).unwrap(), + Value::::from_str("1_000_000u64").unwrap(), + ] + .into_iter(); + + // Execute. + let transaction = + vm.execute(&delegator_private_key, ("credits.aleo", "bond_public"), inputs, None, 0, None, rng).unwrap(); + + // Ensure the transaction is a bond public transition. + assert_eq!(transaction.transitions().count(), 2); + assert!(transaction.transitions().take(1).next().unwrap().is_bond_public()); + + // Assert the size of the transaction. + let transaction_size_in_bytes = transaction.to_bytes_le().unwrap().len(); + assert_eq!(2970, transaction_size_in_bytes, "Update me if serialization has changed"); + + // Assert the size of the execution. + assert!(matches!(transaction, Transaction::Execute(_, _, _))); + if let Transaction::Execute(_, execution, _) = &transaction { + let execution_size_in_bytes = execution.to_bytes_le().unwrap().len(); + assert_eq!(1519, execution_size_in_bytes, "Update me if serialization has changed"); + } + } + + #[cfg(feature = "test")] + #[test] + fn test_execute_cost_fee_migration() { + let rng = &mut TestRng::default(); + let credits_program = "credits.aleo"; + let function_name = "transfer_public"; + + // Initialize a new caller. + let caller_private_key: PrivateKey = PrivateKey::new(rng).unwrap(); + let recipient_private_key: PrivateKey = PrivateKey::new(rng).unwrap(); + let recipient_address = Address::try_from(&recipient_private_key).unwrap(); + let transfer_public_amount = 1_000_000u64; + let inputs = &[recipient_address.to_string(), format!("{transfer_public_amount}_u64")]; + + // Prepare the VM and records. + let (vm, _) = prepare_vm(rng).unwrap(); + + // Prepare the inputs. + + let authorization = vm.authorize(&caller_private_key, credits_program, function_name, inputs, rng).unwrap(); + + let execution = vm.execute_authorization_raw(authorization, None, rng).unwrap(); + let (cost, _) = execution_cost_v2(&vm.process().read(), &execution).unwrap(); + let (old_cost, _) = execution_cost_v1(&vm.process().read(), &execution).unwrap(); + + assert_eq!(34_060, cost); + assert_eq!(51_060, old_cost); + + // Since transfer_public has 2 get.or_use's, the difference is (MAPPING_COST_V1 - MAPPING_BASE_COST_V2) * 2 + assert_eq!(old_cost - cost, 8_500 * 2); + } + + #[cfg(feature = "test")] + #[test] + fn test_fee_migration_occurs_at_correct_block_height() { + // This test will fail if the consensus v2 height is 0 + assert_ne!(0, CurrentNetwork::CONSENSUS_V2_HEIGHT); + + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + let address = Address::try_from(&private_key).unwrap(); + + // Prepare the VM and records. + let (vm, _) = prepare_vm(rng).unwrap(); + + // Prepare the inputs. + let inputs = [ + Value::::from_str(&address.to_string()).unwrap(), + Value::::from_str("1_000_000u64").unwrap(), + ] + .into_iter(); + + // Execute. + let transaction = + vm.execute(&private_key, ("credits.aleo", "transfer_public"), inputs.clone(), None, 0, None, rng).unwrap(); + + assert_eq!(51_060, *transaction.base_fee_amount().unwrap()); + + let transactions: [Transaction; 0] = []; + for _ in 0..CurrentNetwork::CONSENSUS_V2_HEIGHT { + // Call the function + let next_block = crate::vm::test_helpers::sample_next_block(&vm, &private_key, &transactions, rng).unwrap(); + vm.add_next_block(&next_block).unwrap(); + } + + let transaction = + vm.execute(&private_key, ("credits.aleo", "transfer_public"), inputs.clone(), None, 0, None, rng).unwrap(); + + assert_eq!(34_060, *transaction.base_fee_amount().unwrap()); + } + + #[cfg(feature = "test")] + #[test] + fn test_fee_migration_correctly_calculates_nested() { + // This test will fail if the consensus v2 height is 0 + assert_ne!(0, CurrentNetwork::CONSENSUS_V2_HEIGHT); + + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + + // Prepare the VM and records. + let (vm, _) = prepare_vm(rng).unwrap(); + + // Deploy a nested program to test the finalize cost cache + let program = Program::from_str( + r" +import credits.aleo; +program nested_call.aleo; +mapping data: + key as field.public; + value as field.public; +function test: + input r0 as u64.public; + call credits.aleo/transfer_public_as_signer nested_call.aleo r0 into r1; + async test r1 into r2; + output r2 as nested_call.aleo/test.future; +finalize test: + input r0 as credits.aleo/transfer_public_as_signer.future; + await r0; + get data[0field] into r1;", + ) + .unwrap(); + + // Deploy the program. + let transaction = vm.deploy(&private_key, &program, None, 0, None, rng).unwrap(); + + // Construct the next block. + let next_block = crate::test_helpers::sample_next_block(&vm, &private_key, &[transaction], rng).unwrap(); + + // Add the next block to the VM. + vm.add_next_block(&next_block).unwrap(); + + // Prepare the inputs. + let inputs = [Value::::from_str("1_000_000u64").unwrap()].into_iter(); + + // Execute. + let transaction = + vm.execute(&private_key, ("nested_call.aleo", "test"), inputs.clone(), None, 0, None, rng).unwrap(); + + // This fee should be at least the old credits.aleo/transfer_public fee, 51_060 + assert_eq!(62_776, *transaction.base_fee_amount().unwrap()); + + let transactions: [Transaction; 0] = []; + for _ in 1..CurrentNetwork::CONSENSUS_V2_HEIGHT { + // Call the function + let next_block = crate::vm::test_helpers::sample_next_block(&vm, &private_key, &transactions, rng).unwrap(); + vm.add_next_block(&next_block).unwrap(); + } + + let transaction = + vm.execute(&private_key, ("nested_call.aleo", "test"), inputs.clone(), None, 0, None, rng).unwrap(); + + // The difference in old vs new fees is 8_500 * 3 = 25_500 for the three get/get.or_use's + // There are two get.or_use's in transfer_public and an additional one in the nested_call.aleo/test + assert_eq!(37_276, *transaction.base_fee_amount().unwrap()); + } + + #[test] + fn test_credits_bond_public_cost() { + let rng = &mut TestRng::default(); + let credits_program = "credits.aleo"; + let function_name = "bond_public"; + + // Initialize a new caller. + let caller_private_key: PrivateKey = PrivateKey::new(rng).unwrap(); + let validator_private_key: PrivateKey = PrivateKey::new(rng).unwrap(); + let validator_address = Address::try_from(&validator_private_key).unwrap(); + let withdrawal_address = Address::try_from(&caller_private_key).unwrap(); + let bond_public_amount = 1_000_000u64; + let inputs = + &[validator_address.to_string(), withdrawal_address.to_string(), format!("{bond_public_amount}_u64")]; + + // Prepare the VM and records. + let (vm, _) = prepare_vm(rng).unwrap(); + + // Prepare the inputs. + + let authorization = vm.authorize(&caller_private_key, credits_program, function_name, inputs, rng).unwrap(); + + let execution = vm.execute_authorization_raw(authorization, None, rng).unwrap(); + let (cost, _) = execution_cost_v1(&vm.process().read(), &execution).unwrap(); + println!("Cost: {}", cost); + } + + #[test] + fn test_unbond_public_transaction_size() { + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + let address = Address::try_from(&caller_private_key).unwrap(); + + // Prepare the VM and records. + let (vm, _) = prepare_vm(rng).unwrap(); + + // Prepare the inputs. + let inputs = [ + Value::::from_str(&address.to_string()).unwrap(), + Value::::from_str("1u64").unwrap(), + ] + .into_iter(); + + // Execute. + let transaction = + vm.execute(&caller_private_key, ("credits.aleo", "unbond_public"), inputs, None, 0, None, rng).unwrap(); + + // Ensure the transaction is an unbond public transition. + assert_eq!(transaction.transitions().count(), 2); + assert!(transaction.transitions().take(1).next().unwrap().is_unbond_public()); + + // Assert the size of the transaction. + let transaction_size_in_bytes = transaction.to_bytes_le().unwrap().len(); + assert_eq!(2867, transaction_size_in_bytes, "Update me if serialization has changed"); + + // Assert the size of the execution. + assert!(matches!(transaction, Transaction::Execute(_, _, _))); + if let Transaction::Execute(_, execution, _) = &transaction { + let execution_size_in_bytes = execution.to_bytes_le().unwrap().len(); + assert_eq!(1416, execution_size_in_bytes, "Update me if serialization has changed"); + } + } + #[test] fn test_transfer_private_transaction_size() { let rng = &mut TestRng::default(); @@ -271,13 +567,13 @@ mod tests { // Assert the size of the transaction. let transaction_size_in_bytes = transaction.to_bytes_le().unwrap().len(); - assert_eq!(3629, transaction_size_in_bytes, "Update me if serialization has changed"); + assert_eq!(3693, transaction_size_in_bytes, "Update me if serialization has changed"); // Assert the size of the execution. assert!(matches!(transaction, Transaction::Execute(_, _, _))); if let Transaction::Execute(_, execution, _) = &transaction { let execution_size_in_bytes = execution.to_bytes_le().unwrap().len(); - assert_eq!(2210, execution_size_in_bytes, "Update me if serialization has changed"); + assert_eq!(2242, execution_size_in_bytes, "Update me if serialization has changed"); } } @@ -305,13 +601,47 @@ mod tests { // Assert the size of the transaction. let transaction_size_in_bytes = transaction.to_bytes_le().unwrap().len(); - assert_eq!(2807, transaction_size_in_bytes, "Update me if serialization has changed"); + assert_eq!(2871, transaction_size_in_bytes, "Update me if serialization has changed"); // Assert the size of the execution. assert!(matches!(transaction, Transaction::Execute(_, _, _))); if let Transaction::Execute(_, execution, _) = &transaction { let execution_size_in_bytes = execution.to_bytes_le().unwrap().len(); - assert_eq!(1388, execution_size_in_bytes, "Update me if serialization has changed"); + assert_eq!(1420, execution_size_in_bytes, "Update me if serialization has changed"); + } + } + + #[test] + fn test_transfer_public_as_signer_transaction_size() { + let rng = &mut TestRng::default(); + + // Initialize a new signer. + let signer = crate::vm::test_helpers::sample_genesis_private_key(rng); + let address = Address::try_from(&signer).unwrap(); + + // Prepare the VM and records. + let (vm, _) = prepare_vm(rng).unwrap(); + + // Prepare the inputs. + let inputs = [ + Value::::from_str(&address.to_string()).unwrap(), + Value::::from_str("1u64").unwrap(), + ] + .into_iter(); + + // Execute. + let transaction = + vm.execute(&signer, ("credits.aleo", "transfer_public_as_signer"), inputs, None, 0, None, rng).unwrap(); + + // Assert the size of the transaction. + let transaction_size_in_bytes = transaction.to_bytes_le().unwrap().len(); + assert_eq!(2891, transaction_size_in_bytes, "Update me if serialization has changed"); + + // Assert the size of the execution. + assert!(matches!(transaction, Transaction::Execute(_, _, _))); + if let Transaction::Execute(_, execution, _) = &transaction { + let execution_size_in_bytes = execution.to_bytes_le().unwrap().len(); + assert_eq!(1440, execution_size_in_bytes, "Update me if serialization has changed"); } } @@ -340,13 +670,13 @@ mod tests { // Assert the size of the transaction. let transaction_size_in_bytes = transaction.to_bytes_le().unwrap().len(); - assert_eq!(3474, transaction_size_in_bytes, "Update me if serialization has changed"); + assert_eq!(3538, transaction_size_in_bytes, "Update me if serialization has changed"); // Assert the size of the execution. assert!(matches!(transaction, Transaction::Execute(_, _, _))); if let Transaction::Execute(_, execution, _) = &transaction { let execution_size_in_bytes = execution.to_bytes_le().unwrap().len(); - assert_eq!(2055, execution_size_in_bytes, "Update me if serialization has changed"); + assert_eq!(2087, execution_size_in_bytes, "Update me if serialization has changed"); } } @@ -372,15 +702,19 @@ mod tests { let transaction = vm.execute(&caller_private_key, ("credits.aleo", "split"), inputs, None, 0, None, rng).unwrap(); + // Ensure the transaction is a split transition. + assert_eq!(transaction.transitions().count(), 1); + assert!(transaction.transitions().next().unwrap().is_split()); + // Assert the size of the transaction. let transaction_size_in_bytes = transaction.to_bytes_le().unwrap().len(); - assert_eq!(2134, transaction_size_in_bytes, "Update me if serialization has changed"); + assert_eq!(2166, transaction_size_in_bytes, "Update me if serialization has changed"); // Assert the size of the execution. assert!(matches!(transaction, Transaction::Execute(_, _, _))); if let Transaction::Execute(_, execution, _) = &transaction { let execution_size_in_bytes = execution.to_bytes_le().unwrap().len(); - assert_eq!(2099, execution_size_in_bytes, "Update me if serialization has changed"); + assert_eq!(2131, execution_size_in_bytes, "Update me if serialization has changed"); } } @@ -395,9 +729,13 @@ mod tests { Transaction::Fee(_, fee) => fee, _ => panic!("Expected a fee transaction"), }; + + // Ensure the transition is a fee transition. + assert!(fee.is_fee_private()); + // Assert the size of the transition. let fee_size_in_bytes = fee.to_bytes_le().unwrap().len(); - assert_eq!(2011, fee_size_in_bytes, "Update me if serialization has changed"); + assert_eq!(2043, fee_size_in_bytes, "Update me if serialization has changed"); } #[test] @@ -411,8 +749,303 @@ mod tests { Transaction::Fee(_, fee) => fee, _ => panic!("Expected a fee transaction"), }; + + // Ensure the transition is a fee transition. + assert!(fee.is_fee_public()); + // Assert the size of the transition. let fee_size_in_bytes = fee.to_bytes_le().unwrap().len(); - assert_eq!(1384, fee_size_in_bytes, "Update me if serialization has changed"); + assert_eq!(1416, fee_size_in_bytes, "Update me if serialization has changed"); + } + + #[test] + fn test_wide_nested_execution_cost() { + // Initialize an RNG. + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + + // Prepare the VM. + let (vm, _) = prepare_vm(rng).unwrap(); + + // Construct the child program. + let child_program = Program::from_str( + r" +program child.aleo; +mapping data: + key as field.public; + value as field.public; +function test: + input r0 as field.public; + input r1 as field.public; + async test r0 r1 into r2; + output r2 as child.aleo/test.future; +finalize test: + input r0 as field.public; + input r1 as field.public; + hash.bhp256 r0 into r2 as field; + hash.bhp256 r1 into r3 as field; + set r2 into data[r3];", + ) + .unwrap(); + + // Deploy the program. + let transaction = vm.deploy(&caller_private_key, &child_program, None, 0, None, rng).unwrap(); + + // Construct the next block. + let next_block = crate::test_helpers::sample_next_block(&vm, &caller_private_key, &[transaction], rng).unwrap(); + + // Add the next block to the VM. + vm.add_next_block(&next_block).unwrap(); + + // Construct the parent program. + let parent_program = Program::from_str( + r" +import child.aleo; +program parent.aleo; +function test: + call child.aleo/test 0field 1field into r0; + call child.aleo/test 2field 3field into r1; + call child.aleo/test 4field 5field into r2; + call child.aleo/test 6field 7field into r3; + call child.aleo/test 8field 9field into r4; + call child.aleo/test 10field 11field into r5; + call child.aleo/test 12field 13field into r6; + call child.aleo/test 14field 15field into r7; + call child.aleo/test 16field 17field into r8; + call child.aleo/test 18field 19field into r9; + call child.aleo/test 20field 21field into r10; + call child.aleo/test 22field 23field into r11; + call child.aleo/test 24field 25field into r12; + call child.aleo/test 26field 27field into r13; + call child.aleo/test 28field 29field into r14; + call child.aleo/test 30field 31field into r15; + async test r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 into r16; + output r16 as parent.aleo/test.future; +finalize test: + input r0 as child.aleo/test.future; + input r1 as child.aleo/test.future; + input r2 as child.aleo/test.future; + input r3 as child.aleo/test.future; + input r4 as child.aleo/test.future; + input r5 as child.aleo/test.future; + input r6 as child.aleo/test.future; + input r7 as child.aleo/test.future; + input r8 as child.aleo/test.future; + input r9 as child.aleo/test.future; + input r10 as child.aleo/test.future; + input r11 as child.aleo/test.future; + input r12 as child.aleo/test.future; + input r13 as child.aleo/test.future; + input r14 as child.aleo/test.future; + input r15 as child.aleo/test.future; + await r0; + await r1; + await r2; + await r3; + await r4; + await r5; + await r6; + await r7; + await r8; + await r9; + await r10; + await r11; + await r12; + await r13; + await r14; + await r15;", + ) + .unwrap(); + + // Deploy the program. + let transaction = vm.deploy(&caller_private_key, &parent_program, None, 0, None, rng).unwrap(); + + // Construct the next block. + let next_block = crate::test_helpers::sample_next_block(&vm, &caller_private_key, &[transaction], rng).unwrap(); + + // Add the next block to the VM. + vm.add_next_block(&next_block).unwrap(); + + // Execute the parent program. + let Transaction::Execute(_, execution, _) = vm + .execute(&caller_private_key, ("parent.aleo", "test"), Vec::>::new().iter(), None, 0, None, rng) + .unwrap() + else { + unreachable!("VM::execute always produces an `Execution`") + }; + + // Check that the number of transitions is correct. + // Change me if the `MAX_INPUTS` changes. + assert_eq!(execution.transitions().len(), ::MAX_INPUTS + 1); + + // Get the finalize cost of the execution. + let (_, (_, finalize_cost)) = execution_cost_v2(&vm.process().read(), &execution).unwrap(); + + // Compute the expected cost as the sum of the cost in microcredits of each command in each finalize block of each transition in the execution. + let mut expected_cost = 0; + for transition in execution.transitions() { + // Get the program ID and name of the transition. + let program_id = transition.program_id(); + let function_name = transition.function_name(); + // Get the stack. + let stack = vm.process().read().get_stack(program_id).unwrap().clone(); + // Get the finalize block of the transition and sum the cost of each command. + let cost = match stack.get_function(function_name).unwrap().finalize_logic() { + None => 0, + Some(finalize_logic) => { + // Aggregate the cost of all commands in the program. + finalize_logic + .commands() + .iter() + .map(|command| cost_per_command(&stack, finalize_logic, command, ConsensusFeeVersion::V2)) + .try_fold(0u64, |acc, res| { + res.and_then(|x| acc.checked_add(x).ok_or(anyhow!("Finalize cost overflowed"))) + }) + .unwrap() + } + }; + // Add the cost to the total cost. + expected_cost += cost; + } + + // Check that the finalize cost is equal to the expected cost. + assert_eq!(finalize_cost, expected_cost); + } + + #[test] + fn test_deep_nested_execution_cost() { + // Initialize an RNG. + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + + // Prepare the VM. + let (vm, _) = prepare_vm(rng).unwrap(); + + // Construct the base program. + let base_program = Program::from_str( + r" +program test_1.aleo; +mapping data: + key as field.public; + value as field.public; +function test: + input r0 as field.public; + input r1 as field.public; + async test r0 r1 into r2; + output r2 as test_1.aleo/test.future; +finalize test: + input r0 as field.public; + input r1 as field.public; + hash.bhp256 r0 into r2 as field; + hash.bhp256 r1 into r3 as field; + set r2 into data[r3];", + ) + .unwrap(); + + // Deploy the program. + let transaction = vm.deploy(&caller_private_key, &base_program, None, 0, None, rng).unwrap(); + + // Construct the next block. + let next_block = crate::test_helpers::sample_next_block(&vm, &caller_private_key, &[transaction], rng).unwrap(); + + // Add the next block to the VM. + vm.add_next_block(&next_block).unwrap(); + + // Initialize programs up to the maximum depth. + for i in 2..=Transaction::::MAX_TRANSITIONS - 1 { + // Construct the program. + let program = Program::from_str(&format!( + r" +{imports} +program test_{curr}.aleo; +mapping data: + key as field.public; + value as field.public; +function test: + input r0 as field.public; + input r1 as field.public; + call test_{prev}.aleo/test r0 r1 into r2; + async test r0 r1 r2 into r3; + output r3 as test_{curr}.aleo/test.future; +finalize test: + input r0 as field.public; + input r1 as field.public; + input r2 as test_{prev}.aleo/test.future; + await r2; + hash.bhp256 r0 into r3 as field; + hash.bhp256 r1 into r4 as field; + set r3 into data[r4];", + imports = (1..i).map(|j| format!("import test_{j}.aleo;")).join("\n"), + prev = i - 1, + curr = i, + )) + .unwrap(); + + // Deploy the program. + let transaction = vm.deploy(&caller_private_key, &program, None, 0, None, rng).unwrap(); + + // Construct the next block. + let next_block = + crate::test_helpers::sample_next_block(&vm, &caller_private_key, &[transaction], rng).unwrap(); + + // Add the next block to the VM. + vm.add_next_block(&next_block).unwrap(); + } + + // Execute the program. + let Transaction::Execute(_, execution, _) = vm + .execute( + &caller_private_key, + (format!("test_{}.aleo", Transaction::::MAX_TRANSITIONS - 1), "test"), + vec![Value::from_str("0field").unwrap(), Value::from_str("1field").unwrap()].iter(), + None, + 0, + None, + rng, + ) + .unwrap() + else { + unreachable!("VM::execute always produces an `Execution`") + }; + + // Check that the number of transitions is correct. + assert_eq!(execution.transitions().len(), Transaction::::MAX_TRANSITIONS - 1); + + // Get the finalize cost of the execution. + let (_, (_, finalize_cost)) = execution_cost_v2(&vm.process().read(), &execution).unwrap(); + + // Compute the expected cost as the sum of the cost in microcredits of each command in each finalize block of each transition in the execution. + let mut expected_cost = 0; + for transition in execution.transitions() { + // Get the program ID and name of the transition. + let program_id = transition.program_id(); + let function_name = transition.function_name(); + // Get the stack. + let stack = vm.process().read().get_stack(program_id).unwrap().clone(); + // Get the finalize block of the transition and sum the cost of each command. + let cost = match stack.get_function(function_name).unwrap().finalize_logic() { + None => 0, + Some(finalize_logic) => { + // Aggregate the cost of all commands in the program. + finalize_logic + .commands() + .iter() + .map(|command| cost_per_command(&stack, finalize_logic, command, ConsensusFeeVersion::V2)) + .try_fold(0u64, |acc, res| { + res.and_then(|x| acc.checked_add(x).ok_or(anyhow!("Finalize cost overflowed"))) + }) + .unwrap() + } + }; + // Add the cost to the total cost. + expected_cost += cost; + } + + // Check that the finalize cost is equal to the expected cost. + assert_eq!(finalize_cost, expected_cost); } } diff --git a/synthesizer/src/vm/finalize.rs b/synthesizer/src/vm/finalize.rs index 018bc781dd..199a571060 100644 --- a/synthesizer/src/vm/finalize.rs +++ b/synthesizer/src/vm/finalize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,8 +15,13 @@ use super::*; +use ledger_committee::{MAX_DELEGATORS, MIN_DELEGATOR_STAKE, MIN_VALIDATOR_SELF_STAKE}; +use utilities::cfg_sort_by_cached_key; + impl> VM { /// Speculates on the given list of transactions in the VM. + /// This function aborts all transactions that are not are well-formed or unique. + /// /// /// Returns the confirmed transactions, aborted transaction IDs, /// and finalize operations from pre-ratify and post-ratify. @@ -26,32 +32,61 @@ impl> VM { /// `Ratify::BlockReward(block_reward)` and `Ratify::PuzzleReward(puzzle_reward)` /// to the front of the `ratifications` list. #[inline] - pub fn speculate<'a>( + #[allow(clippy::too_many_arguments)] + pub fn speculate<'a, R: Rng + CryptoRng>( &self, state: FinalizeGlobalState, + time_since_last_block: i64, // TODO (raychu86): Consider moving this value into `FinalizeGlobalState`. coinbase_reward: Option, candidate_ratifications: Vec>, - candidate_solutions: Option<&CoinbaseSolution>, + candidate_solutions: &Solutions, candidate_transactions: impl ExactSizeIterator>, + rng: &mut R, ) -> Result<(Ratifications, Transactions, Vec, Vec>)> { let timer = timer!("VM::speculate"); + // Collect the candidate transactions into a vector. + let candidate_transactions: Vec<_> = candidate_transactions.collect::>(); + let candidate_transaction_ids: Vec<_> = candidate_transactions.iter().map(|tx| tx.id()).collect(); + + // Determine if the vm is currently processing the genesis block. + let is_genesis = + self.block_store().find_block_height_from_state_root(self.block_store().current_state_root())?.is_none(); + // If the transactions are not part of the genesis block, ensure each transaction is well-formed and unique. Abort any transactions that are not. + let (verified_transactions, verification_aborted_transactions) = match is_genesis { + // If the current state root does not exist in the block store, then the genesis block has not been introduced yet. + true => (candidate_transactions, vec![]), + // Verify transactions for all non-genesis cases. + false => self.prepare_for_speculate(&candidate_transactions, rng)?, + }; + // Performs a **dry-run** over the list of ratifications, solutions, and transactions. - let (ratifications, confirmed_transactions, aborted_transactions, ratified_finalize_operations) = self - .atomic_speculate( + let (ratifications, confirmed_transactions, speculation_aborted_transactions, ratified_finalize_operations) = + self.atomic_speculate( state, + time_since_last_block, coinbase_reward, candidate_ratifications, candidate_solutions, - candidate_transactions, + verified_transactions.into_iter(), )?; - // Convert the aborted transactions into aborted transaction IDs. - let mut aborted_transaction_ids = Vec::with_capacity(aborted_transactions.len()); - for (tx, error) in aborted_transactions { - warn!("Speculation safely aborted a transaction - {error} ({})", tx.id()); - aborted_transaction_ids.push(tx.id()); - } + // Get the aborted transaction ids. + let verification_aborted_transaction_ids = verification_aborted_transactions.iter().map(|(tx, e)| (tx.id(), e)); + let speculation_aborted_transaction_ids = speculation_aborted_transactions.iter().map(|(tx, e)| (tx.id(), e)); + let unordered_aborted_transaction_ids: IndexMap = + verification_aborted_transaction_ids.chain(speculation_aborted_transaction_ids).collect(); + + // Filter and order the aborted transaction ids according to candidate_transactions + let aborted_transaction_ids: Vec<_> = candidate_transaction_ids + .into_iter() + .filter_map(|tx_id| { + unordered_aborted_transaction_ids.get(&tx_id).map(|error| { + warn!("Speculation safely aborted a transaction - {error} ({tx_id})"); + tx_id + }) + }) + .collect(); finish!(timer, "Finished dry-run of the transactions"); @@ -65,18 +100,31 @@ impl> VM { } /// Checks the speculation on the given transactions in the VM. + /// This function also ensure that the given transactions are well-formed and unique. /// /// Returns the finalize operations from pre-ratify and post-ratify. #[inline] - pub fn check_speculate( + pub fn check_speculate( &self, state: FinalizeGlobalState, + time_since_last_block: i64, ratifications: &Ratifications, - solutions: Option<&CoinbaseSolution>, + solutions: &Solutions, transactions: &Transactions, + rng: &mut R, ) -> Result>> { let timer = timer!("VM::check_speculate"); + // Retrieve the transactions and their rejected IDs. + let transactions_and_rejected_ids = cfg_iter!(transactions) + .map(|transaction| transaction.to_rejected_id().map(|rejected_id| (transaction.deref(), rejected_id))) + .collect::>>()?; + // Ensure each transaction is well-formed and unique. + // NOTE: We perform the transaction checks here prior to `atomic_speculate` because we must + // ensure that the `Fee` transactions are valid. We can't unify the transaction checks in `atomic_speculate` + // because we run speculation on the unconfirmed variant of the transactions. + self.check_transactions(&transactions_and_rejected_ids, rng)?; + // Reconstruct the candidate ratifications to verify the speculation. let candidate_ratifications = ratifications.iter().cloned().collect::>(); // Reconstruct the unconfirmed transactions to verify the speculation. @@ -85,7 +133,14 @@ impl> VM { // Performs a **dry-run** over the list of ratifications, solutions, and transactions. let (speculate_ratifications, confirmed_transactions, aborted_transactions, ratified_finalize_operations) = - self.atomic_speculate(state, None, candidate_ratifications, solutions, candidate_transactions.iter())?; + self.atomic_speculate( + state, + time_since_last_block, + None, + candidate_ratifications, + solutions, + candidate_transactions.iter(), + )?; // Ensure the ratifications after speculation match. if ratifications != &speculate_ratifications { @@ -114,7 +169,7 @@ impl> VM { &self, state: FinalizeGlobalState, ratifications: &Ratifications, - solutions: Option<&CoinbaseSolution>, + solutions: &Solutions, transactions: &Transactions, ) -> Result>> { let timer = timer!("VM::finalize"); @@ -132,7 +187,7 @@ impl> VM { #[cfg(not(any(test, feature = "test")))] pub const MAXIMUM_CONFIRMED_TRANSACTIONS: usize = Transactions::::MAX_TRANSACTIONS; /// The maximum number of confirmed transactions allowed in a block. - /// This is set to a deliberately low value (8) for testing purposes only. + /// This is deliberately set to a low value (8) for testing purposes only. #[cfg(any(test, feature = "test"))] pub const MAXIMUM_CONFIRMED_TRANSACTIONS: usize = 8; @@ -149,9 +204,10 @@ impl> VM { fn atomic_speculate<'a>( &self, state: FinalizeGlobalState, + time_since_last_block: i64, coinbase_reward: Option, ratifications: Vec>, - solutions: Option<&CoinbaseSolution>, + solutions: &Solutions, transactions: impl ExactSizeIterator>, ) -> Result<( Ratifications, @@ -166,11 +222,22 @@ impl> VM { let timer = timer!("VM::atomic_speculate"); + // Retrieve the number of solutions. + let num_solutions = solutions.len(); // Retrieve the number of transactions. let num_transactions = transactions.len(); // Perform the finalize operation on the preset finalize mode. atomic_finalize!(self.finalize_store(), FinalizeMode::DryRun, { + // Ensure the number of solutions does not exceed the maximum. + if num_solutions > Solutions::::MAX_ABORTED_SOLUTIONS { + // Note: This will abort the entire atomic batch. + return Err(format!( + "Too many solutions in the block - {num_solutions} (max: {})", + Solutions::::MAX_ABORTED_SOLUTIONS + )); + } + // Ensure the number of transactions does not exceed the maximum. if num_transactions > Transactions::::MAX_ABORTED_TRANSACTIONS { // Note: This will abort the entire atomic batch. @@ -182,12 +249,12 @@ impl> VM { // Initialize an iterator for ratifications before finalize. let pre_ratifications = ratifications.iter().filter(|r| match r { - Ratify::Genesis(_, _) => true, + Ratify::Genesis(_, _, _) => true, Ratify::BlockReward(..) | Ratify::PuzzleReward(..) => false, }); // Initialize an iterator for ratifications after finalize. let post_ratifications = ratifications.iter().filter(|r| match r { - Ratify::Genesis(_, _) => false, + Ratify::Genesis(_, _, _) => false, Ratify::BlockReward(..) | Ratify::PuzzleReward(..) => true, }); @@ -229,6 +296,8 @@ impl> VM { let mut output_ids: IndexSet> = IndexSet::new(); // Initialize the list of created transition public keys. let mut tpks: IndexSet> = IndexSet::new(); + // Initialize the list of deployment payers. + let mut deployment_payers: IndexSet> = IndexSet::new(); // Finalize the transactions. 'outer: for transaction in transactions { @@ -241,55 +310,19 @@ impl> VM { continue 'outer; } - // Ensure that the transaction is not producing a duplicate transition. - for transition_id in transaction.transition_ids() { - // If the transition ID is already produced in this block or previous blocks, abort the transaction. - if transition_ids.contains(transition_id) - || self.transition_store().contains_transition_id(transition_id).unwrap_or(true) - { - // Store the aborted transaction. - aborted.push((transaction.clone(), format!("Duplicate transition {transition_id}"))); - // Continue to the next transaction. - continue 'outer; - } - } - - // Ensure that the transaction is not double-spending an input. - for input_id in transaction.input_ids() { - // If the input ID is already spent in this block or previous blocks, abort the transaction. - if input_ids.contains(input_id) - || self.transition_store().contains_input_id(input_id).unwrap_or(true) - { - // Store the aborted transaction. - aborted.push((transaction.clone(), format!("Double-spending input {input_id}"))); - // Continue to the next transaction. - continue 'outer; - } - } - - // Ensure that the transaction is not producing a duplicate output. - for output_id in transaction.output_ids() { - // If the output ID is already produced in this block or previous blocks, abort the transaction. - if output_ids.contains(output_id) - || self.transition_store().contains_output_id(output_id).unwrap_or(true) - { - // Store the aborted transaction. - aborted.push((transaction.clone(), format!("Duplicate output {output_id}"))); - // Continue to the next transaction. - continue 'outer; - } - } - - // // Ensure that the transaction is not producing a duplicate transition public key. - // // Note that the tpk and tcm are corresponding, so a uniqueness check for just the tpk is sufficient. - for tpk in transaction.transition_public_keys() { - // If the transition public key is already produced in this block or previous blocks, abort the transaction. - if tpks.contains(tpk) || self.transition_store().contains_tpk(tpk).unwrap_or(true) { - // Store the aborted transaction. - aborted.push((transaction.clone(), format!("Duplicate transition public key {tpk}"))); - // Continue to the next transaction. - continue 'outer; - } + // Determine if the transaction should be aborted. + if let Some(reason) = self.should_abort_transaction( + transaction, + &transition_ids, + &input_ids, + &output_ids, + &tpks, + &deployment_payers, + ) { + // Store the aborted transaction. + aborted.push((transaction.clone(), reason)); + // Continue to the next transaction. + continue 'outer; } // Process the transaction in an isolated atomic batch. @@ -359,7 +392,10 @@ impl> VM { // The finalize operation here involves calling 'update_key_value', // and update the respective leaves of the finalize tree. Transaction::Execute(_, execution, fee) => { - match process.finalize_execution(state, store, execution, fee.as_ref()) { + // Determine if the transaction is safe for execution, and proceed to execute it. + match Self::prepare_for_execution(store, execution) + .and_then(|_| process.finalize_execution(state, store, execution, fee.as_ref())) + { // Construct the accepted execute transaction. Ok(finalize) => { ConfirmedTransaction::accepted_execute(counter, transaction.clone(), finalize) @@ -390,7 +426,10 @@ impl> VM { } } } + // This is a foundational bug - the caller is violating protocol rules. + // It is possible that a `credits.aleo/split` transaction has no fee. However, it + // is a simple transition without finalize operations and should not fail here. // Note: This will abort the entire atomic batch. None => Err("Rejected execute transaction has no fee".to_string()), }, @@ -413,6 +452,10 @@ impl> VM { output_ids.extend(confirmed_transaction.transaction().output_ids()); // Add the transition public keys to the set of produced transition public keys. tpks.extend(confirmed_transaction.transaction().transition_public_keys()); + // Add any public deployment payer to the set of deployment payers. + if let Transaction::Deploy(_, _, _, fee) = confirmed_transaction.transaction() { + fee.payer().map(|payer| deployment_payers.insert(payer)); + } // Store the confirmed transaction. confirmed.push(confirmed_transaction); // Increment the transaction index counter. @@ -450,9 +493,11 @@ impl> VM { }; // Compute the block reward. - let block_reward = ledger_block::block_reward( + let block_reward = ledger_block::block_reward::( + state.block_height(), N::STARTING_SUPPLY, N::BLOCK_TIME, + time_since_last_block, coinbase_reward, transaction_fees, ); @@ -468,7 +513,7 @@ impl> VM { let post_ratifications = reward_ratifications.iter().chain(post_ratifications); // Process the post-ratifications. - match Self::atomic_post_ratify(store, state, post_ratifications, solutions) { + match Self::atomic_post_ratify::(&self.puzzle, store, state, post_ratifications, solutions) { // Store the finalize operations from the post-ratify. Ok(operations) => ratified_finalize_operations.extend(operations), // Note: This will abort the entire atomic batch. @@ -500,7 +545,7 @@ impl> VM { &self, state: FinalizeGlobalState, ratifications: &Ratifications, - solutions: Option<&CoinbaseSolution>, + solutions: &Solutions, transactions: &Transactions, ) -> Result>> { // Acquire the atomic lock, which is needed to ensure this function is not called concurrently @@ -514,12 +559,12 @@ impl> VM { atomic_finalize!(self.finalize_store(), FinalizeMode::RealRun, { // Initialize an iterator for ratifications before finalize. let pre_ratifications = ratifications.iter().filter(|r| match r { - Ratify::Genesis(_, _) => true, + Ratify::Genesis(_, _, _) => true, Ratify::BlockReward(..) | Ratify::PuzzleReward(..) => false, }); // Initialize an iterator for ratifications after finalize. let post_ratifications = ratifications.iter().filter(|r| match r { - Ratify::Genesis(_, _) => false, + Ratify::Genesis(_, _, _) => false, Ratify::BlockReward(..) | Ratify::PuzzleReward(..) => true, }); @@ -712,7 +757,7 @@ impl> VM { /* Perform the ratifications after finalize. */ - match Self::atomic_post_ratify(store, state, post_ratifications, solutions) { + match Self::atomic_post_ratify::(&self.puzzle, store, state, post_ratifications, solutions) { // Store the finalize operations from the post-ratify. Ok(operations) => ratified_finalize_operations.extend(operations), // Note: This will abort the entire atomic batch. @@ -732,6 +777,234 @@ impl> VM { }) } + /// Returns `Some(reason)` if the transaction is aborted. Otherwise, returns `None`. + /// + /// The transaction will be aborted if any of the following conditions are met: + /// - The transaction is producing a duplicate transition + /// - The transaction is double-spending an input + /// - The transaction is producing a duplicate output + /// - The transaction is producing a duplicate transition public key + /// - The transaction is another deployment in the block from the same public fee payer. + fn should_abort_transaction( + &self, + transaction: &Transaction, + transition_ids: &IndexSet, + input_ids: &IndexSet>, + output_ids: &IndexSet>, + tpks: &IndexSet>, + deployment_payers: &IndexSet>, + ) -> Option { + // Ensure that the transaction is not producing a duplicate transition. + for transition_id in transaction.transition_ids() { + // If the transition ID is already produced in this block or previous blocks, abort the transaction. + if transition_ids.contains(transition_id) + || self.transition_store().contains_transition_id(transition_id).unwrap_or(true) + { + return Some(format!("Duplicate transition {transition_id}")); + } + } + + // Ensure that the transaction is not double-spending an input. + for input_id in transaction.input_ids() { + // If the input ID is already spent in this block or previous blocks, abort the transaction. + if input_ids.contains(input_id) || self.transition_store().contains_input_id(input_id).unwrap_or(true) { + return Some(format!("Double-spending input {input_id}")); + } + } + + // Ensure that the transaction is not producing a duplicate output. + for output_id in transaction.output_ids() { + // If the output ID is already produced in this block or previous blocks, abort the transaction. + if output_ids.contains(output_id) || self.transition_store().contains_output_id(output_id).unwrap_or(true) { + return Some(format!("Duplicate output {output_id}")); + } + } + + // Ensure that the transaction is not producing a duplicate transition public key. + // Note that the tpk and tcm are corresponding, so a uniqueness check for just the tpk is sufficient. + for tpk in transaction.transition_public_keys() { + // If the transition public key is already produced in this block or previous blocks, abort the transaction. + if tpks.contains(tpk) || self.transition_store().contains_tpk(tpk).unwrap_or(true) { + return Some(format!("Duplicate transition public key {tpk}")); + } + } + + // If the transaction is a deployment, ensure that it is not another deployment in the block from the same public fee payer. + if let Transaction::Deploy(_, _, _, fee) = transaction { + // If any public deployment payer has already deployed in this block, abort the transaction. + if let Some(payer) = fee.payer() { + if deployment_payers.contains(&payer) { + return Some(format!("Another deployment in the block from the same public fee payer {payer}")); + } + } + } + + // Return `None` because the transaction is well-formed. + None + } + + /// Performs precondition checks on the transactions prior to speculation. + /// + /// This method is used to check the following conditions: + /// - If a transaction is a fee transaction or if it is invalid, + /// then the transaction will be aborted. + pub(crate) fn prepare_for_speculate<'a, R: CryptoRng + Rng>( + &self, + transactions: &[&'a Transaction], + rng: &mut R, + ) -> Result<(Vec<&'a Transaction>, Vec<(&'a Transaction, String)>)> { + // Construct the list of transactions that need to verified. + let mut transactions_to_verify = Vec::with_capacity(transactions.len()); + // Construct the list of valid and invalid transactions. + let mut valid_transactions = Vec::with_capacity(transactions.len()); + let mut aborted_transactions = Vec::with_capacity(transactions.len()); + + // Initialize a list of created transition IDs. + let mut transition_ids: IndexSet = Default::default(); + // Initialize a list of spent input IDs. + let mut input_ids: IndexSet> = Default::default(); + // Initialize a list of created output IDs. + let mut output_ids: IndexSet> = Default::default(); + // Initialize the list of created transition public keys. + let mut tpks: IndexSet> = Default::default(); + // Initialize the list of deployment payers. + let mut deployment_payers: IndexSet> = Default::default(); + + // Abort the transactions that are have duplicates or are invalid. This will prevent the VM from performing + // verification on transactions that would have been aborted in `VM::atomic_speculate`. + for transaction in transactions.iter() { + // Abort the transaction early if it is a fee transaction. + if transaction.is_fee() { + aborted_transactions.push((*transaction, "Fee transactions are not allowed in speculate".to_string())); + continue; + } + + // Determine if the transaction should be aborted. + match self.should_abort_transaction( + transaction, + &transition_ids, + &input_ids, + &output_ids, + &tpks, + &deployment_payers, + ) { + // Store the aborted transaction. + Some(reason) => aborted_transactions.push((*transaction, reason.to_string())), + // Track the transaction state. + None => { + // Add the transition IDs to the set of produced transition IDs. + transition_ids.extend(transaction.transition_ids()); + // Add the input IDs to the set of spent input IDs. + input_ids.extend(transaction.input_ids()); + // Add the output IDs to the set of produced output IDs. + output_ids.extend(transaction.output_ids()); + // Add the transition public keys to the set of produced transition public keys. + tpks.extend(transaction.transition_public_keys()); + // Add any public deployment payer to the set of deployment payers. + if let Transaction::Deploy(_, _, _, fee) = transaction { + fee.payer().map(|payer| deployment_payers.insert(payer)); + } + + // Add the transaction to the list of transactions to verify. + transactions_to_verify.push(transaction); + } + }; + } + + // Separate the transactions into deploys and executions. + let (deployments, executions): (Vec<&Transaction>, Vec<&Transaction>) = + transactions_to_verify.into_iter().partition(|tx| tx.is_deploy()); + // Chunk the deploys and executions into groups for parallel verification. + let deployments_for_verification = deployments.chunks(Self::MAX_PARALLEL_DEPLOY_VERIFICATIONS); + let executions_for_verification = executions.chunks(Self::MAX_PARALLEL_EXECUTE_VERIFICATIONS); + + // Verify the transactions in batches and separate the valid and invalid transactions. + for transactions in deployments_for_verification.chain(executions_for_verification) { + let rngs = (0..transactions.len()).map(|_| StdRng::from_seed(rng.gen())).collect::>(); + // Verify the transactions and collect the error message if there is one. + let (valid, invalid): (Vec<_>, Vec<_>) = + cfg_into_iter!(transactions).zip(rngs).partition_map(|(transaction, mut rng)| { + // Verify the transaction. + match self.check_transaction(transaction, None, &mut rng) { + // If the transaction is valid, add it to the list of valid transactions. + Ok(_) => Either::Left(*transaction), + // If the transaction is invalid, add it to the list of aborted transactions. + Err(e) => Either::Right((*transaction, e.to_string())), + } + }); + + // Collect the valid and aborted transactions. + valid_transactions.extend(valid); + aborted_transactions.extend(invalid); + } + + // Sort the valid and aborted transactions based on their position in the original list. + let position: IndexSet<_> = transactions.iter().map(|tx| tx.id()).collect(); + cfg_sort_by_cached_key!(valid_transactions, |tx| position.get_index_of(&tx.id())); + cfg_sort_by_cached_key!(aborted_transactions, |tx| position.get_index_of(&tx.0.id())); + + // Return the valid and invalid transactions. + Ok((valid_transactions, aborted_transactions)) + } + + /// Performs precondition checks on the transaction prior to execution. + /// + /// This method is used to check the following conditions: + /// - If the transaction contains a `credits.aleo/bond_public` transition, + /// then the outcome should not exceed the maximum committee size. + #[inline] + fn prepare_for_execution(store: &FinalizeStore, execution: &Execution) -> Result<()> { + // Construct the program ID. + let program_id = ProgramID::from_str("credits.aleo")?; + // Construct the committee mapping name. + let committee_mapping = Identifier::from_str("committee")?; + + // Check if the execution has any `bond_validator` transitions, and collect + // the unique validator addresses if so. + // Note: This does not dedup for existing and new validator addresses. + let bond_validator_addresses: HashSet<_> = execution + .transitions() + .filter_map(|transition| match transition.is_bond_validator() { + // Get the first argument of the transition output if it is a `Future` with a `Plaintext` argument. + true => match transition.outputs().first() { + Some(Output::Future(_, Some(future))) => future.arguments().first().and_then(|arg| match arg { + Argument::Plaintext(Plaintext::Literal(Literal::Address(address), _)) => Some(*address), + _ => None, + }), + _ => None, + }, + false => None, + }) + .collect(); + + // Check if we need to reject the execution if the number of new validators exceeds the maximum committee size. + match bond_validator_addresses.is_empty() { + false => { + // Retrieve the committee members from storage. + let committee_members = store + .get_mapping_speculative(program_id, committee_mapping)? + .into_iter() + .map(|(key, _)| match key { + // Extract the address from the key. + Plaintext::Literal(Literal::Address(address), _) => Ok(address), + _ => Err(anyhow!("Invalid committee key (missing address) - {key}")), + }) + .collect::>>()?; + // Get the number of new validators being bonded to. + let num_new_validators = + bond_validator_addresses.into_iter().filter(|address| !committee_members.contains(address)).count(); + // Compute the next committee size. + let next_committee_size = committee_members.len().saturating_add(num_new_validators); + // Check that the number of new validators being bonded does not exceed the maximum number of validators. + match next_committee_size > Committee::::MAX_COMMITTEE_SIZE as usize { + true => Err(anyhow!("Call to 'credits.aleo/bond_public' exceeds the committee size")), + false => Ok(()), + } + } + true => Ok(()), + } + } + /// Performs the pre-ratifications before finalizing transactions. #[inline] fn atomic_pre_ratify<'a>( @@ -743,10 +1016,16 @@ impl> VM { let program_id = ProgramID::from_str("credits.aleo")?; // Construct the committee mapping name. let committee_mapping = Identifier::from_str("committee")?; + // Construct the delegated mapping name. + let delegated_mapping: Identifier = Identifier::from_str("delegated")?; // Construct the bonded mapping name. let bonded_mapping = Identifier::from_str("bonded")?; // Construct the account mapping name. let account_mapping = Identifier::from_str("account")?; + // Construct the metadata mapping name. + let metadata_mapping = Identifier::from_str("metadata")?; + // Construct the withdraw mapping name. + let withdraw_mapping = Identifier::from_str("withdraw")?; // Initialize a list of finalize operations. let mut finalize_operations = Vec::new(); @@ -757,7 +1036,7 @@ impl> VM { // Iterate over the ratifications. for ratify in pre_ratifications { match ratify { - Ratify::Genesis(committee, public_balances) => { + Ratify::Genesis(committee, public_balances, bonded_balances) => { // Ensure this is the genesis block. ensure!(state.block_height() == 0, "Ratify::Genesis(..) expected a genesis block"); // Ensure the genesis committee round is 0. @@ -765,6 +1044,16 @@ impl> VM { committee.starting_round() == 0, "Ratify::Genesis(..) expected a genesis committee round of 0" ); + // Ensure that the number of members in the committee does not exceed the maximum. + ensure!( + committee.members().len() <= Committee::::MAX_COMMITTEE_SIZE as usize, + "Ratify::Genesis(..) exceeds the maximum number of committee members" + ); + // Ensure that the number of delegators does not exceed the maximum. + ensure!( + bonded_balances.len().saturating_sub(committee.members().len()) <= MAX_DELEGATORS as usize, + "Ratify::Genesis(..) exceeds the maximum number of delegators" + ); // Ensure genesis has not been ratified yet. ensure!(!is_genesis_ratified, "Ratify::Genesis(..) has already been ratified"); @@ -780,46 +1069,139 @@ impl> VM { // } // } - // Initialize the stakers. - let mut stakers = IndexMap::with_capacity(committee.members().len()); - // Iterate over the committee members. - for (validator, (microcredits, _)) in committee.members() { - // Insert the validator into the stakers. - stakers.insert(*validator, (*validator, *microcredits)); + // Calculate the stake per validator using `bonded_balances`. + // + // Note: There is no need to check the `delegated` mapping in the genesis block, + // because the design of `bonded_balances` by definition does not support + // delegating to a non-bonded validator. Thus, the assumption is that the + // `delegated` mapping will be correct by construction. + let mut stake_per_validator = IndexMap::with_capacity(committee.members().len()); + for (address, (validator_address, _, amount)) in bonded_balances.iter() { + // Check that the amount meets the minimum requirement, depending on whether the address is a validator. + if *address == *validator_address { + ensure!( + *amount >= MIN_VALIDATOR_SELF_STAKE, + "Ratify::Genesis(..) the validator {address} must stake at least {MIN_VALIDATOR_SELF_STAKE}", + ); + } else { + ensure!( + *amount >= MIN_DELEGATOR_STAKE, + "Ratify::Genesis(..) the delegator {address} must stake at least {MIN_DELEGATOR_STAKE}", + ); + // If the corresponding validator is not a committee member yet, then continue. + if !committee.is_committee_member(*validator_address) { + continue; + } + // If the address is a delegator, check that the corresponding validator is open. + ensure!( + committee.is_committee_member_open(*validator_address), + "Ratify::Genesis(..) the delegator {address} is delegating to a closed validator {validator_address}", + ); + } + // Accumulate the staked amount per validator. + let total = stake_per_validator.entry(validator_address).or_insert(0u64); + *total = total.saturating_add(*amount); } + // Ensure the stake per validator matches the committee. + ensure!( + stake_per_validator.len() == committee.members().len(), + "Ratify::Genesis(..) the number of validators in the committee does not match the number of validators in the bonded balances", + ); + + // Check that `committee` is consistent with `stake_per_validator`. + for (validator_address, amount) in &stake_per_validator { + // Retrieve the expected validator stake from the committee. + let Some((expected_amount, _, _)) = committee.members().get(*validator_address) else { + bail!( + "Ratify::Genesis(..) found a validator in the bonded balances that is not in the committee" + ) + }; + // Ensure the staked amount matches the committee. + ensure!( + *expected_amount == *amount, + "Ratify::Genesis(..) inconsistent staked amount for validator {validator_address}", + ); + } + // Ensure that the total stake matches the sum of the staked amounts. + ensure!( + committee.total_stake() == stake_per_validator.values().sum::(), + "Ratify::Genesis(..) incorrect total total stake for the committee" + ); + + // Split the bonded balances into stakers and withdrawal addresses. + let (next_stakers, withdrawal_addresses) = bonded_balances.iter().fold( + ( + IndexMap::with_capacity(bonded_balances.len()), + IndexMap::with_capacity(bonded_balances.len()), + ), + |(mut stakers, mut withdrawal_addresses), (staker, (validator, withdrawal_address, amount))| { + stakers.insert(*staker, (*validator, *amount)); + withdrawal_addresses.insert(*staker, *withdrawal_address); + (stakers, withdrawal_addresses) + }, + ); + + let next_delegated = to_next_delegated(&next_stakers); // Construct the next committee map and next bonded map. - let (next_committee_map, next_bonded_map) = - to_next_commitee_map_and_bonded_map(committee, &stakers); + let (next_committee_map, next_bonded_map, next_delegated_map) = + to_next_committee_bonded_delegated_map(committee, &next_stakers, &next_delegated); + + // Construct the next withdraw map. + let next_withdraw_map = to_next_withdraw_map(&withdrawal_addresses); // Insert the next committee into storage. - store.committee_store().insert(state.block_height(), committee.clone())?; + store.committee_store().insert(state.block_height(), *(committee.clone()))?; // Store the finalize operations for updating the committee and bonded mapping. finalize_operations.extend(&[ // Replace the committee mapping in storage. store.replace_mapping(program_id, committee_mapping, next_committee_map)?, + // Replace the delegated mapping in storage. + store.replace_mapping(program_id, delegated_mapping, next_delegated_map)?, // Replace the bonded mapping in storage. store.replace_mapping(program_id, bonded_mapping, next_bonded_map)?, + // Replace the withdraw mapping in storage. + store.replace_mapping(program_id, withdraw_mapping, next_withdraw_map)?, ]); - // Iterate over the public balances. - for (address, amount) in public_balances { - // Construct the key. - let key = Plaintext::from(Literal::Address(*address)); - // Retrieve the current public balance. - let value = store.get_value_speculative(program_id, account_mapping, &key)?; - // Compute the next public balance. - let next_value = Value::from(Literal::U64(U64::new(match value { - Some(Value::Plaintext(Plaintext::Literal(Literal::U64(value), _))) => { - (*value).saturating_add(*amount) - } - None => *amount, - v => bail!("Critical bug in pre-ratify - Invalid public balance type ({v:?})"), - }))); - // Update the public balance in finalize storage. - let operation = store.update_key_value(program_id, account_mapping, key, next_value)?; - finalize_operations.push(operation); - } + // Update the number of validators. + finalize_operations.extend(&[ + // Update the number of validators in the metadata mapping. + store.update_key_value( + program_id, + metadata_mapping, + Plaintext::from_str("aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc")?, + Value::from_str(&format!("{}u32", committee.num_members()))?, + )?, + ]); + + // Update the number of delegators. + finalize_operations.extend(&[ + // Update the number of delegators in the metadata mapping. + store.update_key_value( + program_id, + metadata_mapping, + Plaintext::from_str("aleo1qgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqanmpl0")?, + Value::from_str(&format!( + "{}u32", + bonded_balances.len().saturating_sub(committee.num_members()) + ))?, + )?, + ]); + + // Map the public balances into the appropriate format. + let public_balances = public_balances + .iter() + .map(|(address, amount)| { + (Plaintext::from(Literal::Address(*address)), Value::from(Literal::U64(U64::new(*amount)))) + }) + .collect::>(); + + // Update the public balances. + finalize_operations.extend(&[ + // Update the public balances in storage. + store.replace_mapping(program_id, account_mapping, public_balances)?, + ]); // Set the genesis ratification flag. is_genesis_ratified = true; @@ -834,16 +1216,19 @@ impl> VM { /// Performs the post-ratifications after finalizing transactions. #[inline] - fn atomic_post_ratify<'a>( + fn atomic_post_ratify<'a, const IS_FINALIZE: bool>( + puzzle: &Puzzle, store: &FinalizeStore, state: FinalizeGlobalState, post_ratifications: impl Iterator>, - solutions: Option<&CoinbaseSolution>, + solutions: &Solutions, ) -> Result>> { // Construct the program ID. let program_id = ProgramID::from_str("credits.aleo")?; // Construct the committee mapping name. let committee_mapping = Identifier::from_str("committee")?; + // Construct the delegated mapping name. + let delegated_mapping = Identifier::from_str("delegated")?; // Construct the bonded mapping name. let bonded_mapping = Identifier::from_str("bonded")?; // Construct the account mapping name. @@ -867,8 +1252,14 @@ impl> VM { // Retrieve the committee mapping from storage. let current_committee_map = store.get_mapping_speculative(program_id, committee_mapping)?; + // Retrieve the delegator mapping from storage. + let current_delegator_map = store.get_mapping_speculative(program_id, delegated_mapping)?; // Convert the committee mapping into a committee. - let current_committee = committee_map_into_committee(state.block_round(), current_committee_map)?; + let current_committee = committee_and_delegated_maps_into_committee( + state.block_round(), + current_committee_map, + current_delegator_map, + )?; // Retrieve the bonded mapping from storage. let current_bonded_map = store.get_mapping_speculative(program_id, bonded_mapping)?; // Convert the bonded map into stakers. @@ -879,18 +1270,56 @@ impl> VM { // Compute the updated stakers, using the committee and block reward. let next_stakers = staking_rewards(¤t_stakers, ¤t_committee, *block_reward); - // Compute the updated committee, using the stakers. - let next_committee = to_next_committee(¤t_committee, state.block_round(), &next_stakers)?; - // Construct the next committee map and next bonded map. - let (next_committee_map, next_bonded_map) = - to_next_commitee_map_and_bonded_map(&next_committee, &next_stakers); + + // Compute the updated delegated amounts, using the next_stakers updated amounts. + let next_delegated = to_next_delegated(&next_stakers); + + // Compute the updated committee, using the delegatees. + let next_committee = to_next_committee(¤t_committee, state.block_round(), &next_delegated)?; + + // Construct the next committee map, the next bonded map, and the next delegated map. + let (next_committee_map, next_bonded_map, next_delegated_map) = + to_next_committee_bonded_delegated_map(&next_committee, &next_stakers, &next_delegated); // Insert the next committee into storage. store.committee_store().insert(state.block_height(), next_committee)?; + + #[cfg(all(feature = "history", feature = "rocks"))] + { + // When finalizing in `FinalizeMode::RealRun`, store the delegated and bonded mappings in history. + if IS_FINALIZE { + // Load a `History` object. + let history = History::new(N::ID, store.storage_mode()); + + // Write the delegated mapping as JSON. + history.store_mapping(state.block_height(), MappingName::Delegated, &next_delegated_map)?; + + // Write the bonded mapping as JSON. + history.store_mapping(state.block_height(), MappingName::Bonded, &next_bonded_map)?; + + // Write the metadata mapping as JSON. + let metadata_mapping = Identifier::from_str("metadata")?; + let metadata_map = store.get_mapping_speculative(program_id, metadata_mapping)?; + history.store_mapping(state.block_height(), MappingName::Metadata, &metadata_map)?; + + // Write the unbonding mapping as JSON. + let unbonding_mapping = Identifier::from_str("unbonding")?; + let unbonding_map = store.get_mapping_speculative(program_id, unbonding_mapping)?; + history.store_mapping(state.block_height(), MappingName::Unbonding, &unbonding_map)?; + + // Write the withdraw mapping as JSON. + let withdraw_mapping = Identifier::from_str("withdraw")?; + let withdraw_map = store.get_mapping_speculative(program_id, withdraw_mapping)?; + history.store_mapping(state.block_height(), MappingName::Withdraw, &withdraw_map)?; + } + } + // Store the finalize operations for updating the committee and bonded mapping. finalize_operations.extend(&[ // Replace the committee mapping in storage. store.replace_mapping(program_id, committee_mapping, next_committee_map)?, + // Replace the delegated mapping in storage. + store.replace_mapping(program_id, delegated_mapping, next_delegated_map)?, // Replace the bonded mapping in storage. store.replace_mapping(program_id, bonded_mapping, next_bonded_map)?, ]); @@ -907,12 +1336,14 @@ impl> VM { continue; } // Retrieve the solutions. - let Some(solutions) = solutions else { + let Some(solutions) = solutions.deref() else { continue; }; // Compute the proof targets, with the corresponding addresses. - let proof_targets = - solutions.values().map(|s| Ok((s.address(), s.to_target()?))).collect::>>()?; + let proof_targets = solutions + .values() + .map(|s| Ok((s.address(), puzzle.get_proof_target(s)?))) + .collect::>>()?; // Calculate the proving rewards. let proving_rewards = proving_rewards(proof_targets, *puzzle_reward); // Iterate over the proving rewards. @@ -948,13 +1379,17 @@ impl> VM { #[cfg(test)] mod tests { use super::*; - use crate::vm::{test_helpers, test_helpers::sample_finalize_state}; + use crate::vm::{ + test_helpers, + test_helpers::{sample_finalize_state, sample_vm}, + }; use console::{ account::{Address, PrivateKey, ViewKey}, program::{Ciphertext, Entry, Record}, types::Field, }; use ledger_block::{Block, Header, Metadata, Transaction, Transition}; + use ledger_committee::{MAX_DELEGATORS, MIN_VALIDATOR_STAKE}; use ledger_store::helpers::memory::ConsensusMemory; use synthesizer_program::Program; @@ -1040,8 +1475,16 @@ finalize transfer_public: rng: &mut R, ) -> Result> { // Speculate on the candidate ratifications, solutions, and transactions. - let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = - vm.speculate(sample_finalize_state(1), None, vec![], None, transactions.iter())?; + let time_since_last_block = CurrentNetwork::BLOCK_TIME as i64; + let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = vm.speculate( + sample_finalize_state(previous_block.height() + 1), + time_since_last_block, + None, + vec![], + &None.into(), + transactions.iter(), + rng, + )?; // Construct the metadata associated with the block. let metadata = Metadata::new( @@ -1054,7 +1497,7 @@ finalize transfer_public: CurrentNetwork::GENESIS_PROOF_TARGET, previous_block.last_coinbase_target(), previous_block.last_coinbase_timestamp(), - CurrentNetwork::GENESIS_TIMESTAMP + 1, + previous_block.timestamp().saturating_add(time_since_last_block), )?; // Construct the new block header. @@ -1073,7 +1516,8 @@ finalize transfer_public: previous_block.hash(), header, ratifications, - None, + None.into(), + vec![], transactions, aborted_transaction_ids, rng, @@ -1210,6 +1654,90 @@ finalize transfer_public: } } + /// Samples the validators. + fn sample_validators( + num_validators: usize, + rng: &mut TestRng, + ) -> IndexMap, (u64, bool, u8)> { + (0..num_validators) + .map(|_| { + let private_key = PrivateKey::new(rng).unwrap(); + let amount = MIN_VALIDATOR_STAKE; + let is_open = true; + let commission: u8 = 0; + (private_key, (amount, is_open, commission)) + }) + .collect::>() + } + + /// Returns a `committee_map` and the `allocated_amount` given the validators and delegators. + fn sample_committee_map_and_allocated_amount( + validators: &IndexMap, (u64, bool, u8)>, + delegators: &IndexMap, (Address, u64)>, + ) -> (IndexMap, (u64, bool, u8)>, u64) { + // Reset the tracked amount. + let mut allocated_amount = 0; + + // Construct the **correct** committee. + let mut committee_map = IndexMap::new(); + for (private_key, (amount, is_open, commission)) in validators { + let address = Address::try_from(private_key).unwrap(); + committee_map.insert(address, (*amount, *is_open, *commission)); + allocated_amount += amount; + } + for (delegator, (validator, amount)) in delegators { + if let indexmap::map::Entry::Occupied(mut entry) = committee_map.entry(*validator) { + let (current_amount, is_open, commission) = entry.get(); + // Ensure the validator is open. + assert!(*is_open, "delegator {delegator} is delegating {amount} microcredits to a closed validator"); + // Update the committee map. + entry.insert((current_amount + amount, *is_open, *commission)); + } else { + unreachable!("delegator {delegator} is delegating to a closed validator") + } + // Accumulate the allocated amount. + allocated_amount += amount; + } + + (committee_map, allocated_amount) + } + + /// Returns the `bonded_balances` given the validators and delegators. + /// Note that the withdrawal address is the same as the staker address. + fn sample_bonded_balances( + validators: &IndexMap, (u64, bool, u8)>, + delegators: &IndexMap, (Address, u64)>, + ) -> IndexMap, (Address, Address, u64)> { + let mut bonded_balances = IndexMap::with_capacity(validators.len() + delegators.len()); + for (private_key, (amount, _, _)) in validators { + let address = Address::try_from(private_key).unwrap(); + bonded_balances.insert(address, (address, address, *amount)); + } + for (private_key, (validator, amount)) in delegators { + let address = Address::try_from(private_key).unwrap(); + bonded_balances.insert(address, (*validator, address, *amount)); + } + bonded_balances + } + + /// Returns the `public_balances` given the addresses and total amount. + /// Note that the balances are evenly distributed among the addresses. + fn sample_public_balances(addresses: &[Address], total_amount: u64) -> IndexMap, u64> { + // Check that the addresses are not empty. + assert!(!addresses.is_empty(), "must provide at least one address"); + // Distribute the total amount evenly among the addresses. + let amount_per_address = total_amount / addresses.len() as u64; + let mut public_balances: IndexMap<_, _> = + addresses.iter().map(|address| (*address, amount_per_address)).collect(); + // Distribute the remainder to the first address. + let remaining = total_amount % addresses.len() as u64; + if remaining > 0 { + *public_balances.get_mut(&addresses[0]).unwrap() += remaining; + } + // Return the public balances. + public_balances + } + #[test] fn test_finalize_duplicate_deployment() { let rng = &mut TestRng::default(); @@ -1225,7 +1753,15 @@ finalize transfer_public: // Prepare the confirmed transactions. let (ratifications, confirmed_transactions, aborted_transaction_ids, _) = vm - .speculate(sample_finalize_state(1), None, vec![], None, [deployment_transaction.clone()].iter()) + .speculate( + sample_finalize_state(1), + CurrentNetwork::BLOCK_TIME as i64, + None, + vec![], + &None.into(), + [deployment_transaction.clone()].iter(), + rng, + ) .unwrap(); assert_eq!(confirmed_transactions.len(), 1); assert!(aborted_transaction_ids.is_empty()); @@ -1234,28 +1770,131 @@ finalize transfer_public: assert!(!vm.contains_program(&program_id)); // Finalize the transaction. - assert!(vm.finalize(sample_finalize_state(1), &ratifications, None, &confirmed_transactions).is_ok()); + assert!(vm.finalize(sample_finalize_state(1), &ratifications, &None.into(), &confirmed_transactions).is_ok()); // Ensure the VM contains this program. assert!(vm.contains_program(&program_id)); // Ensure the VM can't redeploy the same transaction. - assert!(vm.finalize(sample_finalize_state(1), &ratifications, None, &confirmed_transactions).is_err()); + assert!(vm.finalize(sample_finalize_state(1), &ratifications, &None.into(), &confirmed_transactions).is_err()); // Ensure the VM contains this program. assert!(vm.contains_program(&program_id)); // Ensure the dry run of the redeployment will cause a reject transaction to be created. - let (_, candidate_transactions, aborted_transaction_ids, _) = - vm.atomic_speculate(sample_finalize_state(1), None, vec![], None, [deployment_transaction].iter()).unwrap(); + let (_, candidate_transactions, aborted_transaction_ids, _) = vm + .atomic_speculate( + sample_finalize_state(1), + CurrentNetwork::BLOCK_TIME as i64, + None, + vec![], + &None.into(), + [deployment_transaction].iter(), + ) + .unwrap(); assert_eq!(candidate_transactions.len(), 1); assert!(matches!(candidate_transactions[0], ConfirmedTransaction::RejectedDeploy(..))); assert!(aborted_transaction_ids.is_empty()); - // Check that the unconfirmed transaction id of the rejected deployment is correct. + // Check that the unconfirmed transaction ID of the rejected deployment is correct. assert_eq!(candidate_transactions[0].to_unconfirmed_transaction_id().unwrap(), deployment_transaction_id); } + #[test] + fn test_bond_validator_above_maximum_fails() { + // Initialize an RNG. + let rng = &mut TestRng::default(); + + // Initialize the VM. + let vm = sample_vm(); + + // Initialize the validators with the maximum number of validators. + let validators = + sample_validators::(Committee::::MAX_COMMITTEE_SIZE as usize, rng); + + // Initialize a new address. + let new_validator_private_key = PrivateKey::::new(rng).unwrap(); + let new_validator_address = Address::try_from(&new_validator_private_key).unwrap(); + + // Construct the committee. + // Track the allocated amount. + let (committee_map, allocated_amount) = + sample_committee_map_and_allocated_amount(&validators, &IndexMap::new()); + + // Collect all of the addresses in a single place + let validator_addresses = + validators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(); + + // Construct the public balances, allocating the remaining supply. + let new_validator_balance = MIN_VALIDATOR_STAKE + 100_000_000; + let mut public_balances = sample_public_balances( + &validator_addresses, + ::STARTING_SUPPLY - allocated_amount - new_validator_balance, + ); + // Set the public balance of the new validator to the minimum validator stake. + public_balances.insert(new_validator_address, new_validator_balance); + + // Construct the bonded balances. + let bonded_balances = sample_bonded_balances(&validators, &IndexMap::new()); + + // Construct the genesis block, which should pass. + let block = vm + .genesis_quorum( + validators.keys().next().unwrap(), + Committee::new_genesis(committee_map).unwrap(), + public_balances, + bonded_balances, + rng, + ) + .unwrap(); + + // Add the block. + vm.add_next_block(&block).unwrap(); + + // Attempt to bond a new validator above the maximum number of validators. + let inputs = vec![ + Value::::from_str(&validator_addresses.first().unwrap().to_string()).unwrap(), // Withdrawal address + Value::::from_str(&format!("{MIN_VALIDATOR_STAKE}u64")).unwrap(), // Amount + Value::::from_str("42u8").unwrap(), // Commission + ]; + + // Execute. + let bond_validator_transaction = vm + .execute( + &new_validator_private_key, + ("credits.aleo", "bond_validator"), + inputs.into_iter(), + None, + 1, + None, + rng, + ) + .unwrap(); + + // Verify. + vm.check_transaction(&bond_validator_transaction, None, rng).unwrap(); + + // Speculate on the transactions. + let transactions = [bond_validator_transaction.clone()]; + let (_, confirmed_transactions, _, _) = vm + .atomic_speculate( + sample_finalize_state(1), + CurrentNetwork::BLOCK_TIME as i64, + None, + vec![], + &None.into(), + transactions.iter(), + ) + .unwrap(); + + // Assert that the transaction is rejected. + assert_eq!(confirmed_transactions.len(), 1); + assert_eq!( + confirmed_transactions[0], + reject(0, &bond_validator_transaction, confirmed_transactions[0].finalize_operations()) + ); + } + #[test] fn test_atomic_finalize_many() { let rng = &mut TestRng::default(); @@ -1348,8 +1987,16 @@ finalize transfer_public: // Transfer_20 -> Balance = 20 - 20 = 0 { let transactions = [mint_10.clone(), transfer_10.clone(), transfer_20.clone()]; - let (_, confirmed_transactions, aborted_transaction_ids, _) = - vm.atomic_speculate(sample_finalize_state(1), None, vec![], None, transactions.iter()).unwrap(); + let (_, confirmed_transactions, aborted_transaction_ids, _) = vm + .atomic_speculate( + sample_finalize_state(1), + CurrentNetwork::BLOCK_TIME as i64, + None, + vec![], + &None.into(), + transactions.iter(), + ) + .unwrap(); // Assert that all the transactions are accepted. assert_eq!(confirmed_transactions.len(), 3); @@ -1368,8 +2015,16 @@ finalize transfer_public: // Transfer_30 -> Balance = 30 - 30 = 0 { let transactions = [transfer_20.clone(), mint_10.clone(), mint_20.clone(), transfer_30.clone()]; - let (_, confirmed_transactions, aborted_transaction_ids, _) = - vm.atomic_speculate(sample_finalize_state(1), None, vec![], None, transactions.iter()).unwrap(); + let (_, confirmed_transactions, aborted_transaction_ids, _) = vm + .atomic_speculate( + sample_finalize_state(1), + CurrentNetwork::BLOCK_TIME as i64, + None, + vec![], + &None.into(), + transactions.iter(), + ) + .unwrap(); // Assert that all the transactions are accepted. assert_eq!(confirmed_transactions.len(), 4); @@ -1388,8 +2043,16 @@ finalize transfer_public: // Transfer_10 -> Balance = 0 - 10 = -10 (should be rejected) { let transactions = [transfer_20.clone(), transfer_10.clone()]; - let (_, confirmed_transactions, aborted_transaction_ids, _) = - vm.atomic_speculate(sample_finalize_state(1), None, vec![], None, transactions.iter()).unwrap(); + let (_, confirmed_transactions, aborted_transaction_ids, _) = vm + .atomic_speculate( + sample_finalize_state(1), + CurrentNetwork::BLOCK_TIME as i64, + None, + vec![], + &None.into(), + transactions.iter(), + ) + .unwrap(); // Assert that the accepted and rejected transactions are correct. assert_eq!(confirmed_transactions.len(), 2); @@ -1412,8 +2075,16 @@ finalize transfer_public: // Transfer_10 -> Balance = 10 - 10 = 0 { let transactions = [mint_20.clone(), transfer_30.clone(), transfer_20.clone(), transfer_10.clone()]; - let (_, confirmed_transactions, aborted_transaction_ids, _) = - vm.atomic_speculate(sample_finalize_state(1), None, vec![], None, transactions.iter()).unwrap(); + let (_, confirmed_transactions, aborted_transaction_ids, _) = vm + .atomic_speculate( + sample_finalize_state(1), + CurrentNetwork::BLOCK_TIME as i64, + None, + vec![], + &None.into(), + transactions.iter(), + ) + .unwrap(); // Assert that the accepted and rejected transactions are correct. assert_eq!(confirmed_transactions.len(), 4); @@ -1511,8 +2182,17 @@ function ped_hash: create_execution(&vm, caller_private_key, program_id, "ped_hash", inputs, &mut unspent_records, rng); // Speculatively execute the transaction. Ensure that this call does not panic and returns a rejected transaction. - let (_, confirmed_transactions, aborted_transaction_ids, _) = - vm.speculate(sample_finalize_state(1), None, vec![], None, [transaction.clone()].iter()).unwrap(); + let (_, confirmed_transactions, aborted_transaction_ids, _) = vm + .speculate( + sample_finalize_state(1), + CurrentNetwork::BLOCK_TIME as i64, + None, + vec![], + &None.into(), + [transaction.clone()].iter(), + rng, + ) + .unwrap(); assert!(aborted_transaction_ids.is_empty()); // Ensure that the transaction is rejected. @@ -1627,11 +2307,6 @@ finalize compute: // Check that the storage was not updated. let program_id = ProgramID::from_str("testing.aleo").unwrap(); let mapping_name = Identifier::from_str("entries").unwrap(); - let value = vm - .finalize_store() - .get_value_speculative(program_id, mapping_name, &Plaintext::from(Literal::Address(address))) - .unwrap(); - println!("{:?}", value); assert!( !vm.finalize_store() .contains_key_confirmed(program_id, mapping_name, &Plaintext::from(Literal::Address(address))) @@ -1736,4 +2411,953 @@ finalize compute: VM::>::MAXIMUM_CONFIRMED_TRANSACTIONS ); } + + #[test] + fn test_ratify_genesis_greater_than_max_committee_size() { + // Initialize an RNG. + let rng = &mut TestRng::default(); + + // Initialize the VM. + let vm = sample_vm(); + + // Construct the validators, greater than the maximum committee size. + let validators = + sample_validators::(Committee::::MAX_COMMITTEE_SIZE as usize + 1, rng); + + // Construct the committee. + let mut committee_map = IndexMap::new(); + for (private_key, (amount, _, _)) in &validators { + let address = Address::try_from(private_key).unwrap(); + committee_map.insert(address, (*amount, true, 0)); + } + + // Attempt to construct a `Committee` with more than the maximum committee size. + let result = Committee::new_genesis(committee_map); + assert!(result.is_err()); + + // Reset the validators. + // Note: We use a smaller committee size to ensure that there is enough supply to allocate to the validators and genesis block transactions. + let validators = + sample_validators::(Committee::::MAX_COMMITTEE_SIZE as usize, rng); + + // Construct the committee. + // Track the allocated amount. + let (committee_map, allocated_amount) = + sample_committee_map_and_allocated_amount(&validators, &IndexMap::new()); + + // Construct the public balances, allocating the remaining supply. + let public_balances = sample_public_balances( + &validators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + ::STARTING_SUPPLY - allocated_amount, + ); + + // Construct the bonded balances. + let bonded_balances = sample_bonded_balances(&validators, &IndexMap::new()); + + // Construct the genesis block, which should pass. + let block = vm + .genesis_quorum( + validators.keys().next().unwrap(), + Committee::new_genesis(committee_map).unwrap(), + public_balances, + bonded_balances, + rng, + ) + .unwrap(); + + // Add the block. + vm.add_next_block(&block).unwrap(); + } + + // Note that the maximum delegator size is large enough that the ratification ID cannot be computed. + #[test] + fn test_ratify_genesis_greater_than_max_delegator_size() { + // Initialize an RNG. + let rng = &mut TestRng::default(); + + // Initialize the VM. + let vm = sample_vm(); + + // Construct the validators. + // Note: We use a smaller committee size to ensure that there is enough supply to allocate to the validators and genesis block transactions. + let validators = + sample_validators::(Committee::::MAX_COMMITTEE_SIZE as usize / 4, rng); + + // Construct the delegators, greater than the maximum delegator size. + let delegators = (0..MAX_DELEGATORS + 1) + .map(|_| { + let private_key = PrivateKey::::new(rng).unwrap(); + let validator = Address::try_from(validators.keys().next().unwrap()).unwrap(); + let amount = MIN_DELEGATOR_STAKE; + (private_key, (validator, amount)) + }) + .collect::>(); + + // Construct the committee. + // Track the allocated amount. + let (committee_map, allocated_amount) = sample_committee_map_and_allocated_amount(&validators, &delegators); + + // Construct the public balances, allocating the remaining supply to the validators and zero to the delegators. + let mut public_balances = sample_public_balances( + &validators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + ::STARTING_SUPPLY - allocated_amount, + ); + public_balances.extend(sample_public_balances( + &delegators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + 0, + )); + + // Construct the bonded balances. + let bonded_balances = sample_bonded_balances(&validators, &delegators); + + // Construct the genesis block, which should fail. + let result = vm.genesis_quorum( + validators.keys().next().unwrap(), + Committee::new_genesis(committee_map).unwrap(), + public_balances, + bonded_balances, + rng, + ); + assert!(result.is_err()); + } + + #[test] + fn test_ratify_genesis_is_correct() { + const NUM_VALIDATORS: usize = 5; + const NUM_DELEGATORS: usize = 8; + + // Sample an RNG. + let rng = &mut TestRng::default(); + + println!("Initializing VMs."); + + // Initialize the VM. + let vm = sample_vm(); + + println!("Constructing validator and delegator sets."); + + // Sample the validators. + let validators = sample_validators(NUM_VALIDATORS, rng); + + // Sample the delegators, cycling through the validators. + let delegators: IndexMap<_, _> = (0..NUM_DELEGATORS) + .map(|i| { + let private_key = PrivateKey::new(rng).unwrap(); + let validator = Address::try_from(validators.keys().nth(i % NUM_VALIDATORS).unwrap()).unwrap(); + let amount = MIN_DELEGATOR_STAKE; + (private_key, (validator, amount)) + }) + .collect(); + + // Sample a genesis block without any delegators. + // Specifically, the genesis block will contain a `Ratification` with: + // - the committee state, containing only the validator amounts. + // - the public balances for the delegators, with 10_000_000u64 microcredits each (plus 843_880u64 microcredits for fees). + // - the public balances for the validators dividing up the remaining starting supply. + // - the bonded balances, only containing the validators. + + println!("Initializing the VM."); + + // Construct the committee. + // Track the allocated amount. + let (committee_map, allocated_amount) = sample_committee_map_and_allocated_amount(&validators, &delegators); + let committee = Committee::new_genesis(committee_map).unwrap(); + + // Construct the public balances, allocating the remaining supply to the validators and zero to the delegators. + let mut public_balances = sample_public_balances( + &validators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + ::STARTING_SUPPLY - allocated_amount, + ); + public_balances.extend(sample_public_balances( + &delegators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + 0, + )); + + // Construct the bonded balances. + let bonded_balances = sample_bonded_balances(&validators, &delegators); + + println!("Generating the genesis block."); + + let genesis = vm + .genesis_quorum( + validators.keys().next().unwrap(), + committee.clone(), + public_balances.clone(), + bonded_balances.clone(), + rng, + ) + .unwrap(); + + println!("Adding the genesis block to the VM."); + + // Add the genesis block to the VM. + vm.add_next_block(&genesis).unwrap(); + + // Check that the state of the `credits.aleo` program is correct. + let program_id = ProgramID::from_str("credits.aleo").unwrap(); + let committee_mapping_name = Identifier::from_str("committee").unwrap(); + let account_mapping_name = Identifier::from_str("account").unwrap(); + let bonded_mapping_name = Identifier::from_str("bonded").unwrap(); + let metadata_mapping_name = Identifier::from_str("metadata").unwrap(); + let unbonding_mapping_name = Identifier::from_str("unbonding").unwrap(); + let withdraw_mapping_name = Identifier::from_str("withdraw").unwrap(); + + // Get and check the committee mapping. + let actual_committee = vm.finalize_store().get_mapping_confirmed(program_id, committee_mapping_name).unwrap(); + let expected_committee = committee + .members() + .iter() + .map(|(address, (_, is_open, commission))| { + ( + Plaintext::from_str(&address.to_string()).unwrap(), + Value::from_str(&format!("{{ is_open: {is_open}, commission: {commission}u8 }}")).unwrap(), + ) + }) + .collect_vec(); + // Note that `actual_committee` and `expected_committee` are vectors and not necessarily in the same order. + // By checking that the lengths of the vector are equal and that all entries in `actual_committee` are in `expected_committee`, + // we can ensure that the two vectors contain the same data. + assert_eq!(actual_committee.len(), expected_committee.len()); + for entry in actual_committee.iter() { + assert!(expected_committee.contains(entry)); + } + + // Get and check the account mapping. + let actual_account = vm.finalize_store().get_mapping_confirmed(program_id, account_mapping_name).unwrap(); + let expected_account = public_balances + .iter() + .map(|(address, amount)| { + (Plaintext::from_str(&address.to_string()).unwrap(), Value::from_str(&format!("{amount}u64")).unwrap()) + }) + .collect_vec(); + // Note that `actual_account` and `expected_account` are vectors and not necessarily in the same order. + // By checking that the lengths of the vector are equal and that all entries in `actual_account` are in `expected_account`, + // we can ensure that the two vectors contain the same data. + assert_eq!(actual_account.len(), expected_account.len()); + // Check that all entries except for the first validator are the same. + for entry in actual_account.iter() { + let first_validator = Address::try_from(validators.keys().next().unwrap()).unwrap(); + // Note that the first validator is used to execute additional transactions in `VM::genesis_quorum`. + // Therefore, the balance of the first validator will be different from the expected balance. + if entry.0 == Plaintext::from_str(&first_validator.to_string()).unwrap() { + assert_eq!(entry.1, Value::from_str("144991999894244u64").unwrap()); + } else { + assert!(expected_account.contains(entry)); + } + } + + // Get and check the bonded mapping. + let actual_bonded = vm.finalize_store().get_mapping_confirmed(program_id, bonded_mapping_name).unwrap(); + let expected_bonded = bonded_balances + .iter() + .map(|(address, (validator, _, amount))| { + ( + Plaintext::from_str(&address.to_string()).unwrap(), + Value::from_str(&format!("{{ validator: {validator}, microcredits: {amount}u64 }}")).unwrap(), + ) + }) + .collect_vec(); + // Note that `actual_bonded` and `expected_bonded` are vectors and not necessarily in the same order. + // By checking that the lengths of the vector are equal and that all entries in `actual_bonded` are in `expected_bonded`, + // we can ensure that the two vectors contain the same data. + assert_eq!(actual_bonded.len(), expected_bonded.len()); + for entry in actual_bonded.iter() { + assert!(expected_bonded.contains(entry)); + } + + // Get and check the withdraw mapping. + let actual_withdraw = vm.finalize_store().get_mapping_confirmed(program_id, withdraw_mapping_name).unwrap(); + let expected_withdraw = bonded_balances + .iter() + .map(|(address, (_, withdrawal_address, _))| { + ( + Plaintext::from_str(&address.to_string()).unwrap(), + Value::from_str(&withdrawal_address.to_string()).unwrap(), + ) + }) + .collect_vec(); + // Note that `actual_withdraw` and `expected_withdraw` are vectors and not necessarily in the same order. + // By checking that the lengths of the vector are equal and that all entries in `actual_withdraw` are in `expected_withdraw`, + // we can ensure that the two vectors contain the same data. + assert_eq!(actual_withdraw.len(), expected_withdraw.len()); + for entry in actual_withdraw.iter() { + assert!(expected_withdraw.contains(entry)); + } + + // Get and check the entry in metadata mapping corresponding to the number of validators. + let num_validators = vm + .finalize_store() + .get_value_confirmed( + program_id, + metadata_mapping_name, + &Plaintext::from_str("aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc").unwrap(), + ) + .unwrap() + .unwrap(); + assert_eq!(num_validators, Value::from_str(&format!("{NUM_VALIDATORS}u32")).unwrap()); + + // Get and check the entry in metadata mapping corresponding to the number of delegators. + let num_delegators = vm + .finalize_store() + .get_value_confirmed( + program_id, + metadata_mapping_name, + &Plaintext::from_str("aleo1qgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqanmpl0").unwrap(), + ) + .unwrap() + .unwrap(); + assert_eq!(num_delegators, Value::from_str(&format!("{NUM_DELEGATORS}u32")).unwrap()); + + // Get and check the unbonding mapping. + let actual_unbonding = vm.finalize_store().get_mapping_confirmed(program_id, unbonding_mapping_name).unwrap(); + assert!(actual_unbonding.is_empty()); + } + + #[test] + fn test_ratify_genesis_is_consistent() { + const NUM_VALIDATORS: usize = 5; + const NUM_DELEGATORS: usize = 8; + + // Sample an RNG. + let rng = &mut TestRng::default(); + + println!("Initializing VMs."); + + // Initialize two VMs. + let vm_1 = sample_vm(); + let vm_2 = sample_vm(); + + println!("Constructing validator and delegator sets."); + + // Sample the validators. + let validators = sample_validators(NUM_VALIDATORS, rng); + + // Sample the delegators, cycling through the validators. + let delegators: IndexMap<_, _> = (0..NUM_DELEGATORS) + .map(|i| { + let private_key = PrivateKey::new(rng).unwrap(); + let validator = Address::try_from(validators.keys().nth(i % NUM_VALIDATORS).unwrap()).unwrap(); + let amount = MIN_DELEGATOR_STAKE; + (private_key, (validator, amount)) + }) + .collect(); + + // For the first VM, sample a genesis block without any delegators. + // Specifically, the genesis block will contain a `Ratification` with: + // - the committee state, containing only the validator amounts. + // - the public balances for the delegators, with 10_000_000u64 microcredits each (plus 843_880u64 microcredits for fees). + // - the public balances for the validators dividing up the remaining starting supply. + // - the bonded balances, only containing the validators. + + println!("Initializing the first VM."); + + // Construct the committee. + // Track the allocated amount. + let (committee_map, mut allocated_amount) = + sample_committee_map_and_allocated_amount(&validators, &IndexMap::new()); + let committee = Committee::new_genesis(committee_map).unwrap(); + + // Construct the public balances. + let mut public_balances = IndexMap::new(); + for (private_key, (_validator, _amount)) in &delegators { + let address = Address::try_from(private_key).unwrap(); + let amount = MIN_DELEGATOR_STAKE * 2; + public_balances.insert(address, amount); + allocated_amount += amount; + } + public_balances.extend(sample_public_balances( + &validators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + ::STARTING_SUPPLY - allocated_amount, + )); + + // Construct the bonded balances. + let bonded_balances = sample_bonded_balances(&validators, &IndexMap::new()); + + println!("[VM1] Generating the genesis block."); + + let genesis_1 = vm_1 + .genesis_quorum(validators.keys().next().unwrap(), committee, public_balances, bonded_balances, rng) + .unwrap(); + + println!("[VM1] Adding the genesis block to the VM."); + + // Add the genesis block to the VM. + vm_1.add_next_block(&genesis_1).unwrap(); + + println!("[VM1] Generating bond transactions for each of the delegators."); + + // Generate bond transactions for each of the delegators. + let mut transactions = Vec::new(); + for (private_key, (validator, amount)) in &delegators { + let transaction = vm_1 + .execute( + private_key, + ("credits.aleo", "bond_public"), + vec![ + Value::::from_str(&validator.to_string()).unwrap(), + Value::::from_str(&Address::try_from(private_key).unwrap().to_string()) + .unwrap(), + Value::::from_str(&format!("{amount}u64")).unwrap(), + ] + .into_iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + transactions.push(transaction); + } + + println!("[VM1] Generating the next block."); + let next_block = + sample_next_block(&vm_1, validators.keys().next().unwrap(), &transactions, &genesis_1, &mut vec![], rng) + .unwrap(); + + println!("[VM1] Adding the next block to the VM."); + vm_1.add_next_block(&next_block).unwrap(); + + // For the second VM, sample a genesis block with the same validators and delegators. + // Specifically, the genesis block will contain a `Ratification` with: + // - the committee state, containing the total staked amount per validator. + // - the public balances for the delegators, with 0 microcredits each. + // - the public balances for the validators dividing up the remaining starting supply. + // - the bonded balances, containing the validators and delegators. + + println!("Initializing the second VM."); + + // Construct the committee. + // Track the allocated amount. + let (committee_map, allocated_amount) = sample_committee_map_and_allocated_amount(&validators, &delegators); + let committee = Committee::new_genesis(committee_map).unwrap(); + + // Construct the public balances, allocating the remaining supply to the validators and zero to the delegators. + let mut public_balances = sample_public_balances( + &validators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + ::STARTING_SUPPLY - allocated_amount, + ); + public_balances.extend(sample_public_balances( + &delegators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + 0, + )); + + // Construct the bonded balances. + let bonded_balances = sample_bonded_balances(&validators, &delegators); + + println!("[VM2] Generating the genesis block."); + + // Construct the genesis block. + let genesis_2 = vm_2 + .genesis_quorum(validators.keys().next().unwrap(), committee, public_balances, bonded_balances, rng) + .unwrap(); + + println!("[VM2] Adding the genesis block to the VM."); + + // Add the genesis block to the VM. + vm_2.add_next_block(&genesis_2).unwrap(); + + println!("Checking that all mappings in `credits.aleo` are equal across the two VMs."); + + // Check that all mappings in `credits.aleo` are equal across the two VMs. + let program_id = ProgramID::from_str("credits.aleo").unwrap(); + let committee_mapping_name = Identifier::from_str("committee").unwrap(); + let bonded_mapping_name = Identifier::from_str("bonded").unwrap(); + let unbonding_mapping_name = Identifier::from_str("unbonding").unwrap(); + let account_mapping_name = Identifier::from_str("account").unwrap(); + let metadata_mapping_name = Identifier::from_str("metadata").unwrap(); + let withdraw_mapping_name = Identifier::from_str("withdraw").unwrap(); + + let committee_1 = vm_1.finalize_store().get_mapping_confirmed(program_id, committee_mapping_name).unwrap(); + let committee_2 = vm_2.finalize_store().get_mapping_confirmed(program_id, committee_mapping_name).unwrap(); + assert_eq!(committee_1, committee_2); + + let bonded_1 = vm_1.finalize_store().get_mapping_confirmed(program_id, bonded_mapping_name).unwrap(); + let bonded_2 = vm_2.finalize_store().get_mapping_confirmed(program_id, bonded_mapping_name).unwrap(); + assert_eq!(bonded_1, bonded_2); + + let unbonding_1 = vm_1.finalize_store().get_mapping_confirmed(program_id, unbonding_mapping_name).unwrap(); + let unbonding_2 = vm_2.finalize_store().get_mapping_confirmed(program_id, unbonding_mapping_name).unwrap(); + assert_eq!(unbonding_1, unbonding_2); + + // Check that the account mapping across both VMs have the same keys. + let account_1 = vm_1 + .finalize_store() + .get_mapping_confirmed(program_id, account_mapping_name) + .unwrap() + .into_iter() + .map(|(k, _)| k.to_string()) + .collect::>(); + let account_2 = vm_2 + .finalize_store() + .get_mapping_confirmed(program_id, account_mapping_name) + .unwrap() + .into_iter() + .map(|(k, _)| k.to_string()) + .collect::>(); + assert_eq!(account_1, account_2); + + // Check that the metadata mapping across both VMs are equal. + let metadata_1 = vm_1.finalize_store().get_mapping_confirmed(program_id, metadata_mapping_name).unwrap(); + let metadata_2 = vm_2.finalize_store().get_mapping_confirmed(program_id, metadata_mapping_name).unwrap(); + assert_eq!(metadata_1, metadata_2); + + // Check that the withdraw mapping across both VMs are equal. + let withdraw_1 = vm_1.finalize_store().get_mapping_confirmed(program_id, withdraw_mapping_name).unwrap(); + let withdraw_2 = vm_2.finalize_store().get_mapping_confirmed(program_id, withdraw_mapping_name).unwrap(); + assert_eq!(withdraw_1, withdraw_2); + } + + #[test] + fn test_ratify_genesis_with_insufficient_validator_balance() { + // Sample an RNG. + let rng = &mut TestRng::default(); + + // Initialize the VM. + let vm = sample_vm(); + + // Attempt to construct a genesis quorum, with a validator with an insufficient amount. + let mut validators = (0..3) + .map(|_| { + let private_key = PrivateKey::::new(rng).unwrap(); + let address = Address::try_from(&private_key).unwrap(); + let amount = MIN_VALIDATOR_STAKE; + let is_open = true; + let commission = 0u8; + (address, (amount, is_open, commission)) + }) + .collect::>(); + validators + .insert(Address::try_from(PrivateKey::new(rng).unwrap()).unwrap(), (MIN_VALIDATOR_STAKE - 1, true, 0)); + + // Construct the committee. + let result = Committee::new_genesis(validators); + assert!(result.is_err()); + + // Track the allocated amount. + let mut allocated_amount = 0; + + // Reset the validators. + let validators = sample_validators(4, rng); + + // Construct the committee. + let committee = Committee::new_genesis( + validators + .iter() + .map(|(private_key, (amount, _, _))| { + let address = Address::try_from(private_key).unwrap(); + allocated_amount += *amount; + (address, (*amount, true, 0u8)) + }) + .collect(), + ) + .unwrap(); + + // Construct the public balances, allocating the remaining supply to rest of the validators. + let public_balances = sample_public_balances( + &validators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + ::STARTING_SUPPLY - allocated_amount, + ); + + // Construct the bonded balances. + let bonded_balances = sample_bonded_balances(&validators, &IndexMap::new()); + + // Construct the genesis block, which should pass. + let block = vm + .genesis_quorum(validators.keys().next().unwrap(), committee, public_balances, bonded_balances, rng) + .unwrap(); + + // Add the block. + vm.add_next_block(&block).unwrap(); + } + + #[test] + fn test_ratify_genesis_with_insufficient_delegator_balance() { + // Sample an RNG. + let rng = &mut TestRng::default(); + + // Initialize the VM. + let vm = sample_vm(); + + // Track the allocated amount. + let mut allocated_amount = 0; + + // Sample the validators. + let validators = sample_validators(4, rng); + + // Attempt to construct a genesis quorum, with a delegator with an insufficient amount. + let mut delegators = IndexMap::new(); + delegators.insert( + PrivateKey::new(rng).unwrap(), + (Address::try_from(validators.keys().next().unwrap()).unwrap(), MIN_DELEGATOR_STAKE - 1), + ); + + // Construct the committee. + let mut committee_map = IndexMap::new(); + for (private_key, (amount, _, _)) in &validators { + let address = Address::try_from(private_key).unwrap(); + let amount = if address == Address::try_from(validators.keys().next().unwrap()).unwrap() { + *amount + MIN_DELEGATOR_STAKE - 1 + } else { + *amount + }; + committee_map.insert(address, (amount, true, 0u8)); + allocated_amount += amount; + } + let committee = Committee::new_genesis(committee_map).unwrap(); + + // Construct the public balances, allocating the remaining supply to rest of the validators. + let mut public_balances = sample_public_balances( + &validators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + ::STARTING_SUPPLY - allocated_amount, + ); + public_balances + .extend(sample_public_balances(&[Address::try_from(delegators.keys().next().unwrap()).unwrap()], 0)); + + // Construct the bonded balances. + let bonded_balances = sample_bonded_balances(&validators, &delegators); + + // Construct the genesis block, which should fail. + let result = + vm.genesis_quorum(validators.keys().next().unwrap(), committee, public_balances, bonded_balances, rng); + assert!(result.is_err()); + + // Reset the delegators. + let mut delegators = IndexMap::new(); + delegators.insert( + PrivateKey::new(rng).unwrap(), + (Address::try_from(validators.keys().next().unwrap()).unwrap(), MIN_DELEGATOR_STAKE), + ); + + // Track the allocated amount. + let mut allocated_amount = 0; + + // Construct the committee. + let mut committee_map = IndexMap::new(); + for (private_key, (amount, _, _)) in &validators { + let address = Address::try_from(private_key).unwrap(); + let amount = if address == Address::try_from(validators.keys().next().unwrap()).unwrap() { + *amount + MIN_DELEGATOR_STAKE + } else { + *amount + }; + committee_map.insert(address, (amount, true, 0u8)); + allocated_amount += amount; + } + let committee = Committee::new_genesis(committee_map).unwrap(); + + // Construct the public balances, allocating the remaining supply to rest of the validators. + let mut public_balances = sample_public_balances( + &validators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + ::STARTING_SUPPLY - allocated_amount, + ); + public_balances + .extend(sample_public_balances(&[Address::try_from(delegators.keys().next().unwrap()).unwrap()], 0)); + + // Construct the bonded balances. + let bonded_balances = sample_bonded_balances(&validators, &delegators); + + // Construct the genesis block, which should pass. + let block = vm + .genesis_quorum(validators.keys().next().unwrap(), committee, public_balances, bonded_balances, rng) + .unwrap(); + + // Add the block. + vm.add_next_block(&block).unwrap(); + } + + #[test] + fn test_ratify_genesis_with_incorrect_committee_amounts() { + // Sample an RNG. + let rng = &mut TestRng::default(); + + // Initialize the VM. + let vm = sample_vm(); + + // Initialize the validators. + let validators = sample_validators(4, rng); + + // Initialize the delegators. + let delegators = (0..4) + .map(|_| { + let private_key = PrivateKey::new(rng).unwrap(); + let validator = Address::try_from(validators.keys().next().unwrap()).unwrap(); + let amount = MIN_DELEGATOR_STAKE; + (private_key, (validator, amount)) + }) + .collect::>(); + + // Construct the **incorrect** committee. + // Track the allocated amount. + // Note: this committee is missing the additional stake from the delegators. + let (committee_map, allocated_amount) = + sample_committee_map_and_allocated_amount(&validators, &IndexMap::new()); + let committee = Committee::new_genesis(committee_map).unwrap(); + + // Construct the public balances, allocating the remaining supply to rest of the validators. + let mut public_balances = sample_public_balances( + &validators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + ::STARTING_SUPPLY - allocated_amount, + ); + public_balances.extend(sample_public_balances( + &delegators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + 0, + )); + + // Construct the bonded balances. + let bonded_balances = sample_bonded_balances(&validators, &delegators); + + // Construct the genesis block, which should fail. + let result = vm.genesis_quorum( + validators.keys().next().unwrap(), + committee, + public_balances, + bonded_balances.clone(), + rng, + ); + assert!(result.is_err()); + + // Construct the **correct** committee. + // Reset the tracked amount. + let (committee_map, allocated_amount) = sample_committee_map_and_allocated_amount(&validators, &delegators); + let committee = Committee::new_genesis(committee_map).unwrap(); + + // Construct the public balances, allocating the remaining supply to rest of the validators. + let mut public_balances = sample_public_balances( + &validators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + ::STARTING_SUPPLY - allocated_amount, + ); + public_balances.extend(sample_public_balances( + &delegators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + 0, + )); + + // Construct the genesis block, which should pass. + let block = vm + .genesis_quorum(validators.keys().next().unwrap(), committee, public_balances, bonded_balances, rng) + .unwrap(); + + // Add the block. + vm.add_next_block(&block).unwrap(); + } + + #[test] + fn test_ratify_genesis_with_closed_validator() { + // Sample an RNG. + let rng = &mut TestRng::default(); + + // Initialize the VM. + let vm = sample_vm(); + + // Initialize the validators, with one closed. + let validators = (0..4) + .map(|i| { + let private_key = PrivateKey::new(rng).unwrap(); + let amount = MIN_VALIDATOR_STAKE; + let is_open = i != 0; + let commission = 0; + (private_key, (amount, is_open, commission)) + }) + .collect::>(); + + // Initialize a potential delegator. + let delegator_key = PrivateKey::new(rng).unwrap(); + let delegator_address = Address::try_from(delegator_key).unwrap(); + + // Construct the committee. + // Track the allocated amount. + let (committee_map, allocated_amount) = + sample_committee_map_and_allocated_amount(&validators, &IndexMap::new()); + + // Construct the public balances, allocating half to the first validator and the remaining to the delegator. + let public_balances = sample_public_balances( + &[Address::try_from(validators.keys().next().unwrap()).unwrap(), delegator_address], + ::STARTING_SUPPLY - allocated_amount, + ); + + // Construct the bonded balances. + let bonded_balances = sample_bonded_balances(&validators, &IndexMap::new()); + + // Construct the genesis block, which should pass. + let block = vm + .genesis_quorum( + validators.keys().next().unwrap(), + Committee::new_genesis(committee_map).unwrap(), + public_balances, + bonded_balances, + rng, + ) + .unwrap(); + + // Add the block. + vm.add_next_block(&block).unwrap(); + + // Attempt to bond the potential delegator to the closed validator. + let transaction = vm + .execute( + &delegator_key, + ("credits.aleo", "bond_public"), + vec![ + Value::::from_str( + &Address::try_from(validators.keys().next().unwrap()).unwrap().to_string(), + ) + .unwrap(), + Value::::from_str(&Address::try_from(delegator_key).unwrap().to_string()).unwrap(), + Value::::from_str(&format!("{MIN_DELEGATOR_STAKE}u64")).unwrap(), + ] + .into_iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Generate the next block. + let next_block = + sample_next_block(&vm, validators.keys().next().unwrap(), &vec![transaction], &block, &mut vec![], rng) + .unwrap(); + + // Add the next block. + vm.add_next_block(&next_block).unwrap(); + + // Check that the delegator is not in the `bonded` mapping. + let bonded_mapping = vm + .finalize_store() + .get_mapping_confirmed( + ProgramID::from_str("credits.aleo").unwrap(), + Identifier::from_str("bonded").unwrap(), + ) + .unwrap(); + assert_eq!(bonded_mapping.len(), validators.len()); + + // Attempt to bond the potential delegator to the open validator. + let transaction = vm + .execute( + &delegator_key, + ("credits.aleo", "bond_public"), + vec![ + Value::::from_str( + &Address::try_from(validators.keys().nth(1).unwrap()).unwrap().to_string(), + ) + .unwrap(), + Value::::from_str(&Address::try_from(delegator_key).unwrap().to_string()).unwrap(), + Value::::from_str(&format!("{MIN_DELEGATOR_STAKE}u64")).unwrap(), + ] + .into_iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Generate the next block. + let next_block = sample_next_block( + &vm, + validators.keys().next().unwrap(), + &vec![transaction], + &next_block, + &mut vec![], + rng, + ) + .unwrap(); + + // Add the next block. + vm.add_next_block(&next_block).unwrap(); + + // Check that the delegator is in the `bonded` mapping. + let bonded_mapping = vm + .finalize_store() + .get_mapping_confirmed( + ProgramID::from_str("credits.aleo").unwrap(), + Identifier::from_str("bonded").unwrap(), + ) + .unwrap(); + assert_eq!(bonded_mapping.len(), validators.len() + 1); + } + + #[test] + fn test_ratify_genesis_withdrawal_address() { + const NUM_VALIDATORS: usize = 5; + const NUM_DELEGATORS: usize = 8; + + // Sample an RNG. + let rng = &mut TestRng::default(); + + // Initialize the VM. + let vm = sample_vm(); + + // Sample the validators. + let validators = sample_validators(NUM_VALIDATORS, rng); + + // Sample the delegators, cycling through the validators. + let delegators: IndexMap<_, _> = (0..NUM_DELEGATORS) + .map(|i| { + let private_key = PrivateKey::new(rng).unwrap(); + let validator = Address::try_from(validators.keys().nth(i % NUM_VALIDATORS).unwrap()).unwrap(); + let amount = MIN_DELEGATOR_STAKE; + (private_key, (validator, amount)) + }) + .collect(); + + // Construct the committee. + // Track the allocated amount. + let (committee_map, allocated_amount) = sample_committee_map_and_allocated_amount(&validators, &delegators); + let committee = Committee::new_genesis(committee_map).unwrap(); + + // Construct the public balances, allocating the remaining supply to the validators and zero to the delegators. + let mut public_balances = sample_public_balances( + &validators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + ::STARTING_SUPPLY - allocated_amount, + ); + public_balances.extend(sample_public_balances( + &delegators.keys().map(|private_key| Address::try_from(private_key).unwrap()).collect::>(), + 0, + )); + + // Construct the bonded balances. + let mut bonded_balances = sample_bonded_balances(&validators, &delegators); + + // Randomly sample and update the withdrawal addresses in the bonded balances. + for (_, (_, withdrawal_address, _)) in bonded_balances.iter_mut() { + *withdrawal_address = Address::rand(rng); + } + + // Construct the genesis block. + let genesis = vm + .genesis_quorum( + validators.keys().next().unwrap(), + committee.clone(), + public_balances.clone(), + bonded_balances.clone(), + rng, + ) + .unwrap(); + + // Add the genesis block to the VM. + vm.add_next_block(&genesis).unwrap(); + + // Check that the state of the `credits.aleo` program is correct. + let program_id = ProgramID::from_str("credits.aleo").unwrap(); + let withdraw_mapping_name = Identifier::from_str("withdraw").unwrap(); + + // Get and check the withdraw mapping. + let actual_withdraw = vm.finalize_store().get_mapping_confirmed(program_id, withdraw_mapping_name).unwrap(); + let expected_withdraw = bonded_balances + .iter() + .map(|(address, (_, withdrawal_address, _))| { + ( + Plaintext::from_str(&address.to_string()).unwrap(), + Value::from_str(&withdrawal_address.to_string()).unwrap(), + ) + }) + .collect_vec(); + // Note that `actual_withdraw` and `expected_withdraw` are vectors and not necessarily in the same order. + // By checking that the lengths of the vector are equal and that all entries in `actual_withdraw` are in `expected_withdraw`, + // we can ensure that the two vectors contain the same data. + assert_eq!(actual_withdraw.len(), expected_withdraw.len()); + for entry in actual_withdraw.iter() { + assert!(expected_withdraw.contains(entry)); + } + } } diff --git a/synthesizer/src/vm/helpers/committee.rs b/synthesizer/src/vm/helpers/committee.rs index d44c4eafd1..77a51bb695 100644 --- a/synthesizer/src/vm/helpers/committee.rs +++ b/synthesizer/src/vm/helpers/committee.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -19,28 +20,29 @@ use console::{ network::Network, prelude::{cfg_into_iter, cfg_iter, cfg_reduce}, program::{Identifier, Literal, Plaintext, Value}, - types::{Boolean, U64}, + types::{Boolean, U8, U64}, }; use ledger_committee::Committee; -use anyhow::{bail, ensure, Result}; -use indexmap::{indexmap, IndexMap}; +use anyhow::{Result, bail, ensure}; +use indexmap::{IndexMap, indexmap}; use std::str::FromStr; #[cfg(not(feature = "serial"))] use rayon::prelude::*; /// Returns the committee given the committee map from finalize storage. -pub fn committee_map_into_committee( +pub fn committee_and_delegated_maps_into_committee( starting_round: u64, committee_map: Vec<(Plaintext, Value)>, + delegated_map: Vec<(Plaintext, Value)>, ) -> Result> { // Prepare the identifiers. - let microcredits_identifier = Identifier::from_str("microcredits")?; - let is_open_identifier = Identifier::from_str("is_open")?; + let is_open_identifier: Identifier = Identifier::from_str("is_open")?; + let commission_identifier: Identifier = Identifier::from_str("commission")?; // Extract the committee members. - let committee_members = committee_map + let committee_members: IndexMap, (u64, bool, u8)> = committee_map .iter() .map(|(key, value)| { // Extract the address from the key. @@ -48,24 +50,48 @@ pub fn committee_map_into_committee( Plaintext::Literal(Literal::Address(address), _) => address, _ => bail!("Invalid committee key (missing address) - {key}"), }; + // Extract the committee state from the value. - match value { + let (is_open, commission) = match value { Value::Plaintext(Plaintext::Struct(state, _)) => { - // Extract the microcredits from the value. - let microcredits = match state.get(µcredits_identifier) { - Some(Plaintext::Literal(Literal::U64(microcredits), _)) => **microcredits, - _ => bail!("Invalid committee state (missing microcredits) - {value}"), - }; // Extract the is_open flag from the value. let is_open = match state.get(&is_open_identifier) { Some(Plaintext::Literal(Literal::Boolean(is_open), _)) => **is_open, _ => bail!("Invalid committee state (missing boolean) - {value}"), }; + // Extract the commission from the value. + let commission = match state.get(&commission_identifier) { + Some(Plaintext::Literal(Literal::U8(commission), _)) => **commission, + _ => bail!("Invalid committee state (missing commission) - {value}"), + }; // Return the committee state. - Ok((*address, (microcredits, is_open))) + (is_open, commission) } _ => bail!("Invalid committee value (missing struct) - {value}"), - } + }; + + // Extract the microcredits for the address from the delegated map. + let Some(microcredits) = delegated_map.iter().find_map(|(delegated_key, delegated_value)| { + // Retrieve the delegated address. + let delegated_address = match delegated_key { + Plaintext::Literal(Literal::Address(address), _) => Some(address), + _ => None, + }; + // Check if the address matches. + match delegated_address == Some(address) { + // Extract the microcredits from the value. + true => match delegated_value { + Value::Plaintext(Plaintext::Literal(Literal::U64(microcredits), _)) => Some(**microcredits), + _ => None, + }, + false => None, + } + }) else { + bail!("Missing microcredits for committee member - {address}"); + }; + + // Return the committee member. + Ok((*address, (microcredits, is_open, commission))) }) .collect::>>()?; @@ -119,7 +145,15 @@ pub fn ensure_stakers_matches( ) -> Result<()> { // Construct the validator map. let validator_map: IndexMap<_, _> = cfg_reduce!( - cfg_into_iter!(stakers).map(|(_, (validator, microcredits))| indexmap! {*validator => *microcredits}), + cfg_into_iter!(stakers) + .map(|(_, (validator, microcredits))| { + if committee.members().contains_key(validator) { + Some(indexmap! {*validator => *microcredits}) + } else { + None + } + }) + .flatten(), || IndexMap::new(), |mut acc, e| { for (validator, microcredits) in e { @@ -143,7 +177,7 @@ pub fn ensure_stakers_matches( ensure!(committee.total_stake() == total_microcredits, "Committee and validator map total stake do not match"); // Iterate over the committee and ensure the committee and validators match. - for (validator, (microcredits, _)) in committee.members() { + for (validator, (microcredits, _, _)) in committee.members() { let candidate_microcredits = validator_map.get(validator); ensure!(candidate_microcredits.is_some(), "A validator is missing in finalize storage"); ensure!( @@ -159,48 +193,61 @@ pub fn ensure_stakers_matches( pub fn to_next_committee( current_committee: &Committee, next_round: u64, - next_stakers: &IndexMap, (Address, u64)>, + next_delegated: &IndexMap, u64>, ) -> Result> { - // Construct the validator map. - let validator_map: IndexMap<_, _> = cfg_reduce!( - cfg_into_iter!(next_stakers).map(|(_, (validator, microcredits))| indexmap! {*validator => *microcredits}), + // Return the next committee. + Committee::new( + next_round, + cfg_iter!(next_delegated) + .flat_map(|(delegatee, microcredits)| { + let Some((_, is_open, commission)) = current_committee.members().get(delegatee) else { + // Do nothing, as the delegatee is not part of the committee. + return None; + }; + Some((*delegatee, (*microcredits, *is_open, *commission))) + }) + .collect(), + ) +} + +pub fn to_next_delegated( + next_stakers: &IndexMap, (Address, u64)>, +) -> IndexMap, u64> { + // Construct the delegated map. + let delegated_map: IndexMap, u64> = cfg_reduce!( + cfg_into_iter!(next_stakers).map(|(_, (delegatee, microcredits))| indexmap! {*delegatee => *microcredits}), || IndexMap::new(), |mut acc, e| { - for (validator, microcredits) in e { - let entry: &mut u64 = acc.entry(validator).or_default(); + for (delegatee, microcredits) in e { + let entry: &mut u64 = acc.entry(delegatee).or_default(); *entry = entry.saturating_add(microcredits); } acc } ); - // Initialize the members. - let mut members = IndexMap::with_capacity(validator_map.len()); - // Iterate over the validators. - for (validator, microcredits) in validator_map { - members.insert(validator, (microcredits, current_committee.is_committee_member_open(validator))); - } - // Return the next committee. - Committee::new(next_round, members) + delegated_map } -/// Returns the committee map and bonded map, given the committee and stakers. -pub fn to_next_commitee_map_and_bonded_map( +/// Returns the committee map, bonded map, and delegated map, given the committee and stakers. +pub fn to_next_committee_bonded_delegated_map( next_committee: &Committee, next_stakers: &IndexMap, (Address, u64)>, -) -> (Vec<(Plaintext, Value)>, Vec<(Plaintext, Value)>) { + next_delegated: &IndexMap, u64>, +) -> (Vec<(Plaintext, Value)>, Vec<(Plaintext, Value)>, Vec<(Plaintext, Value)>) { // Prepare the identifiers. let validator_identifier = Identifier::from_str("validator").expect("Failed to parse 'validator'"); let microcredits_identifier = Identifier::from_str("microcredits").expect("Failed to parse 'microcredits'"); let is_open_identifier = Identifier::from_str("is_open").expect("Failed to parse 'is_open'"); + let commission_identifier = Identifier::from_str("commission").expect("Failed to parse 'commission'"); // Construct the committee map. let committee_map = cfg_iter!(next_committee.members()) - .map(|(validator, (microcredits, is_open))| { + .map(|(validator, (_, is_open, commission))| { // Construct the committee state. let committee_state = indexmap! { - microcredits_identifier => Plaintext::from(Literal::U64(U64::new(*microcredits))), is_open_identifier => Plaintext::from(Literal::Boolean(Boolean::new(*is_open))), + commission_identifier => Plaintext::from(Literal::U8(U8::new(*commission))), }; // Return the committee state. ( @@ -226,30 +273,54 @@ pub fn to_next_commitee_map_and_bonded_map( }) .collect::>(); - (committee_map, bonded_map) + // Construct the delegated map. + let delegated_map = cfg_iter!(next_delegated) + .map(|(delegatee, microcredits)| { + ( + Plaintext::from(Literal::Address(*delegatee)), + Value::Plaintext(Plaintext::Literal(Literal::U64(U64::new(*microcredits)), Default::default())), + ) + }) + .collect::>(); + + (committee_map, bonded_map, delegated_map) +} + +/// Returns the withdraw map, given the withdrawal addresses. +pub fn to_next_withdraw_map( + withdrawal_addresses: &IndexMap, Address>, +) -> Vec<(Plaintext, Value)> { + cfg_iter!(withdrawal_addresses) + .map(|(staker, withdraw_address)| { + ( + Plaintext::from(Literal::Address(*staker)), + Value::Plaintext(Plaintext::Literal(Literal::Address(*withdraw_address), Default::default())), + ) + }) + .collect::>() } #[cfg(test)] pub(crate) mod test_helpers { use super::*; use crate::vm::TestRng; - use ledger_committee::MIN_VALIDATOR_STAKE; + use ledger_committee::{MIN_DELEGATOR_STAKE, MIN_VALIDATOR_STAKE}; use rand::{CryptoRng, Rng}; - /// Returns the stakers, given the map of `(validator, (microcredits, is_open))` entries. + /// Returns the stakers, given the map of `(validator, (microcredits, is_open, commission))` entries. /// This method simulates the existence of delegators for the members. pub(crate) fn to_stakers( - members: &IndexMap, (u64, bool)>, + members: &IndexMap, (u64, bool, u8)>, rng: &mut R, ) -> IndexMap, (Address, u64)> { members .into_iter() - .flat_map(|(validator, (microcredits, _))| { + .flat_map(|(validator, (microcredits, _, _))| { // Keep a tally of the remaining microcredits. let remaining_microcredits = microcredits.saturating_sub(MIN_VALIDATOR_STAKE); - // Set the staker amount to 10 credit. - let staker_amount = 10_000_000; + // Set the staker amount to `MIN_DELEGATOR_STAKE` microcredits. + let staker_amount = MIN_DELEGATOR_STAKE; // Determine the number of iterations. let num_iterations = (remaining_microcredits / staker_amount).saturating_sub(1); @@ -278,6 +349,31 @@ pub(crate) mod test_helpers { }) .collect() } + + /// Returns the validator delegation totals, given the map of `(validator, (microcredits, is_open, commission))` entries. + /// This method simulates the existence of delegators for the members. + pub(crate) fn to_delegations( + members: &IndexMap, (u64, bool, u8)>, + ) -> IndexMap, u64> { + members.into_iter().map(|(validator, (microcredits, _, _))| (*validator, *microcredits)).collect() + } + + /// Returns the withdrawal addresses, given the stakers. + /// This method simulates the existence of unique withdrawal addresses for the stakers. + pub(crate) fn to_withdraw_addresses( + stakers: &IndexMap, (Address, u64)>, + rng: &mut R, + ) -> IndexMap, Address> { + stakers + .into_iter() + .map(|(staker, _)| { + // Sample a random withdraw address. + let withdraw_address = Address::::new(rng.gen()); + // Return the withdraw address. + (*staker, withdraw_address) + }) + .collect() + } } #[cfg(test)] @@ -289,16 +385,29 @@ mod tests { use rayon::prelude::*; use std::str::FromStr; - /// Returns the committee map, given the map of `(validator, (microcredits, is_open))` entries. - fn to_committee_map(members: &IndexMap, (u64, bool)>) -> Vec<(Plaintext, Value)> { + /// Returns the committee map, given the map of `(validator, (microcredits, is_open, commission))` entries. + fn to_committee_map(members: &IndexMap, (u64, bool, u8)>) -> Vec<(Plaintext, Value)> { members .par_iter() - .map(|(validator, (microcredits, is_open))| { - let microcredits = U64::::new(*microcredits); + .map(|(validator, (_, is_open, commission))| { let is_open = Boolean::::new(*is_open); + let commission = U8::::new(*commission); ( Plaintext::from(Literal::Address(*validator)), - Value::from_str(&format!("{{ microcredits: {microcredits}, is_open: {is_open} }}")).unwrap(), + Value::from_str(&format!("{{ is_open: {is_open}, commission: {commission} }}")).unwrap(), + ) + }) + .collect() + } + + /// Returns the delegated map, given the map of `(validator, (microcredits, is_open, commission))` entries. + fn to_delegated_map(members: &IndexMap, (u64, bool, u8)>) -> Vec<(Plaintext, Value)> { + members + .par_iter() + .map(|(validator, (microcredits, _, _))| { + ( + Plaintext::from(Literal::Address(*validator)), + Value::Plaintext(Plaintext::Literal(Literal::U64(U64::new(*microcredits)), Default::default())), ) }) .collect() @@ -327,8 +436,33 @@ mod tests { .collect() } + /// Returns the withdrawal addresses given the withdraw map from finalize storage. + pub fn withdraw_map_to_withdrawal_addresses( + withdraw_map: Vec<(Plaintext, Value)>, + ) -> Result, Address>> { + // Convert the given key and value into a staker entry. + let convert = |key, value| { + // Extract the staker from the key. + let staker = match key { + Plaintext::Literal(Literal::Address(address), _) => address, + _ => bail!("Invalid withdraw key (missing staker) - {key}"), + }; + + // Extract the withdrawal address from the value. + let withdrawal_address = match value { + Value::Plaintext(Plaintext::Literal(Literal::Address(address), _)) => address, + _ => bail!("Invalid withdraw value (missing address) - {key}"), + }; + + Ok((staker, withdrawal_address)) + }; + + // Convert the withdraw map into withdrawal addresses. + withdraw_map.into_iter().map(|(key, value)| convert(key, value)).collect::>>() + } + #[test] - fn test_committee_map_into_committee() { + fn test_committee_and_delegated_maps_into_committee() { let rng = &mut TestRng::default(); // Sample a committee. @@ -337,11 +471,16 @@ mod tests { // Initialize the committee map. let committee_map = to_committee_map(committee.members()); + // Initialize the delegated map. + let delegated_map = to_delegated_map(committee.members()); + // Start a timer. let timer = std::time::Instant::now(); // Convert the committee map into a committee. - let candidate_committee = committee_map_into_committee(committee.starting_round(), committee_map).unwrap(); - println!("committee_map_into_committee: {}ms", timer.elapsed().as_millis()); + let candidate_committee = + committee_and_delegated_maps_into_committee(committee.starting_round(), committee_map, delegated_map) + .unwrap(); + println!("committee_and_delegated_maps_into_committee: {}ms", timer.elapsed().as_millis()); assert_eq!(candidate_committee, committee); } @@ -389,34 +528,59 @@ mod tests { // Sample a committee. let committee = ledger_committee::test_helpers::sample_committee_for_round_and_size(1, 100, rng); // Convert the committee into stakers. - let stakers = crate::committee::test_helpers::to_stakers(committee.members(), rng); + let _stakers = crate::committee::test_helpers::to_stakers(committee.members(), rng); + // Convert the committee into delegations. + let delegations = crate::committee::test_helpers::to_delegations(committee.members()); // Start a timer. let timer = std::time::Instant::now(); // Ensure the next committee matches the current committee. // Note: We can perform this check, in this specific case only, because we did not apply staking rewards. - let next_committee = to_next_committee(&committee, committee.starting_round() + 1, &stakers).unwrap(); + let next_committee = to_next_committee(&committee, committee.starting_round() + 1, &delegations).unwrap(); println!("to_next_committee: {}ms", timer.elapsed().as_millis()); assert_eq!(committee.starting_round() + 1, next_committee.starting_round()); assert_eq!(committee.members(), next_committee.members()); } #[test] - fn test_to_next_commitee_map_and_bonded_map() { + fn test_to_next_committee_bonded_delegated_map() { let rng = &mut TestRng::default(); // Sample a committee. let committee = ledger_committee::test_helpers::sample_committee(rng); // Convert the committee into stakers. - let stakers = crate::committee::test_helpers::to_stakers(committee.members(), rng); + let stakers: IndexMap, (Address, u64)> = + crate::committee::test_helpers::to_stakers(committee.members(), rng); + // Convert the committee into delegations. + let delegations = crate::committee::test_helpers::to_delegations(committee.members()); // Start a timer. let timer = std::time::Instant::now(); // Ensure the next committee matches the current committee. // Note: We can perform this check, in this specific case only, because we did not apply staking rewards. - let (committee_map, bonded_map) = to_next_commitee_map_and_bonded_map(&committee, &stakers); - println!("to_next_commitee_map_and_bonded_map: {}ms", timer.elapsed().as_millis()); + let (committee_map, bonded_map, _) = to_next_committee_bonded_delegated_map(&committee, &stakers, &delegations); + println!("to_next_committee_bonded_delegated_map: {}ms", timer.elapsed().as_millis()); assert_eq!(committee_map, to_committee_map(committee.members())); assert_eq!(bonded_map, to_bonded_map(&stakers)); } + + #[test] + fn test_to_withdraw_map() { + let rng = &mut TestRng::default(); + + // Sample a committee. + let committee = ledger_committee::test_helpers::sample_committee(rng); + // Convert the committee into stakers. + let stakers = crate::committee::test_helpers::to_stakers(committee.members(), rng); + + // Construct the withdraw addresses. + let withdrawal_addresses = crate::committee::test_helpers::to_withdraw_addresses(&stakers, rng); + + // Start a timer. + let timer = std::time::Instant::now(); + // Ensure the withdrawal map is correct. + let withdrawal_map = to_next_withdraw_map(&withdrawal_addresses); + println!("to_next_withdraw_map: {}ms", timer.elapsed().as_millis()); + assert_eq!(withdrawal_addresses, withdraw_map_to_withdrawal_addresses(withdrawal_map).unwrap()); + } } diff --git a/synthesizer/src/vm/helpers/cost.rs b/synthesizer/src/vm/helpers/cost.rs deleted file mode 100644 index 6f349baa84..0000000000 --- a/synthesizer/src/vm/helpers/cost.rs +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. -// This file is part of the snarkVM library. - -// 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::VM; -use console::{ - prelude::*, - program::{LiteralType, PlaintextType}, -}; -use ledger_block::{Deployment, Execution}; -use ledger_store::ConsensusStorage; -use synthesizer_program::{Command, Finalize, Instruction}; - -use std::collections::HashMap; - -/// Returns the *minimum* cost in microcredits to publish the given deployment (total cost, (storage cost, namespace cost)). -pub fn deployment_cost(deployment: &Deployment) -> Result<(u64, (u64, u64))> { - // Determine the number of bytes in the deployment. - let size_in_bytes = deployment.size_in_bytes()?; - // Retrieve the program ID. - let program_id = deployment.program_id(); - // Determine the number of characters in the program ID. - let num_characters = u32::try_from(program_id.name().to_string().len())?; - - // Compute the storage cost in microcredits. - let storage_cost = size_in_bytes - .checked_mul(N::DEPLOYMENT_FEE_MULTIPLIER) - .ok_or(anyhow!("The storage cost computation overflowed for a deployment"))?; - - // Compute the namespace cost in credits: 10^(10 - num_characters). - let namespace_cost = 10u64 - .checked_pow(10u32.saturating_sub(num_characters)) - .ok_or(anyhow!("The namespace cost computation overflowed for a deployment"))? - .saturating_mul(1_000_000); // 1 microcredit = 1e-6 credits. - - // Compute the total cost in microcredits. - let total_cost = storage_cost - .checked_add(namespace_cost) - .ok_or(anyhow!("The total cost computation overflowed for a deployment"))?; - - Ok((total_cost, (storage_cost, namespace_cost))) -} - -/// Returns the *minimum* cost in microcredits to publish the given execution (total cost, (storage cost, namespace cost)). -pub fn execution_cost>( - vm: &VM, - execution: &Execution, -) -> Result<(u64, (u64, u64))> { - // Compute the storage cost in microcredits. - let storage_cost = execution.size_in_bytes()?; - - // Prepare the program lookup. - let lookup = execution - .transitions() - .map(|transition| { - let program_id = transition.program_id(); - Ok((*program_id, vm.process().read().get_program(program_id)?.clone())) - }) - .collect::>>()?; - - // Compute the finalize cost in microcredits. - let mut finalize_cost = 0u64; - // Iterate over the transitions to accumulate the finalize cost. - for transition in execution.transitions() { - // Retrieve the program ID. - let program_id = transition.program_id(); - // Retrieve the function name. - let function_name = transition.function_name(); - // Retrieve the program. - let program = lookup.get(program_id).ok_or(anyhow!("Program '{program_id}' is missing"))?; - // Retrieve the finalize cost. - let cost = match program.get_function(function_name)?.finalize_logic() { - Some(finalize) => cost_in_microcredits(finalize)?, - None => continue, - }; - // Accumulate the finalize cost. - finalize_cost = finalize_cost - .checked_add(cost) - .ok_or(anyhow!("The finalize cost computation overflowed for an execution"))?; - } - - // Compute the total cost in microcredits. - let total_cost = storage_cost - .checked_add(finalize_cost) - .ok_or(anyhow!("The total cost computation overflowed for an execution"))?; - - Ok((total_cost, (storage_cost, finalize_cost))) -} - -/// Returns the minimum number of microcredits required to run the finalize. -pub fn cost_in_microcredits(finalize: &Finalize) -> Result { - // Defines the cost of each command. - let cost = |command: &Command| match command { - Command::Instruction(Instruction::Abs(_)) => Ok(2_000), - Command::Instruction(Instruction::AbsWrapped(_)) => Ok(2_000), - Command::Instruction(Instruction::Add(_)) => Ok(2_000), - Command::Instruction(Instruction::AddWrapped(_)) => Ok(2_000), - Command::Instruction(Instruction::And(_)) => Ok(2_000), - Command::Instruction(Instruction::AssertEq(_)) => Ok(2_000), - Command::Instruction(Instruction::AssertNeq(_)) => Ok(2_000), - Command::Instruction(Instruction::Async(_)) => bail!("`async` is not supported in finalize."), - Command::Instruction(Instruction::Call(_)) => bail!("`call` is not supported in finalize."), - Command::Instruction(Instruction::Cast(_)) => Ok(2_000), - Command::Instruction(Instruction::CastLossy(_)) => Ok(2_000), - Command::Instruction(Instruction::CommitBHP256(_)) => Ok(200_000), - Command::Instruction(Instruction::CommitBHP512(_)) => Ok(200_000), - Command::Instruction(Instruction::CommitBHP768(_)) => Ok(200_000), - Command::Instruction(Instruction::CommitBHP1024(_)) => Ok(200_000), - Command::Instruction(Instruction::CommitPED64(_)) => Ok(100_000), - Command::Instruction(Instruction::CommitPED128(_)) => Ok(100_000), - Command::Instruction(Instruction::Div(_)) => Ok(10_000), - Command::Instruction(Instruction::DivWrapped(_)) => Ok(2_000), - Command::Instruction(Instruction::Double(_)) => Ok(2_000), - Command::Instruction(Instruction::GreaterThan(_)) => Ok(2_000), - Command::Instruction(Instruction::GreaterThanOrEqual(_)) => Ok(2_000), - Command::Instruction(Instruction::HashBHP256(_)) => Ok(100_000), - Command::Instruction(Instruction::HashBHP512(_)) => Ok(100_000), - Command::Instruction(Instruction::HashBHP768(_)) => Ok(100_000), - Command::Instruction(Instruction::HashBHP1024(_)) => Ok(100_000), - Command::Instruction(Instruction::HashKeccak256(_)) => Ok(100_000), - Command::Instruction(Instruction::HashKeccak384(_)) => Ok(100_000), - Command::Instruction(Instruction::HashKeccak512(_)) => Ok(100_000), - Command::Instruction(Instruction::HashPED64(_)) => Ok(20_000), - Command::Instruction(Instruction::HashPED128(_)) => Ok(30_000), - Command::Instruction(Instruction::HashPSD2(hash)) => match hash.destination_type() { - PlaintextType::Literal(LiteralType::Address) | PlaintextType::Literal(LiteralType::Group) => Ok(600_000), - PlaintextType::Literal(..) => Ok(60_000), - plaintext_type => bail!("`hash.psd2` is not supported for plaintext type '{plaintext_type}'"), - }, - Command::Instruction(Instruction::HashPSD4(hash)) => match hash.destination_type() { - PlaintextType::Literal(LiteralType::Address) | PlaintextType::Literal(LiteralType::Group) => Ok(700_000), - PlaintextType::Literal(..) => Ok(100_000), - plaintext_type => bail!("`hash.psd4` is not supported for plaintext type '{plaintext_type}'"), - }, - Command::Instruction(Instruction::HashPSD8(hash)) => match hash.destination_type() { - PlaintextType::Literal(LiteralType::Address) | PlaintextType::Literal(LiteralType::Group) => Ok(800_000), - PlaintextType::Literal(..) => Ok(200_000), - plaintext_type => bail!("`hash.psd8` is not supported for plaintext type '{plaintext_type}'"), - }, - Command::Instruction(Instruction::HashSha3_256(_)) => Ok(100_000), - Command::Instruction(Instruction::HashSha3_384(_)) => Ok(100_000), - Command::Instruction(Instruction::HashSha3_512(_)) => Ok(100_000), - Command::Instruction(Instruction::HashManyPSD2(_)) => { - bail!("`hash_many.psd2` is not supported in finalize.") - } - Command::Instruction(Instruction::HashManyPSD4(_)) => { - bail!("`hash_many.psd4` is not supported in finalize.") - } - Command::Instruction(Instruction::HashManyPSD8(_)) => { - bail!("`hash_many.psd8` is not supported in finalize.") - } - Command::Instruction(Instruction::Inv(_)) => Ok(10_000), - Command::Instruction(Instruction::IsEq(_)) => Ok(2_000), - Command::Instruction(Instruction::IsNeq(_)) => Ok(2_000), - Command::Instruction(Instruction::LessThan(_)) => Ok(2_000), - Command::Instruction(Instruction::LessThanOrEqual(_)) => Ok(2_000), - Command::Instruction(Instruction::Modulo(_)) => Ok(2_000), - Command::Instruction(Instruction::Mul(_)) => Ok(150_000), - Command::Instruction(Instruction::MulWrapped(_)) => Ok(2_000), - Command::Instruction(Instruction::Nand(_)) => Ok(2_000), - Command::Instruction(Instruction::Neg(_)) => Ok(2_000), - Command::Instruction(Instruction::Nor(_)) => Ok(2_000), - Command::Instruction(Instruction::Not(_)) => Ok(2_000), - Command::Instruction(Instruction::Or(_)) => Ok(2_000), - Command::Instruction(Instruction::Pow(_)) => Ok(20_000), - Command::Instruction(Instruction::PowWrapped(_)) => Ok(2_000), - Command::Instruction(Instruction::Rem(_)) => Ok(2_000), - Command::Instruction(Instruction::RemWrapped(_)) => Ok(2_000), - Command::Instruction(Instruction::SignVerify(_)) => Ok(250_000), - Command::Instruction(Instruction::Shl(_)) => Ok(2_000), - Command::Instruction(Instruction::ShlWrapped(_)) => Ok(2_000), - Command::Instruction(Instruction::Shr(_)) => Ok(2_000), - Command::Instruction(Instruction::ShrWrapped(_)) => Ok(2_000), - Command::Instruction(Instruction::Square(_)) => Ok(2_000), - Command::Instruction(Instruction::SquareRoot(_)) => Ok(120_000), - Command::Instruction(Instruction::Sub(_)) => Ok(10_000), - Command::Instruction(Instruction::SubWrapped(_)) => Ok(2_000), - Command::Instruction(Instruction::Ternary(_)) => Ok(2_000), - Command::Instruction(Instruction::Xor(_)) => Ok(2_000), - // TODO: The following 'finalize' commands are currently priced higher than expected. - // Expect these numbers to change as their usage is stabilized. - Command::Await(_) => Ok(2_000), - Command::Contains(_) => Ok(12_500), - Command::Get(_) => Ok(25_000), - Command::GetOrUse(_) => Ok(25_000), - Command::RandChaCha(_) => Ok(25_000), - Command::Remove(_) => Ok(10_000), - Command::Set(_) => Ok(100_000), - Command::BranchEq(_) | Command::BranchNeq(_) => Ok(5_000), - Command::Position(_) => Ok(1_000), - }; - finalize - .commands() - .iter() - .map(cost) - .try_fold(0u64, |acc, res| res.and_then(|x| acc.checked_add(x).ok_or(anyhow!("Finalize cost overflowed")))) -} diff --git a/synthesizer/src/vm/helpers/history.rs b/synthesizer/src/vm/helpers/history.rs new file mode 100644 index 0000000000..568d93f624 --- /dev/null +++ b/synthesizer/src/vm/helpers/history.rs @@ -0,0 +1,130 @@ +// Copyright 2024 Aleo Network Foundation +// This file is part of the snarkVM library. + +// 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 console::prelude::{Deserialize, Serialize}; + +use aleo_std::{StorageMode, aleo_ledger_dir}; + +use anyhow::Result; +use serde_json; +use std::{ + fmt::{Display, Formatter}, + path::PathBuf, +}; + +/// Returns the path where a `history` directory may be stored. +pub fn history_directory_path(network: u16, storage_mode: &StorageMode) -> PathBuf { + const HISTORY_DIRECTORY_NAME: &str = "history"; + + // Create the name of the history directory. + let directory_name = match &storage_mode { + StorageMode::Development(id) => format!(".{HISTORY_DIRECTORY_NAME}-{network}-{id}"), + StorageMode::Production | StorageMode::Custom(_) => format!("{HISTORY_DIRECTORY_NAME}-{network}"), + }; + + // Obtain the path to the ledger. + let mut path = aleo_ledger_dir(network, storage_mode.clone()); + // Go to the folder right above the ledger. + path.pop(); + // Append the history directory's name. + path.push(directory_name); + + path +} + +#[derive(Copy, Clone, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum MappingName { + /// The `bonded` mapping. + Bonded, + /// The `delegated` mapping. + Delegated, + /// The `metadata` mapping. + Metadata, + /// The `unbonding` mapping. + Unbonding, + /// The `withdraw` mapping. + Withdraw, +} + +impl Display for MappingName { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::Bonded => write!(f, "bonded"), + Self::Delegated => write!(f, "delegated"), + Self::Metadata => write!(f, "metadata"), + Self::Unbonding => write!(f, "unbonding"), + Self::Withdraw => write!(f, "withdraw"), + } + } +} + +pub struct History { + /// The path to the history directory. + path: PathBuf, +} + +impl History { + /// Initializes a new instance of `History`. + pub fn new(network: u16, storage_mode: &StorageMode) -> Self { + Self { path: history_directory_path(network, storage_mode) } + } + + /// Stores a mapping from a given block in the history directory as JSON. + pub fn store_mapping(&self, height: u32, mapping: MappingName, data: &T) -> Result<()> + where + T: Serialize + ?Sized, + { + // Get the path to the block directory. + let path = self.block_path(height); + // Create the block directory if it does not exist. + if !path.exists() { + std::fs::create_dir_all(&path)?; + } + + // Write the entry to the block directory. + let path = path.join(format!("block-{height}-{mapping}.json")); + std::fs::write(path, serde_json::to_string_pretty(data)?)?; + + Ok(()) + } + + /// Loads the JSON string for a mapping from a given block from the history directory. + pub fn load_mapping(&self, height: u32, mapping: MappingName) -> Result { + // Get the path to the block directory. + let path = self.block_path(height); + // Get the path to the block file. + let path = path.join(format!("block-{height}-{mapping}.json")); + + // Read the file. + let data = std::fs::read_to_string(path)?; + + Ok(data) + } + + // A helper function to get the path to the block directory. + fn block_path(&self, height: u32) -> PathBuf { + // Get the path the directory group. + let group = Self::group(height); + let path = self.path.join(format!("group-{group}")); + // Get the path to the block directory. + path.join(format!("block-{height}")) + } + + // A helper function to calculate the group number for a given block height. + fn group(height: u32) -> u32 { + height.saturating_div(u16::MAX as u32) + } +} diff --git a/synthesizer/src/vm/helpers/macros.rs b/synthesizer/src/vm/helpers/macros.rs index 16911566e3..0309e825ef 100644 --- a/synthesizer/src/vm/helpers/macros.rs +++ b/synthesizer/src/vm/helpers/macros.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,19 +16,19 @@ /// A helper macro to downcast a `$variable` to `$object<$network>`. #[macro_export] macro_rules! cast_ref { - // Example: cast_ref!((foo.bar()) as Bar) + // Example: cast_ref!((foo.bar()) as Bar) (($variable:expr) as $object:ident<$($traits:path),+>) => {{ (&$variable as &dyn std::any::Any) .downcast_ref::<$object<$($traits),+>>() .ok_or_else(|| anyhow!("Failed to downcast {}", stringify!($variable)))? }}; - // Example: cast_ref!(bar as Bar) + // Example: cast_ref!(bar as Bar) ($variable:ident as $object:ident<$($traits:path),+>) => {{ (&$variable as &dyn std::any::Any) .downcast_ref::<$object<$($traits),+>>() .ok_or_else(|| anyhow!("Failed to downcast {}", stringify!($variable)))? }}; - // Example: cast_ref!(&bar as Bar) + // Example: cast_ref!(&bar as Bar) (&$variable:ident as $object:ident<$($traits:path),+>) => {{ ($variable as &dyn std::any::Any) .downcast_ref::<$object<$($traits),+>>() @@ -38,13 +39,13 @@ macro_rules! cast_ref { /// A helper macro to downcast a `$variable` to `&mut $object<$network>`. #[macro_export] macro_rules! cast_mut_ref { - // Example: cast_mut_ref!((foo.bar()) as Bar) + // Example: cast_mut_ref!((foo.bar()) as Bar) (($variable:expr) as $object:ident<$($traits:path),+>) => {{ (&mut $variable as &mut dyn std::any::Any) .downcast_mut::<$object<$($traits),+>>() .ok_or_else(|| anyhow!("Failed to downcast mut {}", stringify!($variable)))? }}; - // Example: cast_mut_ref!(bar as Bar) + // Example: cast_mut_ref!(bar as Bar) ($variable:ident as $object:ident<$($traits:path),+>) => {{ (&mut $variable as &mut dyn std::any::Any) .downcast_mut::<$object<$($traits),+>>() @@ -52,19 +53,58 @@ macro_rules! cast_mut_ref { }}; } +/// A helper macro to dedup the `Network` trait and `Aleo` trait and process its given logic. +#[macro_export] +macro_rules! convert { + // Example: convert!(logic) + ($logic:ident) => {{ + match N::ID { + console::network::MainnetV0::ID => { + // Process the logic. + $logic!(console::network::MainnetV0, circuit::AleoV0) + } + console::network::TestnetV0::ID => { + // Process the logic. + $logic!(console::network::TestnetV0, circuit::AleoTestnetV0) + } + console::network::CanaryV0::ID => { + // Process the logic. + $logic!(console::network::CanaryV0, circuit::AleoCanaryV0) + } + _ => bail!("Unsupported VM configuration for network: {}", N::ID), + } + }}; +} + /// A helper macro to dedup the `Network` trait and `Aleo` trait and process its given logic. #[macro_export] macro_rules! process { // Example: process!(self, logic) ($self:ident, $logic:ident) => {{ match N::ID { - console::network::Testnet3::ID => { + console::network::MainnetV0::ID => { + // Cast the process. + let process = (&$self.process as &dyn std::any::Any) + .downcast_ref::>>>() + .ok_or_else(|| anyhow!("Failed to downcast {}", stringify!($self.process)))?; + // Process the logic. + $logic!(process.read(), console::network::MainnetV0, circuit::AleoV0) + } + console::network::TestnetV0::ID => { + // Cast the process. + let process = (&$self.process as &dyn std::any::Any) + .downcast_ref::>>>() + .ok_or_else(|| anyhow!("Failed to downcast {}", stringify!($self.process)))?; + // Process the logic. + $logic!(process.read(), console::network::TestnetV0, circuit::AleoTestnetV0) + } + console::network::CanaryV0::ID => { // Cast the process. let process = (&$self.process as &dyn std::any::Any) - .downcast_ref::>>>() + .downcast_ref::>>>() .ok_or_else(|| anyhow!("Failed to downcast {}", stringify!($self.process)))?; // Process the logic. - $logic!(process.read(), console::network::Testnet3, circuit::AleoV0) + $logic!(process.read(), console::network::CanaryV0, circuit::AleoCanaryV0) } _ => bail!("Unsupported VM configuration for network: {}", N::ID), } diff --git a/synthesizer/src/vm/helpers/mod.rs b/synthesizer/src/vm/helpers/mod.rs index 2ef9403bee..bb9ae9dcd8 100644 --- a/synthesizer/src/vm/helpers/mod.rs +++ b/synthesizer/src/vm/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -15,8 +16,10 @@ pub(crate) mod committee; pub use committee::*; -mod cost; -pub use cost::*; +#[cfg(feature = "history")] +mod history; +#[cfg(feature = "history")] +pub use history::*; mod macros; diff --git a/synthesizer/src/vm/helpers/rewards.rs b/synthesizer/src/vm/helpers/rewards.rs index ae5f9d4fba..54ac028a26 100644 --- a/synthesizer/src/vm/helpers/rewards.rs +++ b/synthesizer/src/vm/helpers/rewards.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -23,16 +24,23 @@ use rayon::prelude::*; /// A safety bound (sanity-check) for the coinbase reward. const MAX_COINBASE_REWARD: u64 = ledger_block::MAX_COINBASE_REWARD; // Coinbase reward at block 1. -/// Returns the updated stakers reflecting the staking rewards for the given committee and block reward. -/// The staking reward is defined as: `block_reward * stake / total_stake`. +/// Returns the updated stakers reflecting the staking rewards for the given committee, block reward, +/// and validator commission rates. +/// +/// The staking reward for validators is defined as: `block_reward * stake / total_stake + commission_to_recieve`. +/// The commission to receive for validators is defined as: `block_reward * (total_stake_delegated / total_stake) * (rate / 100)`. +/// +/// The staking reward for delegators is defined as: `block_reward * stake / total_stake - commission_to_pay`. +/// The commission to pay for delegators is defined as: `block_reward * (stake / total_stake) * (rate / 100)` /// /// This method ensures that stakers who are bonded to validators with more than **25%** /// of the total stake will not receive a staking reward. In addition, this method -/// ensures stakers who have less than 10 credit are not eligible for a staking reward. +/// ensures delegators who have less than 10,000 credits are not eligible for a staking reward. /// -/// The choice of 25% is to ensure at least 4 validators are operational at any given time, -/// since our security model adheres to 3f+1, where f=1. As such, we tolerate Byzantine behavior -/// up to 33% of the total stake. +/// The choice of 25% is to ensure at least 4 validators are operational at any given time. +/// Our security model tolerates Byzantines behavior by validators staking up to f stake, +/// where f = max{m: integer | m < N/3}, N being the total amount staked. +/// Therefore, 1 Byzantine validator out of 4 equal-staked validators will be tolerated. pub fn staking_rewards( stakers: &IndexMap, (Address, u64)>, committee: &Committee, @@ -46,13 +54,26 @@ pub fn staking_rewards( // Compute the updated stakers. cfg_iter!(stakers) .map(|(staker, (validator, stake))| { + // If the validator is not in the committee, skip the staker. + let Some((validator_stake, _is_open, commission_rate)) = committee.members().get(validator) else { + trace!("Validator {validator} is not in the committee - skipping {staker}"); + return (*staker, (*validator, *stake)); + }; + + // If the commission rate is greater than 100, skip the staker. + if *commission_rate > 100 { + error!("Commission rate ({commission_rate}) is greater than 100 - skipping {staker}"); + return (*staker, (*validator, *stake)); + } + // If the validator has more than 25% of the total stake, skip the staker. - if committee.get_stake(*validator) > committee.total_stake().saturating_div(4) { + if *validator_stake > committee.total_stake().saturating_div(4) { trace!("Validator {validator} has more than 25% of the total stake - skipping {staker}"); return (*staker, (*validator, *stake)); } - // If the staker has less than the minimum required stake, skip the staker. - if *stake < MIN_DELEGATOR_STAKE { + + // If the staker has less than the minimum required stake, skip the staker, unless the staker is the validator. + if *stake < MIN_DELEGATOR_STAKE && *staker != *validator { trace!("Staker has less than {MIN_DELEGATOR_STAKE} microcredits - skipping {staker}"); return (*staker, (*validator, *stake)); } @@ -72,8 +93,47 @@ pub fn staking_rewards( // Cast the staking reward as a u64. // Note: This '.expect' is guaranteed to be safe, as we ensure the quotient is within a safe bound. let staking_reward = u64::try_from(quotient).expect("Staking reward is too large"); + + // Update the staking reward with the commission. + // + // Note: This approach to computing commissions is far more computationally-efficient, + // however it does introduce a small (deterministic) precision error that is accepted for the + // sake of performance. There is a negligible difference (at most 100 microcredits per delegator) + // between the validators (+) and the delegators (-) in the allocated commission difference. + let staking_reward_after_commission = match staker == validator { + // If the staker is the validator, add the total commission to the staking reward. + true => { + // Calculate the total stake delegated to the validator. + let total_delegated_stake = validator_stake.saturating_sub(*stake); + // Compute the numerator. + let numerator = (block_reward as u128).saturating_mul(total_delegated_stake as u128); + // Compute the quotient. This quotient is the total staking reward recieved by delegators. + let quotient = numerator.saturating_div(denominator); + // Compute the commission. + let total_commission_to_receive = + quotient.saturating_mul(*commission_rate as u128).saturating_div(100u128); + // Cast the commission as a u64. + // Note: This '.expect' is guaranteed to be safe, as we ensure the commission is within a safe bound. + let total_commission_to_receive = + u64::try_from(total_commission_to_receive).expect("Commission is too large"); + + // Add the commission to the validator staking reward. + staking_reward.saturating_add(total_commission_to_receive) + } + // If the staker is a delegator, subtract the commission from the staking reward. + false => { + // Calculate the commission. + let commission = quotient.saturating_mul(*commission_rate as u128).saturating_div(100u128); + // Cast the commission as a u64. + // Note: This '.expect' is guaranteed to be safe, as we ensure the quotient is within a safe bound. + let commission_to_pay = u64::try_from(commission).expect("Commission is too large"); + + // Subtract the commission from the delegator staking reward. + staking_reward.saturating_sub(commission_to_pay) + } + }; // Return the staker and the updated stake. - (*staker, (*validator, stake.saturating_add(staking_reward))) + (*staker, (*validator, stake.saturating_add(staking_reward_after_commission))) }) .collect() } @@ -131,7 +191,7 @@ mod tests { use indexmap::indexmap; - type CurrentNetwork = console::network::Testnet3; + type CurrentNetwork = console::network::MainnetV0; const ITERATIONS: usize = 1000; @@ -139,7 +199,7 @@ mod tests { fn test_staking_rewards() { let rng = &mut TestRng::default(); // Sample a random committee. - let committee = ledger_committee::test_helpers::sample_committee(rng); + let committee = ledger_committee::test_helpers::sample_committee_with_commissions(rng); // Sample a random block reward. let block_reward = rng.gen_range(0..MAX_COINBASE_REWARD); // Retrieve an address. @@ -160,6 +220,119 @@ mod tests { } } + #[test] + fn test_staking_rewards_to_validator_not_in_committee() { + let rng = &mut TestRng::default(); + // Sample a random committee. + let committee = ledger_committee::test_helpers::sample_committee(rng); + let fake_committee = ledger_committee::test_helpers::sample_committee(rng); + // Sample a random block reward. + let block_reward = rng.gen_range(0..MAX_COINBASE_REWARD); + + // Generate the stakers + let stakers = crate::committee::test_helpers::to_stakers(committee.members(), rng); + // Generate stakers for a non-existent committee, to ensure they are not rewarded. + let stakers_fake = crate::committee::test_helpers::to_stakers(fake_committee.members(), rng); + let all_stakers: IndexMap, (Address, u64)> = + stakers.clone().into_iter().chain(stakers_fake.clone()).collect(); + + // Start a timer. + let timer = std::time::Instant::now(); + + let next_stakers = staking_rewards::(&all_stakers, &committee, block_reward); + println!("staking_rewards: {}ms", timer.elapsed().as_millis()); + assert_eq!(next_stakers.len(), all_stakers.len()); + for ((staker, (validator, stake)), (next_staker, (next_validator, next_stake))) in + all_stakers.into_iter().zip(next_stakers.into_iter()) + { + assert_eq!(staker, next_staker); + assert_eq!(validator, next_validator); + // If the validator is not in the committee, the stake should not change. + if !committee.members().contains_key(&validator) { + assert_eq!(stake, next_stake, "stake: {stake}, reward should be 0"); + } else { + // Otherwise, the stake should increase. + let reward = block_reward as u128 * stake as u128 / committee.total_stake() as u128; + assert_eq!(stake + u64::try_from(reward).unwrap(), next_stake, "stake: {stake}, reward: {reward}"); + } + } + } + + #[test] + fn test_staking_rewards_commission() { + let rng = &mut TestRng::default(); + // Sample a random committee. + let committee = ledger_committee::test_helpers::sample_committee_with_commissions(rng); + // Convert the committee into stakers. + let stakers = crate::committee::test_helpers::to_stakers(committee.members(), rng); + // Sample a random block reward. + let block_reward = rng.gen_range(0..MAX_COINBASE_REWARD); + // Create a map of validators to commissions + let commissions: IndexMap, u8> = + committee.members().iter().map(|(address, (_, _, commission))| (*address, *commission)).collect(); + // Print the commissions from the indexmap + println!("commissions: {:?}", commissions); + // Create a map of validators to the sum of their commissions + let mut total_commissions: IndexMap, u64> = Default::default(); + + // Start a timer. + let timer = std::time::Instant::now(); + // Compute the staking rewards. + let next_stakers = staking_rewards::(&stakers, &committee, block_reward); + println!("staking_rewards: {}ms", timer.elapsed().as_millis()); + assert_eq!(next_stakers.len(), stakers.len()); + for ((staker, (validator, stake)), (next_staker, (next_validator, next_stake))) in + stakers.clone().into_iter().zip(next_stakers.clone().into_iter()) + { + assert_eq!(staker, next_staker); + assert_eq!(validator, next_validator); + + let commission_rate = commissions.get(&validator).copied().unwrap_or(0); + + if staker == validator { + // Calculate the total stake delegated to the validator. + let total_stake = committee.get_stake(validator); + let total_delegated_stake = total_stake.saturating_sub(stake); + + // Calculate the commission to receive. + let reward = block_reward as u128 * total_delegated_stake as u128 / committee.total_stake() as u128; + let commission_to_receive = reward * commission_rate as u128 / 100; + + total_commissions.insert(validator, u64::try_from(commission_to_receive).unwrap()); + assert_eq!( + stake + u64::try_from(reward + commission_to_receive).unwrap(), + next_stake, + "stake: {stake}, reward: {reward}, commission_to_receive: {commission_to_receive}, commission_rate: {commission_rate}" + ); + } else { + // Calculate the commission to pay the validator. + let reward = block_reward as u128 * stake as u128 / committee.total_stake() as u128; + let commission_to_pay = reward * commission_rate as u128 / 100; + + assert_eq!( + stake + u64::try_from(reward - commission_to_pay).unwrap(), + next_stake, + "stake: {stake}, reward: {reward}, commission_to_pay: {commission_to_pay}, commission_rate: {commission_rate}" + ); + } + } + + assert_eq!( + total_commissions.len(), + committee.members().len(), + "total_commissions.len() != committee.members().len()" + ); + + // For each staker that is a validator, ensure the next staker = reward + commission. + for (validator, commission) in total_commissions { + let (_, stake) = stakers.get(&validator).unwrap(); + let (_, next_stake) = next_stakers.get(&validator).unwrap(); + let reward = block_reward as u128 * *stake as u128 / committee.total_stake() as u128; + let expected_stake = stake + commission + u64::try_from(reward).unwrap(); + assert_eq!(*next_stake, expected_stake, "stake: {stake}, commission: {commission}"); + } + } + #[test] fn test_staking_rewards_large() { let rng = &mut TestRng::default(); @@ -188,14 +361,16 @@ mod tests { } #[test] - fn test_staking_rewards_when_staker_is_under_min_yields_no_reward() { + fn test_staking_rewards_when_delegator_is_under_min_yields_no_reward() { let rng = &mut TestRng::default(); // Sample a random committee. let committee = ledger_committee::test_helpers::sample_committee(rng); + // Convert the committee into stakers. + let stakers = crate::committee::test_helpers::to_stakers(committee.members(), rng); // Sample a random block reward. let block_reward = rng.gen_range(0..MAX_COINBASE_REWARD); - // Retrieve an address. - let address = *committee.members().iter().next().unwrap().0; + // Retrieve an address of a delegator that isn't a validator + let address = *stakers.iter().find(|(address, _)| !committee.is_committee_member(**address)).unwrap().0; for _ in 0..ITERATIONS { // Sample a random stake. diff --git a/synthesizer/src/vm/mod.rs b/synthesizer/src/vm/mod.rs index d7f7912c9a..72b7166b70 100644 --- a/synthesizer/src/vm/mod.rs +++ b/synthesizer/src/vm/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -21,11 +22,11 @@ mod execute; mod finalize; mod verify; -use crate::{cast_mut_ref, cast_ref, process}; +use crate::{Restrictions, cast_mut_ref, cast_ref, convert, process}; use console::{ account::{Address, PrivateKey}, network::prelude::*, - program::{Identifier, Literal, Locator, Plaintext, ProgramID, ProgramOwner, Record, Value}, + program::{Argument, Identifier, Literal, Locator, Plaintext, ProgramID, ProgramOwner, Record, Value}, types::{Field, Group, U64}, }; use ledger_block::{ @@ -35,17 +36,19 @@ use ledger_block::{ Execution, Fee, Header, + Output, Ratifications, Ratify, Rejected, + Solutions, Transaction, Transactions, }; -use ledger_coinbase::CoinbaseSolution; use ledger_committee::Committee; -use ledger_query::Query; +use ledger_narwhal_data::Data; +use ledger_puzzle::Puzzle; +use ledger_query::{Query, QueryTrait}; use ledger_store::{ - atomic_finalize, BlockStore, ConsensusStorage, ConsensusStore, @@ -54,15 +57,19 @@ use ledger_store::{ TransactionStorage, TransactionStore, TransitionStore, + atomic_finalize, }; -use synthesizer_process::{Authorization, Process, Trace}; +use synthesizer_process::{Authorization, Process, Trace, deployment_cost, execution_cost_v1, execution_cost_v2}; use synthesizer_program::{FinalizeGlobalState, FinalizeOperation, FinalizeStoreTrait, Program}; +use utilities::try_vm_runtime; use aleo_std::prelude::{finish, lap, timer}; use indexmap::{IndexMap, IndexSet}; +use itertools::Either; use lru::LruCache; use parking_lot::{Mutex, RwLock}; -use std::{num::NonZeroUsize, sync::Arc}; +use rand::{SeedableRng, rngs::StdRng}; +use std::{collections::HashSet, num::NonZeroUsize, sync::Arc}; #[cfg(not(feature = "serial"))] use rayon::prelude::*; @@ -71,14 +78,18 @@ use rayon::prelude::*; pub struct VM> { /// The process. process: Arc>>, + /// The puzzle. + puzzle: Puzzle, /// The VM store. store: ConsensusStore, + /// A cache containing the list of recent partially-verified transactions. + partially_verified_transactions: Arc>>, + /// The restrictions list. + restrictions: Restrictions, /// The lock to guarantee atomicity over calls to speculate and finalize. atomic_lock: Arc>, /// The lock for ensuring there is no concurrency when advancing blocks. block_lock: Arc>, - /// A cache containing the list of recent partially-verified transactions. - partially_verified_transactions: Arc>>, } impl> VM { @@ -104,7 +115,7 @@ impl> VM { transaction_store: &TransactionStore, transaction_id: N::TransactionID, ) -> Result, Deployment)>> { - // Retrieve the deployment from the transaction id. + // Retrieve the deployment from the transaction ID. let deployment = match transaction_store.get_deployment(&transaction_id)? { Some(deployment) => deployment, None => bail!("Deployment transaction '{transaction_id}' is not found in storage."), @@ -126,11 +137,11 @@ impl> VM { for import_program_id in program.imports().keys() { // Add the imports to the process if does not exist yet. if !process.contains_program(import_program_id) { - // Fetch the deployment transaction id. + // Fetch the deployment transaction ID. let Some(transaction_id) = transaction_store.deployment_store().find_transaction_id_from_program_id(import_program_id)? else { - bail!("Transaction id for '{program_id}' is not found in storage."); + bail!("Transaction ID for '{program_id}' is not found in storage."); }; // Add the deployment and its imports found recursively. @@ -178,12 +189,14 @@ impl> VM { // Return the new VM. Ok(Self { process: Arc::new(RwLock::new(process)), + puzzle: Self::new_puzzle()?, store, - atomic_lock: Arc::new(Mutex::new(())), - block_lock: Arc::new(Mutex::new(())), partially_verified_transactions: Arc::new(RwLock::new(LruCache::new( - NonZeroUsize::new(Transactions::::MAX_TRANSACTIONS).unwrap(), + NonZeroUsize::new(Transactions::::MAX_TRANSACTIONS).unwrap(), ))), + restrictions: Restrictions::load()?, + atomic_lock: Arc::new(Mutex::new(())), + block_lock: Arc::new(Mutex::new(())), }) } @@ -199,11 +212,23 @@ impl> VM { self.process.clone() } + /// Returns the puzzle. + #[inline] + pub const fn puzzle(&self) -> &Puzzle { + &self.puzzle + } + /// Returns the partially-verified transactions. #[inline] - pub fn partially_verified_transactions(&self) -> Arc>> { + pub fn partially_verified_transactions(&self) -> Arc>> { self.partially_verified_transactions.clone() } + + /// Returns the restrictions. + #[inline] + pub const fn restrictions(&self) -> &Restrictions { + &self.restrictions + } } impl> VM { @@ -232,6 +257,21 @@ impl> VM { } } +impl> VM { + /// Returns a new instance of the puzzle. + pub fn new_puzzle() -> Result> { + // Initialize a new instance of the puzzle. + macro_rules! logic { + ($network:path, $aleo:path) => {{ + let puzzle = Puzzle::new::>(); + Ok(cast_ref!(puzzle as Puzzle).clone()) + }}; + } + // Initialize the puzzle. + convert!(logic) + } +} + impl> VM { /// Returns a new genesis block for a beacon chain. pub fn genesis_beacon(&self, private_key: &PrivateKey, rng: &mut R) -> Result> { @@ -239,10 +279,10 @@ impl> VM { // Construct the committee members. let members = indexmap::indexmap! { - Address::try_from(private_keys[0])? => (ledger_committee::MIN_VALIDATOR_STAKE, true), - Address::try_from(private_keys[1])? => (ledger_committee::MIN_VALIDATOR_STAKE, true), - Address::try_from(private_keys[2])? => (ledger_committee::MIN_VALIDATOR_STAKE, true), - Address::try_from(private_keys[3])? => (ledger_committee::MIN_VALIDATOR_STAKE, true), + Address::try_from(private_keys[0])? => (ledger_committee::MIN_VALIDATOR_STAKE, true, 0u8), + Address::try_from(private_keys[1])? => (ledger_committee::MIN_VALIDATOR_STAKE, true, 0u8), + Address::try_from(private_keys[2])? => (ledger_committee::MIN_VALIDATOR_STAKE, true, 0u8), + Address::try_from(private_keys[3])? => (ledger_committee::MIN_VALIDATOR_STAKE, true, 0u8), }; // Construct the committee. let committee = Committee::::new_genesis(members)?; @@ -256,8 +296,14 @@ impl> VM { Address::try_from(private_keys[2])? => remaining_supply / 4, Address::try_from(private_keys[3])? => remaining_supply / 4, }; + // Construct the bonded balances. + let bonded_balances = committee + .members() + .iter() + .map(|(address, (amount, _, _))| (*address, (*address, *address, *amount))) + .collect(); // Return the genesis block. - self.genesis_quorum(private_key, committee, public_balances, rng) + self.genesis_quorum(private_key, committee, public_balances, bonded_balances, rng) } /// Returns a new genesis block for a quorum chain. @@ -266,30 +312,46 @@ impl> VM { private_key: &PrivateKey, committee: Committee, public_balances: IndexMap, u64>, + bonded_balances: IndexMap, (Address, Address, u64)>, rng: &mut R, ) -> Result> { - // Retrieve the total stake. - let total_stake = committee.total_stake(); + // Retrieve the total bonded balance. + let total_bonded_amount = bonded_balances + .values() + .try_fold(0u64, |acc, (_, _, x)| acc.checked_add(*x).ok_or(anyhow!("Invalid bonded amount")))?; // Compute the account supply. - let account_supply = public_balances.values().fold(0u64, |acc, x| acc.saturating_add(*x)); + let account_supply = public_balances + .values() + .try_fold(0u64, |acc, x| acc.checked_add(*x).ok_or(anyhow!("Invalid account supply")))?; // Compute the total supply. - let total_supply = total_stake.checked_add(account_supply).ok_or_else(|| anyhow!("Invalid total supply"))?; + let total_supply = + total_bonded_amount.checked_add(account_supply).ok_or_else(|| anyhow!("Invalid total supply"))?; // Ensure the total supply matches. - ensure!(total_supply == N::STARTING_SUPPLY, "Invalid total supply"); + ensure!( + total_supply == N::STARTING_SUPPLY, + "Invalid total supply. Found {total_supply}, expected {}", + N::STARTING_SUPPLY + ); // Prepare the caller. let caller = Address::try_from(private_key)?; // Prepare the locator. let locator = ("credits.aleo", "transfer_public_to_private"); // Prepare the amount for each call to the function. - let amount = ledger_committee::MIN_VALIDATOR_STAKE; + let amount = public_balances + .get(&caller) + .ok_or_else(|| anyhow!("Missing public balance for {caller}"))? + .saturating_div(Block::::NUM_GENESIS_TRANSACTIONS.saturating_mul(2) as u64); // Prepare the function inputs. let inputs = [caller.to_string(), format!("{amount}_u64")]; // Prepare the ratifications. - let ratifications = vec![Ratify::Genesis(committee, public_balances)]; + let ratifications = + vec![Ratify::Genesis(Box::new(committee), Box::new(public_balances), Box::new(bonded_balances))]; // Prepare the solutions. - let solutions = None; // The genesis block does not require solutions. + let solutions = Solutions::::from(None); // The genesis block does not require solutions. + // Prepare the aborted solution IDs. + let aborted_solution_ids = vec![]; // Prepare the transactions. let transactions = (0..Block::::NUM_GENESIS_TRANSACTIONS) .map(|_| self.execute(private_key, locator, inputs.iter(), None, 0, None, rng)) @@ -299,7 +361,7 @@ impl> VM { let state = FinalizeGlobalState::new_genesis::()?; // Speculate on the ratifications, solutions, and transactions. let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = - self.speculate(state, None, ratifications, solutions.as_ref(), transactions.iter())?; + self.speculate(state, 0, None, ratifications, &solutions, transactions.iter(), rng)?; ensure!( aborted_transaction_ids.is_empty(), "Failed to initialize a genesis block - found aborted transaction IDs" @@ -317,6 +379,7 @@ impl> VM { header, ratifications, solutions, + aborted_solution_ids, transactions, aborted_transaction_ids, rng, @@ -349,7 +412,19 @@ impl> VM { self.block_store().pause_atomic_writes()?; // First, insert the block. - self.block_store().insert(block)?; + if let Err(insert_error) = self.block_store().insert(block) { + if cfg!(feature = "rocks") { + // Clear all pending atomic operations so that unpausing the atomic writes + // doesn't execute any of the queued storage operations. + self.block_store().abort_atomic(); + // Disable the atomic batch override. + // Note: This call is guaranteed to succeed (without error), because `DISCARD_BATCH == true`. + self.block_store().unpause_atomic_writes::()?; + } + + return Err(insert_error); + }; + // Next, finalize the transactions. match self.finalize(state, block.ratifications(), block.solutions(), block.transactions()) { Ok(_ratified_finalize_operations) => { @@ -368,19 +443,15 @@ impl> VM { // Note: This call is guaranteed to succeed (without error), because `DISCARD_BATCH == true`. self.block_store().unpause_atomic_writes::()?; // Rollback the Merkle tree. - self.block_store().remove_last_n_from_tree_only(1).map_err(|removal_error| { + self.block_store().remove_last_n_from_tree_only(1).inspect_err(|_| { // Log the finalize error. error!("Failed to finalize block {} - {finalize_error}", block.height()); - // Return the removal error. - removal_error })?; } else { // Rollback the block. - self.block_store().remove_last_n(1).map_err(|removal_error| { + self.block_store().remove_last_n(1).inspect_err(|_| { // Log the finalize error. error!("Failed to finalize block {} - {finalize_error}", block.height()); - // Return the removal error. - removal_error })?; } // Return the finalize error. @@ -395,19 +466,24 @@ pub(crate) mod test_helpers { use super::*; use console::{ account::{Address, ViewKey}, - network::Testnet3, - program::Value, + network::MainnetV0, + program::{Entry, Value}, types::Field, }; use ledger_block::{Block, Header, Metadata, Transition}; use ledger_store::helpers::memory::ConsensusMemory; + #[cfg(feature = "rocks")] + use ledger_store::helpers::rocksdb::ConsensusDB; + use ledger_test_helpers::{large_transaction_program, small_transaction_program}; use synthesizer_program::Program; use indexmap::IndexMap; use once_cell::sync::OnceCell; - use std::borrow::Borrow; + #[cfg(feature = "rocks")] + use std::path::Path; + use synthesizer_snark::VerifyingKey; - pub(crate) type CurrentNetwork = Testnet3; + pub(crate) type CurrentNetwork = MainnetV0; /// Samples a new finalize state. pub(crate) fn sample_finalize_state(block_height: u32) -> FinalizeGlobalState { @@ -419,6 +495,12 @@ pub(crate) mod test_helpers { VM::from(ConsensusStore::open(None).unwrap()).unwrap() } + #[cfg(feature = "rocks")] + pub(crate) fn sample_vm_rocks(path: &Path) -> VM> { + // Initialize a new VM. + VM::from(ConsensusStore::open(path.to_owned()).unwrap()).unwrap() + } + pub(crate) fn sample_genesis_private_key(rng: &mut TestRng) -> PrivateKey { static INSTANCE: OnceCell> = OnceCell::new(); *INSTANCE.get_or_init(|| { @@ -671,34 +753,70 @@ function compute: .clone() } + #[cfg(feature = "test")] + pub(crate) fn create_new_transaction_with_different_fee( + rng: &mut TestRng, + transaction: Transaction, + fee: u64, + ) -> Transaction { + // Initialize a new caller. + let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + + // Initialize the genesis block. + let genesis = crate::vm::test_helpers::sample_genesis_block(rng); + + // Initialize the VM. + let vm = sample_vm(); + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Get Execution + let execution = transaction.execution().unwrap().clone(); + + // Authorize the fee. + let authorization = + vm.authorize_fee_public(&caller_private_key, fee, 100, execution.to_execution_id().unwrap(), rng).unwrap(); + // Compute the fee. + let fee = vm.execute_fee_authorization(authorization, None, rng).unwrap(); + + // Construct the transaction. + Transaction::from_execution(execution, Some(fee)).unwrap() + } + pub fn sample_next_block( - vm: &VM>, - private_key: &PrivateKey, - transactions: &[Transaction], + vm: &VM>, + private_key: &PrivateKey, + transactions: &[Transaction], rng: &mut R, - ) -> Result> { + ) -> Result> { // Get the most recent block. - let block_hash = - vm.block_store().get_block_hash(*vm.block_store().heights().max().unwrap().borrow()).unwrap().unwrap(); + let block_hash = vm.block_store().get_block_hash(vm.block_store().max_height().unwrap()).unwrap().unwrap(); let previous_block = vm.block_store().get_block(&block_hash).unwrap().unwrap(); // Construct the new block header. - let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = - vm.speculate(sample_finalize_state(1), None, vec![], None, transactions.iter())?; - assert!(aborted_transaction_ids.is_empty()); + let time_since_last_block = MainnetV0::BLOCK_TIME as i64; + let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = vm.speculate( + sample_finalize_state(1), + time_since_last_block, + None, + vec![], + &None.into(), + transactions.iter(), + rng, + )?; // Construct the metadata associated with the block. let metadata = Metadata::new( - Testnet3::ID, + MainnetV0::ID, previous_block.round() + 1, previous_block.height() + 1, 0, 0, - Testnet3::GENESIS_COINBASE_TARGET, - Testnet3::GENESIS_PROOF_TARGET, + MainnetV0::GENESIS_COINBASE_TARGET, + MainnetV0::GENESIS_PROOF_TARGET, previous_block.last_coinbase_target(), previous_block.last_coinbase_timestamp(), - Testnet3::GENESIS_TIMESTAMP + 1, + previous_block.timestamp().saturating_add(time_since_last_block), )?; let header = Header::from( @@ -717,7 +835,8 @@ function compute: previous_block.hash(), header, ratifications, - None, + None.into(), + vec![], transactions, aborted_transaction_ids, rng, @@ -850,7 +969,7 @@ finalize getter: .execute( &caller_private_key, ("test_program_1.aleo", "init"), - Vec::>::new().iter(), + Vec::>::new().iter(), Some(third_record), 1, None, @@ -861,7 +980,7 @@ finalize getter: .execute( &caller_private_key, ("test_program_2.aleo", "init"), - Vec::>::new().iter(), + Vec::>::new().iter(), Some(fourth_record), 1, None, @@ -973,17 +1092,18 @@ function a: sample_next_block(&vm, &caller_private_key, &[deployment_3.clone(), deployment_4.clone()], rng).unwrap(); vm.add_next_block(&deployment_block).unwrap(); - // Check that the iterator ordering is not the same as the deployment ordering. - let deployment_transaction_ids = - vm.transaction_store().deployment_transaction_ids().map(|id| *id).collect::>(); - // This `assert_ne` check is here to ensure that we are properly loading imports even though any order will work for `VM::from`. - // Note: `deployment_transaction_ids` is sorted lexicographically by transaction id, so the order may change if we update internal methods. - assert_ne!(deployment_transaction_ids, vec![ - deployment_1.id(), - deployment_2.id(), - deployment_3.id(), - deployment_4.id() - ]); + // Sanity check the ordering of the deployment transaction IDs from storage. + { + let deployment_transaction_ids = + vm.transaction_store().deployment_transaction_ids().map(|id| *id).collect::>(); + // This assert check is here to ensure that we are properly loading imports even though any order will work for `VM::from`. + // Note: `deployment_transaction_ids` is sorted lexicographically by transaction ID, so the order may change if we update internal methods. + assert_eq!( + deployment_transaction_ids, + vec![deployment_4.id(), deployment_3.id(), deployment_2.id(), deployment_1.id()], + "Update me if serialization has changed" + ); + } // Enforce that the VM can load properly with the imports. assert!(VM::from(vm.store.clone()).is_ok()); @@ -1038,9 +1158,9 @@ function multitransfer: // Execute the programs. let inputs = [ - Value::::Record(record_1), - Value::::from_str(&address.to_string()).unwrap(), - Value::::from_str("10u64").unwrap(), + Value::::Record(record_1), + Value::::from_str(&address.to_string()).unwrap(), + Value::::from_str("10u64").unwrap(), ]; let execution = vm .execute( @@ -1153,16 +1273,11 @@ function transfer: } #[test] - #[ignore] - fn test_deployment_memory_overload() { - const NUM_DEPLOYMENTS: usize = 32; - + fn test_internal_fee_calls_are_invalid() { let rng = &mut TestRng::default(); // Initialize a private key. let private_key = sample_genesis_private_key(rng); - - // Initialize a view key. let view_key = ViewKey::try_from(&private_key).unwrap(); // Initialize the genesis block. @@ -1173,81 +1288,1288 @@ function transfer: // Update the VM. vm.add_next_block(&genesis).unwrap(); + // Fetch the unspent records. + let records = + genesis.transitions().cloned().flat_map(Transition::into_records).take(3).collect::>(); + trace!("Unspent Records:\n{:#?}", records); + let record_0 = records.values().next().unwrap().decrypt(&view_key).unwrap(); + + // Deploy the program. + let program = Program::from_str( + r" +import credits.aleo; +program test_program.aleo; + +function call_fee_public: + input r0 as u64.private; + input r1 as u64.private; + input r2 as field.private; + call credits.aleo/fee_public r0 r1 r2 into r3; + async call_fee_public r3 into r4; + output r4 as test_program.aleo/call_fee_public.future; + +finalize call_fee_public: + input r0 as credits.aleo/fee_public.future; + await r0; + +function call_fee_private: + input r0 as credits.aleo/credits.record; + input r1 as u64.private; + input r2 as u64.private; + input r3 as field.private; + call credits.aleo/fee_private r0 r1 r2 r3 into r4; + output r4 as credits.aleo/credits.record; +", + ) + .unwrap(); + + let deployment = vm.deploy(&private_key, &program, None, 0, None, rng).unwrap(); + assert!(vm.check_transaction(&deployment, None, rng).is_ok()); + vm.add_next_block(&sample_next_block(&vm, &private_key, &[deployment], rng).unwrap()).unwrap(); + + // Execute the programs. + let internal_base_fee_amount: u64 = rng.gen_range(1..1000); + let internal_priority_fee_amount: u64 = rng.gen_range(1..1000); + + // Ensure that the transaction that calls `fee_public` internally cannot be generated. + let inputs = [ + Value::::from_str(&format!("{}u64", internal_base_fee_amount)).unwrap(), + Value::::from_str(&format!("{}u64", internal_priority_fee_amount)).unwrap(), + Value::::from_str("1field").unwrap(), + ]; + assert!( + vm.execute(&private_key, ("test_program.aleo", "call_fee_public"), inputs.into_iter(), None, 0, None, rng) + .is_err() + ); + + // Ensure that the transaction that calls `fee_private` internally cannot be generated. + let inputs = [ + Value::::Record(record_0), + Value::::from_str(&format!("{}u64", internal_base_fee_amount)).unwrap(), + Value::::from_str(&format!("{}u64", internal_priority_fee_amount)).unwrap(), + Value::::from_str("1field").unwrap(), + ]; + assert!( + vm.execute(&private_key, ("test_program.aleo", "call_fee_private"), inputs.into_iter(), None, 0, None, rng) + .is_err() + ); + } + + #[test] + fn test_deployment_synthesis_overload() { + let rng = &mut TestRng::default(); + + // Initialize a private key. + let private_key = sample_genesis_private_key(rng); + + // Initialize the genesis block. + let genesis = sample_genesis_block(rng); + + // Initialize the VM. + let vm = sample_vm(); + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + // Deploy the base program. let program = Program::from_str( r" -program program_layer_0.aleo; +program synthesis_overload.aleo; -mapping m: - key as u8.public; - value as u32.public; +function do: + input r0 as [[u128; 32u32]; 2u32].private; + hash.sha3_256 r0 into r1 as field; + output r1 as field.public;", + ) + .unwrap(); + + // Create the deployment transaction. + let deployment = vm.deploy(&private_key, &program, None, 0, None, rng).unwrap(); + + // Verify the deployment transaction. It should fail because there are too many constraints. + assert!(vm.check_transaction(&deployment, None, rng).is_err()); + } + + #[test] + fn test_deployment_num_constant_overload() { + let rng = &mut TestRng::default(); + + // Initialize a private key. + let private_key = sample_genesis_private_key(rng); + + // Initialize the genesis block. + let genesis = sample_genesis_block(rng); + + // Initialize the VM. + let vm = sample_vm(); + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + // Deploy the base program. + let program = Program::from_str( + r" +program synthesis_num_constants.aleo; function do: - input r0 as u32.public; - async do r0 into r1; - output r1 as program_layer_0.aleo/do.future; + cast 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 into r0 as [u32; 32u32]; + cast r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 into r1 as [[u32; 32u32]; 32u32]; + cast r1 r1 r1 r1 r1 into r2 as [[[u32; 32u32]; 32u32]; 5u32]; + hash.bhp1024 r2 into r3 as u32; + output r3 as u32.private; +function do2: + cast 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 0u32 into r0 as [u32; 32u32]; + cast r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 into r1 as [[u32; 32u32]; 32u32]; + cast r1 r1 r1 r1 r1 into r2 as [[[u32; 32u32]; 32u32]; 5u32]; + hash.bhp1024 r2 into r3 as u32; + output r3 as u32.private;", + ) + .unwrap(); -finalize do: - input r0 as u32.public; - set r0 into m[0u8];", + // Create the deployment transaction. + let deployment = vm.deploy(&private_key, &program, None, 0, None, rng).unwrap(); + + // Verify the deployment transaction. It should fail because there are too many constants. + let check_tx_res = vm.check_transaction(&deployment, None, rng); + assert!(check_tx_res.is_err()); + } + + #[test] + fn test_deployment_synthesis_overreport() { + let rng = &mut TestRng::default(); + + // Initialize a private key. + let private_key = sample_genesis_private_key(rng); + + // Initialize the genesis block. + let genesis = sample_genesis_block(rng); + + // Initialize the VM. + let vm = sample_vm(); + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Deploy the base program. + let program = Program::from_str( + r" +program synthesis_overreport.aleo; + +function do: + input r0 as u32.private; + add r0 r0 into r1; + output r1 as u32.public;", ) .unwrap(); - let deployment = vm.deploy(&private_key, &program, None, 0, None, rng).unwrap(); - vm.add_next_block(&sample_next_block(&vm, &private_key, &[deployment], rng).unwrap()).unwrap(); + // Create the deployment transaction. + let transaction = vm.deploy(&private_key, &program, None, 0, None, rng).unwrap(); - // For each layer, deploy a program that calls the program from the previous layer. - for i in 1..NUM_DEPLOYMENTS { - let mut program_string = String::new(); - // Add the import statements. - for j in 0..i { - program_string.push_str(&format!("import program_layer_{}.aleo;\n", j)); - } - // Add the program body. - program_string.push_str(&format!( - "program program_layer_{i}.aleo; + // Destructure the deployment transaction. + let Transaction::Deploy(_, program_owner, deployment, fee) = transaction else { + panic!("Expected a deployment transaction"); + }; -mapping m: - key as u8.public; - value as u32.public; + // Increase the number of constraints in the verifying keys. + let mut vks_with_overreport = Vec::with_capacity(deployment.verifying_keys().len()); + for (id, (vk, cert)) in deployment.verifying_keys() { + let mut vk_deref = vk.deref().clone(); + vk_deref.circuit_info.num_constraints += 1; + let vk = VerifyingKey::new(Arc::new(vk_deref), vk.num_variables()); + vks_with_overreport.push((*id, (vk, cert.clone()))); + } + + // Each additional constraint costs 25 microcredits, so we need to increase the fee by 25 microcredits. + let required_fee = *fee.base_amount().unwrap() + 25; + // Authorize a new fee. + let fee_authorization = vm + .authorize_fee_public(&private_key, required_fee, 0, deployment.as_ref().to_deployment_id().unwrap(), rng) + .unwrap(); + // Compute the fee. + let fee = vm.execute_fee_authorization(fee_authorization, None, rng).unwrap(); + + // Create a new deployment transaction with the overreported verifying keys. + let adjusted_deployment = + Deployment::new(deployment.edition(), deployment.program().clone(), vks_with_overreport).unwrap(); + let adjusted_transaction = Transaction::from_deployment(program_owner, adjusted_deployment, fee).unwrap(); + + // Verify the deployment transaction. It should error when certificate checking for constraint count mismatch. + let res = vm.check_transaction(&adjusted_transaction, None, rng); + assert!(res.is_err()); + } + + #[test] + fn test_deployment_synthesis_underreport() { + let rng = &mut TestRng::default(); + + // Initialize a private key. + let private_key = sample_genesis_private_key(rng); + let address = Address::try_from(&private_key).unwrap(); + + // Initialize the genesis block. + let genesis = sample_genesis_block(rng); + + // Initialize the VM. + let vm = sample_vm(); + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Deploy the base program. + let program = Program::from_str( + r" +program synthesis_underreport.aleo; function do: - input r0 as u32.public; - call program_layer_{prev}.aleo/do r0 into r1; - async do r0 r1 into r2; - output r2 as program_layer_{i}.aleo/do.future; + input r0 as u32.private; + add r0 r0 into r1; + output r1 as u32.public;", + ) + .unwrap(); -finalize do: - input r0 as u32.public; - input r1 as program_layer_{prev}.aleo/do.future; - await r1; - set r0 into m[0u8];", - prev = i - 1 - )); - // Construct the program. - let program = Program::from_str(&program_string).unwrap(); + // Create the deployment transaction. + let transaction = vm.deploy(&private_key, &program, None, 0, None, rng).unwrap(); - // Deploy the program. - let deployment = vm.deploy(&private_key, &program, None, 0, None, rng).unwrap(); + // Destructure the deployment transaction. + let Transaction::Deploy(txid, program_owner, deployment, fee) = transaction else { + panic!("Expected a deployment transaction"); + }; - vm.add_next_block(&sample_next_block(&vm, &private_key, &[deployment], rng).unwrap()).unwrap(); + // Decrease the number of constraints in the verifying keys. + let mut vks_with_underreport = Vec::with_capacity(deployment.verifying_keys().len()); + for (id, (vk, cert)) in deployment.verifying_keys() { + let mut vk_deref = vk.deref().clone(); + vk_deref.circuit_info.num_constraints -= 2; + let vk = VerifyingKey::new(Arc::new(vk_deref), vk.num_variables()); + vks_with_underreport.push((*id, (vk, cert.clone()))); } - // Fetch the unspent records. - let records = genesis.transitions().cloned().flat_map(Transition::into_records).collect::>(); - trace!("Unspent Records:\n{:#?}", records); + // Create a new deployment transaction with the underreported verifying keys. + let adjusted_deployment = + Deployment::new(deployment.edition(), deployment.program().clone(), vks_with_underreport).unwrap(); + let adjusted_transaction = Transaction::Deploy(txid, program_owner, Box::new(adjusted_deployment), fee); - // Select a record to spend. - let record = Some(records.values().next().unwrap().decrypt(&view_key).unwrap()); + // Verify the deployment transaction. It should error when enforcing the first constraint over the vk limit. + let result = vm.check_transaction(&adjusted_transaction, None, rng); + assert!(result.is_err()); + // Create a standard transaction // Prepare the inputs. - let inputs = [Value::::from_str("1u32").unwrap()].into_iter(); + let inputs = [ + Value::::from_str(&address.to_string()).unwrap(), + Value::::from_str("1u64").unwrap(), + ] + .into_iter(); // Execute. let transaction = - vm.execute(&private_key, ("program_layer_30.aleo", "do"), inputs, record, 0, None, rng).unwrap(); + vm.execute(&private_key, ("credits.aleo", "transfer_public"), inputs, None, 0, None, rng).unwrap(); - // Verify. - vm.check_transaction(&transaction, None, rng).unwrap(); + // Check that the deployment transaction will be aborted if injected into a block. + let block = sample_next_block(&vm, &private_key, &[transaction, adjusted_transaction.clone()], rng).unwrap(); + + // Check that the block aborts the deployment transaction. + assert_eq!(block.aborted_transaction_ids(), &vec![adjusted_transaction.id()]); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + } + + #[test] + fn test_deployment_variable_underreport() { + let rng = &mut TestRng::default(); + + // Initialize a private key. + let private_key = sample_genesis_private_key(rng); + let address = Address::try_from(&private_key).unwrap(); + + // Initialize the genesis block. + let genesis = sample_genesis_block(rng); + + // Initialize the VM. + let vm = sample_vm(); + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Deploy the base program. + let program = Program::from_str( + r" +program synthesis_underreport.aleo; +function do: + input r0 as u32.private; + add r0 r0 into r1; + output r1 as u32.public;", + ) + .unwrap(); + + // Create the deployment transaction. + let transaction = vm.deploy(&private_key, &program, None, 0, None, rng).unwrap(); + + // Destructure the deployment transaction. + let Transaction::Deploy(txid, program_owner, deployment, fee) = transaction else { + panic!("Expected a deployment transaction"); + }; + + // Decrease the number of reported variables in the verifying keys. + let mut vks_with_underreport = Vec::with_capacity(deployment.verifying_keys().len()); + for (id, (vk, cert)) in deployment.verifying_keys() { + let vk = VerifyingKey::new(Arc::new(vk.deref().clone()), vk.num_variables() - 2); + vks_with_underreport.push((*id, (vk.clone(), cert.clone()))); + } + + // Create a new deployment transaction with the underreported verifying keys. + let adjusted_deployment = + Deployment::new(deployment.edition(), deployment.program().clone(), vks_with_underreport).unwrap(); + let adjusted_transaction = Transaction::Deploy(txid, program_owner, Box::new(adjusted_deployment), fee); + + // Verify the deployment transaction. It should error when synthesizing the first variable over the vk limit. + let result = vm.check_transaction(&adjusted_transaction, None, rng); + assert!(result.is_err()); + + // Create a standard transaction + // Prepare the inputs. + let inputs = [ + Value::::from_str(&address.to_string()).unwrap(), + Value::::from_str("1u64").unwrap(), + ] + .into_iter(); + + // Execute. + let transaction = + vm.execute(&private_key, ("credits.aleo", "transfer_public"), inputs, None, 0, None, rng).unwrap(); + + // Check that the deployment transaction will be aborted if injected into a block. + let block = sample_next_block(&vm, &private_key, &[transaction, adjusted_transaction.clone()], rng).unwrap(); + + // Check that the block aborts the deployment transaction. + assert_eq!(block.aborted_transaction_ids(), &vec![adjusted_transaction.id()]); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + } + + #[test] + #[ignore] + fn test_deployment_memory_overload() { + const NUM_DEPLOYMENTS: usize = 32; + + let rng = &mut TestRng::default(); + + // Initialize a private key. + let private_key = sample_genesis_private_key(rng); + + // Initialize a view key. + let view_key = ViewKey::try_from(&private_key).unwrap(); + + // Initialize the genesis block. + let genesis = sample_genesis_block(rng); + + // Initialize the VM. + let vm = sample_vm(); + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Deploy the base program. + let program = Program::from_str( + r" +program program_layer_0.aleo; + +mapping m: + key as u8.public; + value as u32.public; + +function do: + input r0 as u32.public; + async do r0 into r1; + output r1 as program_layer_0.aleo/do.future; + +finalize do: + input r0 as u32.public; + set r0 into m[0u8];", + ) + .unwrap(); + + let deployment = vm.deploy(&private_key, &program, None, 0, None, rng).unwrap(); + vm.add_next_block(&sample_next_block(&vm, &private_key, &[deployment], rng).unwrap()).unwrap(); + + // For each layer, deploy a program that calls the program from the previous layer. + for i in 1..NUM_DEPLOYMENTS { + let mut program_string = String::new(); + // Add the import statements. + for j in 0..i { + program_string.push_str(&format!("import program_layer_{}.aleo;\n", j)); + } + // Add the program body. + program_string.push_str(&format!( + "program program_layer_{i}.aleo; + +mapping m: + key as u8.public; + value as u32.public; + +function do: + input r0 as u32.public; + call program_layer_{prev}.aleo/do r0 into r1; + async do r0 r1 into r2; + output r2 as program_layer_{i}.aleo/do.future; + +finalize do: + input r0 as u32.public; + input r1 as program_layer_{prev}.aleo/do.future; + await r1; + set r0 into m[0u8];", + prev = i - 1 + )); + // Construct the program. + let program = Program::from_str(&program_string).unwrap(); + + // Deploy the program. + let deployment = vm.deploy(&private_key, &program, None, 0, None, rng).unwrap(); + + vm.add_next_block(&sample_next_block(&vm, &private_key, &[deployment], rng).unwrap()).unwrap(); + } + + // Fetch the unspent records. + let records = genesis.transitions().cloned().flat_map(Transition::into_records).collect::>(); + trace!("Unspent Records:\n{:#?}", records); + + // Select a record to spend. + let record = Some(records.values().next().unwrap().decrypt(&view_key).unwrap()); + + // Prepare the inputs. + let inputs = [Value::::from_str("1u32").unwrap()].into_iter(); + + // Execute. + let transaction = + vm.execute(&private_key, ("program_layer_30.aleo", "do"), inputs, record, 0, None, rng).unwrap(); + + // Verify. + vm.check_transaction(&transaction, None, rng).unwrap(); + } + + #[test] + fn test_transfer_public_from_user() { + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + let caller_address = Address::try_from(&caller_private_key).unwrap(); + + // Initialize a recipient. + let recipient_private_key = PrivateKey::new(rng).unwrap(); + let recipient_address = Address::try_from(&recipient_private_key).unwrap(); + + // Initialize the genesis block. + let genesis = crate::vm::test_helpers::sample_genesis_block(rng); + + // Initialize the VM. + let vm = crate::vm::test_helpers::sample_vm(); + + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Check the balance of the caller. + let credits_program_id = ProgramID::from_str("credits.aleo").unwrap(); + let account_mapping_name = Identifier::from_str("account").unwrap(); + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(caller_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 182_499_999_894_244, "Update me if the initial balance changes."); + + // Transfer credits from the caller to the recipient. + let transaction = vm + .execute( + &caller_private_key, + ("credits.aleo", "transfer_public"), + [Value::from_str(&format!("{recipient_address}")).unwrap(), Value::from_str("1u64").unwrap()].iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Verify the transaction. + vm.check_transaction(&transaction, None, rng).unwrap(); + + // Add the transaction to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[transaction], rng).unwrap(); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + + // Check the balance of the caller. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(caller_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 182_499_999_843_183, "Update me if the initial balance changes."); + + // Check the balance of the recipient. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(recipient_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 1, "Update me if the test amount changes."); + } + + #[test] + fn test_transfer_public_as_signer_from_user() { + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + let caller_address = Address::try_from(&caller_private_key).unwrap(); + + // Initialize a recipient. + let recipient_private_key = PrivateKey::new(rng).unwrap(); + let recipient_address = Address::try_from(&recipient_private_key).unwrap(); + + // Initialize the genesis block. + let genesis = crate::vm::test_helpers::sample_genesis_block(rng); + + // Initialize the VM. + let vm = crate::vm::test_helpers::sample_vm(); + + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Check the balance of the caller. + let credits_program_id = ProgramID::from_str("credits.aleo").unwrap(); + let account_mapping_name = Identifier::from_str("account").unwrap(); + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(caller_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 182_499_999_894_244, "Update me if the initial balance changes."); + + // Transfer credits from the caller to the recipient. + let transaction = vm + .execute( + &caller_private_key, + ("credits.aleo", "transfer_public_as_signer"), + [Value::from_str(&format!("{recipient_address}")).unwrap(), Value::from_str("1u64").unwrap()].iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Verify the transaction. + vm.check_transaction(&transaction, None, rng).unwrap(); + + // Add the transaction to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[transaction], rng).unwrap(); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + + // Check the balance of the caller. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(caller_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 182_499_999_843_163, "Update me if the initial balance changes."); + + // Check the balance of the recipient. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(recipient_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 1, "Update me if the test amount changes."); + } + + #[test] + fn transfer_public_from_program() { + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + let caller_address = Address::try_from(&caller_private_key).unwrap(); + + // Initialize a recipient. + let recipient_private_key = PrivateKey::new(rng).unwrap(); + let recipient_address = Address::try_from(&recipient_private_key).unwrap(); + + // Initialize the genesis block. + let genesis = crate::vm::test_helpers::sample_genesis_block(rng); + + // Initialize the VM. + let vm = crate::vm::test_helpers::sample_vm(); + + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Check the balance of the caller. + let credits_program_id = ProgramID::from_str("credits.aleo").unwrap(); + let account_mapping_name = Identifier::from_str("account").unwrap(); + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(caller_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 182_499_999_894_244, "Update me if the initial balance changes."); + + // Initialize a wrapper program, importing `credits.aleo` and calling `transfer_public`. + let program = Program::from_str( + r" +import credits.aleo; +program credits_wrapper.aleo; + +function transfer_public: + input r0 as address.public; + input r1 as u64.public; + call credits.aleo/transfer_public r0 r1 into r2; + async transfer_public r2 into r3; + output r3 as credits_wrapper.aleo/transfer_public.future; + +finalize transfer_public: + input r0 as credits.aleo/transfer_public.future; + await r0; + ", + ) + .unwrap(); + + // Get the address of the wrapper program. + let wrapper_program_id = ProgramID::from_str("credits_wrapper.aleo").unwrap(); + let wrapper_program_address = wrapper_program_id.to_address().unwrap(); + + // Deploy the wrapper program. + let deployment = vm.deploy(&caller_private_key, &program, None, 0, None, rng).unwrap(); + + // Add the deployment to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[deployment], rng).unwrap(); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + + // Transfer credits from the caller to the `credits_wrapper` program. + let transaction = vm + .execute( + &caller_private_key, + ("credits.aleo", "transfer_public"), + [Value::from_str(&format!("{wrapper_program_address}")).unwrap(), Value::from_str("1u64").unwrap()] + .iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Verify the transaction. + vm.check_transaction(&transaction, None, rng).unwrap(); + + // Add the transaction to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[transaction], rng).unwrap(); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + + // Check the balance of the caller. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(caller_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 182_499_996_914_808, "Update me if the initial balance changes."); + + // Check the balance of the `credits_wrapper` program. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(wrapper_program_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 1, "Update me if the test amount changes."); + + // Transfer credits from the `credits_wrapper` program to the recipient. + let transaction = vm + .execute( + &caller_private_key, + ("credits_wrapper.aleo", "transfer_public"), + [Value::from_str(&format!("{recipient_address}")).unwrap(), Value::from_str("1u64").unwrap()].iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Verify the transaction. + vm.check_transaction(&transaction, None, rng).unwrap(); + + // Add the transaction to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[transaction], rng).unwrap(); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + + // Check the balance of the caller. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(caller_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 182_499_996_862_283, "Update me if the initial balance changes."); + + // Check the balance of the `credits_wrapper` program. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(wrapper_program_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 0); + + // Check the balance of the recipient. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(recipient_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 1, "Update me if the test amount changes."); + } + + #[test] + fn transfer_public_as_signer_from_program() { + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + let caller_address = Address::try_from(&caller_private_key).unwrap(); + + // Initialize a recipient. + let recipient_private_key = PrivateKey::new(rng).unwrap(); + let recipient_address = Address::try_from(&recipient_private_key).unwrap(); + + // Initialize the genesis block. + let genesis = crate::vm::test_helpers::sample_genesis_block(rng); + + // Initialize the VM. + let vm = crate::vm::test_helpers::sample_vm(); + + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Check the balance of the caller. + let credits_program_id = ProgramID::from_str("credits.aleo").unwrap(); + let account_mapping_name = Identifier::from_str("account").unwrap(); + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(caller_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 182_499_999_894_244, "Update me if the initial balance changes."); + + // Initialize a wrapper program, importing `credits.aleo` and calling `transfer_public`. + let program = Program::from_str( + r" +import credits.aleo; +program credits_wrapper.aleo; + +function transfer_public_as_signer: + input r0 as address.public; + input r1 as u64.public; + call credits.aleo/transfer_public_as_signer r0 r1 into r2; + async transfer_public_as_signer r2 into r3; + output r3 as credits_wrapper.aleo/transfer_public_as_signer.future; + +finalize transfer_public_as_signer: + input r0 as credits.aleo/transfer_public_as_signer.future; + await r0; + ", + ) + .unwrap(); + + // Get the address of the wrapper program. + let wrapper_program_id = ProgramID::from_str("credits_wrapper.aleo").unwrap(); + let wrapper_program_address = wrapper_program_id.to_address().unwrap(); + + // Deploy the wrapper program. + let deployment = vm.deploy(&caller_private_key, &program, None, 0, None, rng).unwrap(); + + // Add the deployment to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[deployment], rng).unwrap(); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + + // Transfer credits from the signer using `credits_wrapper` program. + let transaction = vm + .execute( + &caller_private_key, + ("credits_wrapper.aleo", "transfer_public_as_signer"), + [Value::from_str(&format!("{recipient_address}")).unwrap(), Value::from_str("1u64").unwrap()].iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Verify the transaction. + vm.check_transaction(&transaction, None, rng).unwrap(); + + // Add the transaction to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[transaction], rng).unwrap(); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + + // Check the balance of the caller. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(caller_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 182_499_996_821_793, "Update me if the initial balance changes."); + + // Check the `credits_wrapper` program does not have any balance. + let balance = vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(wrapper_program_address)), + ) + .unwrap(); + assert!(balance.is_none()); + + // Check the balance of the recipient. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(recipient_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 1, "Update me if the test amount changes."); + } + + #[test] + fn test_transfer_public_to_private_from_program() { + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + let caller_address = Address::try_from(&caller_private_key).unwrap(); + + // Initialize a recipient. + let recipient_private_key = PrivateKey::new(rng).unwrap(); + let recipient_address = Address::try_from(&recipient_private_key).unwrap(); + + // Initialize the genesis block. + let genesis = crate::vm::test_helpers::sample_genesis_block(rng); + + // Initialize the VM. + let vm = crate::vm::test_helpers::sample_vm(); + + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Check the balance of the caller. + let credits_program_id = ProgramID::from_str("credits.aleo").unwrap(); + let account_mapping_name = Identifier::from_str("account").unwrap(); + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(caller_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 182_499_999_894_244, "Update me if the initial balance changes."); + + // Check that the recipient does not have a public balance. + let balance = vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(recipient_address)), + ) + .unwrap(); + assert!(balance.is_none()); + + // Initialize a wrapper program, importing `credits.aleo` and calling `transfer_public_as_signer` then `transfer_public_to_private`. + let program = Program::from_str( + r" +import credits.aleo; + +program credits_wrapper.aleo; + +function transfer_public_to_private: + input r0 as address.private; + input r1 as u64.public; + call credits.aleo/transfer_public_as_signer credits_wrapper.aleo r1 into r2; + call credits.aleo/transfer_public_to_private r0 r1 into r3 r4; + async transfer_public_to_private r2 r4 into r5; + output r3 as credits.aleo/credits.record; + output r5 as credits_wrapper.aleo/transfer_public_to_private.future; + +finalize transfer_public_to_private: + input r0 as credits.aleo/transfer_public_as_signer.future; + input r1 as credits.aleo/transfer_public_to_private.future; + contains credits.aleo/account[credits_wrapper.aleo] into r2; + assert.eq r2 false; + await r0; + get credits.aleo/account[credits_wrapper.aleo] into r3; + assert.eq r3 r0[2u32]; + await r1; + ", + ) + .unwrap(); + + // Get the address of the wrapper program. + let wrapper_program_id = ProgramID::from_str("credits_wrapper.aleo").unwrap(); + + // Deploy the wrapper program. + let deployment = vm.deploy(&caller_private_key, &program, None, 0, None, rng).unwrap(); + + // Add the deployment to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[deployment], rng).unwrap(); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + + // Call the wrapper program to transfer credits from the caller to the recipient. + let transaction = vm + .execute( + &caller_private_key, + ("credits_wrapper.aleo", "transfer_public_to_private"), + [Value::from_str(&format!("{recipient_address}")).unwrap(), Value::from_str("1u64").unwrap()].iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Verify the transaction. + vm.check_transaction(&transaction, None, rng).unwrap(); + + // Add the transaction to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[transaction.clone()], rng).unwrap(); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + + // Check the balance of the caller. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(caller_address)), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + + assert_eq!(balance, 182_499_996_071_881, "Update me if the initial balance changes."); + + // Check that the `credits_wrapper` program has a balance of 0. + let balance = match vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(wrapper_program_id.to_address().unwrap())), + ) + .unwrap() + { + Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance, + _ => panic!("Expected a valid balance"), + }; + assert_eq!(balance, 0); + + // Check that the recipient does not have a public balance. + let balance = vm + .finalize_store() + .get_value_confirmed( + credits_program_id, + account_mapping_name, + &Plaintext::from(Literal::Address(recipient_address)), + ) + .unwrap(); + assert!(balance.is_none()); + + // Get the output record from the transaction and check that it is well-formed. + let records = transaction.records().collect_vec(); + assert_eq!(records.len(), 1); + let (commitment, record) = records[0]; + let record = record.decrypt(&ViewKey::try_from(&recipient_private_key).unwrap()).unwrap(); + assert_eq!(**record.owner(), recipient_address); + let data = record.data(); + assert_eq!(data.len(), 1); + match data.get(&Identifier::from_str("microcredits").unwrap()) { + Some(Entry::::Private(Plaintext::Literal(Literal::U64(value), _))) => { + assert_eq!(**value, 1) + } + _ => panic!("Incorrect record."), + } + + // Check that the record exists in the VM. + assert!(vm.transition_store().get_record(commitment).unwrap().is_some()); + + // Check that the serial number of the record does not exist in the VM. + assert!( + !vm.transition_store() + .contains_serial_number( + &Record::>::serial_number( + recipient_private_key, + *commitment + ) + .unwrap() + ) + .unwrap() + ); + } + + #[test] + fn test_large_transaction_is_aborted() { + let rng = &mut TestRng::default(); + + // Initialize a new caller. + let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + + // Initialize the genesis block. + let genesis = crate::vm::test_helpers::sample_genesis_block(rng); + + // Initialize the VM. + let vm = crate::vm::test_helpers::sample_vm(); + + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Deploy a program that produces small transactions. + let program = small_transaction_program(); + + // Deploy the program. + let deployment = vm.deploy(&caller_private_key, &program, None, 0, None, rng).unwrap(); + + // Add the deployment to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[deployment], rng).unwrap(); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + + // Deploy a program that produces large transactions. + let program = large_transaction_program(); + + // Deploy the program. + let deployment = vm.deploy(&caller_private_key, &program, None, 0, None, rng).unwrap(); + + // Add the deployment to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[deployment], rng).unwrap(); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + + // Call the program to produce the small transaction. + let transaction = vm + .execute( + &caller_private_key, + ("testing_small.aleo", "small_transaction"), + Vec::>::new().iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Verify the transaction. + vm.check_transaction(&transaction, None, rng).unwrap(); + + // Add the transaction to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[transaction], rng).unwrap(); + + // Check that the transaction was accepted. + assert_eq!(block.transactions().num_accepted(), 1); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + + // Call the program to produce a large transaction. + let transaction = vm + .execute( + &caller_private_key, + ("testing_large.aleo", "large_transaction"), + Vec::>::new().iter(), + None, + 0, + None, + rng, + ) + .unwrap(); + + // Verify that the transaction is invalid. + assert!(vm.check_transaction(&transaction, None, rng).is_err()); + + // Add the transaction to a block and update the VM. + let block = sample_next_block(&vm, &caller_private_key, &[transaction], rng).unwrap(); + + // Check that the transaction was aborted. + assert_eq!(block.aborted_transaction_ids().len(), 1); + + // Update the VM. + vm.add_next_block(&block).unwrap(); + } + + #[test] + fn test_vm_puzzle() { + // Attention: This test is used to ensure that the VM has performed downcasting correctly for + // the puzzle, and that the underlying traits in the puzzle are working correctly. Please + // *do not delete* this test as it is a critical safety check for the integrity of the + // instantiation of the puzzle in the VM. + + let rng = &mut TestRng::default(); + + // Initialize the VM. + let vm = sample_vm(); + + // Ensure this call succeeds. + vm.puzzle.prove(rng.gen(), rng.gen(), rng.gen(), None).unwrap(); + } + + #[cfg(feature = "rocks")] + #[test] + fn test_atomic_unpause_on_error() { + let rng = &mut TestRng::default(); + + // Initialize a genesis private key.. + let genesis_private_key = sample_genesis_private_key(rng); + + // Initialize the genesis block. + let genesis = sample_genesis_block(rng); + + // Initialize a VM and sample 2 blocks using it. + let vm = sample_vm(); + vm.add_next_block(&genesis).unwrap(); + let block1 = sample_next_block(&vm, &genesis_private_key, &[], rng).unwrap(); + vm.add_next_block(&block1).unwrap(); + let block2 = sample_next_block(&vm, &genesis_private_key, &[], rng).unwrap(); + + // Create a new, rocks-based VM shadowing the 1st one. + let tempdir = tempfile::tempdir().unwrap(); + let vm = sample_vm_rocks(tempdir.path()); + vm.add_next_block(&genesis).unwrap(); + // This time, however, try to insert the 2nd block first, which fails due to height. + assert!(vm.add_next_block(&block2).is_err()); + + // It should still be possible to insert the 1st block afterwards. + vm.add_next_block(&block1).unwrap(); } } diff --git a/synthesizer/src/vm/verify.rs b/synthesizer/src/vm/verify.rs index 3892d153db..ab45e68444 100644 --- a/synthesizer/src/vm/verify.rs +++ b/synthesizer/src/vm/verify.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -31,6 +32,38 @@ macro_rules! ensure_is_unique { }; } +impl> VM { + /// The maximum number of deployments to verify in parallel. + pub(crate) const MAX_PARALLEL_DEPLOY_VERIFICATIONS: usize = 5; + /// The maximum number of executions to verify in parallel. + pub(crate) const MAX_PARALLEL_EXECUTE_VERIFICATIONS: usize = 1000; + + /// Verifies the list of transactions in the VM. On failure, returns an error. + pub fn check_transactions( + &self, + transactions: &[(&Transaction, Option>)], + rng: &mut R, + ) -> Result<()> { + // Separate the transactions into deploys and executions. + let (deployments, executions): (Vec<_>, Vec<_>) = transactions.iter().partition(|(tx, _)| tx.is_deploy()); + // Chunk the deploys and executions into groups for parallel verification. + let deployments_for_verification = deployments.chunks(Self::MAX_PARALLEL_DEPLOY_VERIFICATIONS); + let executions_for_verification = executions.chunks(Self::MAX_PARALLEL_EXECUTE_VERIFICATIONS); + + // Verify the transactions in batches. + for transactions in deployments_for_verification.chain(executions_for_verification) { + // Ensure each transaction is well-formed and unique. + let rngs = (0..transactions.len()).map(|_| StdRng::from_seed(rng.gen())).collect::>(); + cfg_iter!(transactions).zip(rngs).try_for_each(|((transaction, rejected_id), mut rng)| { + self.check_transaction(transaction, *rejected_id, &mut rng) + .map_err(|e| anyhow!("Invalid transaction found in the transactions list: {e}")) + })?; + } + + Ok(()) + } +} + impl> VM { /// Verifies the transaction in the VM. On failure, returns an error. #[inline] @@ -44,6 +77,13 @@ impl> VM { /* Transaction */ + // Allocate a buffer to write the transaction. + let mut buffer = Vec::with_capacity(N::MAX_TRANSACTION_SIZE); + // Ensure that the transaction is well formed and does not exceed the maximum size. + if let Err(error) = transaction.write_le(LimitedWriter::new(&mut buffer, N::MAX_TRANSACTION_SIZE)) { + bail!("Transaction '{}' is not well-formed: {error}", transaction.id()) + } + // Ensure the transaction ID is unique. if self.block_store().contains_transaction_id(&transaction.id())? { bail!("Transaction '{}' already exists in the ledger", transaction.id()) @@ -95,8 +135,12 @@ impl> VM { // First, verify the fee. self.check_fee(transaction, rejected_id)?; + // Construct the transaction checksum. + let checksum = Data::>::Buffer(transaction.to_bytes_le()?.into()).to_checksum::()?; + // Check if the transaction exists in the partially-verified cache. - let is_partially_verified = self.partially_verified_transactions.read().peek(&transaction.id()).is_some(); + let is_partially_verified = + self.partially_verified_transactions.read().peek(&(transaction.id())) == Some(&checksum); // Next, verify the deployment or execution. match transaction { @@ -121,7 +165,11 @@ impl> VM { } // Verify the deployment if it has not been verified before. if !is_partially_verified { - self.check_deployment_internal(deployment, rng)?; + // Verify the deployment. + match try_vm_runtime!(|| self.check_deployment_internal(deployment, rng)) { + Ok(result) => result?, + Err(_) => bail!("VM safely halted transaction '{id}' during verification"), + } } } Transaction::Execute(id, execution, _) => { @@ -134,7 +182,10 @@ impl> VM { bail!("Transaction '{id}' contains a previously rejected execution") } // Verify the execution. - self.check_execution_internal(execution, is_partially_verified)?; + match try_vm_runtime!(|| self.check_execution_internal(execution, is_partially_verified)) { + Ok(result) => result?, + Err(_) => bail!("VM safely halted transaction '{id}' during verification"), + } } Transaction::Fee(..) => { /* no-op */ } } @@ -142,7 +193,7 @@ impl> VM { // If the above checks have passed and this is not a fee transaction, // then add the transaction ID to the partially-verified transactions cache. if !matches!(transaction, Transaction::Fee(..)) && !is_partially_verified { - self.partially_verified_transactions.write().push(transaction.id(), ()); + self.partially_verified_transactions.write().push(transaction.id(), checksum); } finish!(timer, "Verify the transaction"); @@ -160,7 +211,7 @@ impl> VM { let Ok(deployment_id) = deployment.to_deployment_id() else { bail!("Failed to compute the Merkle root for deployment transaction '{id}'") }; - // Compute the deployment cost. + // Compute the minimum deployment cost. let (cost, _) = deployment_cost(deployment)?; // Ensure the fee is sufficient to cover the cost. if *fee.base_amount()? < cost { @@ -182,8 +233,15 @@ impl> VM { if let Some(fee) = fee { // If the fee is required, then check that the base fee amount is satisfied. if is_fee_required { - // Compute the execution cost. - let (cost, _) = execution_cost(self, execution)?; + // Compute the execution cost based on the block height + let block_height = self + .block_store() + .find_block_height_from_state_root(execution.global_state_root())? + .unwrap_or_default(); + let (cost, (_, _)) = match block_height < N::CONSENSUS_V2_HEIGHT { + true => execution_cost_v1(&self.process().read(), execution)?, + false => execution_cost_v2(&self.process().read(), execution)?, + }; // Ensure the fee is sufficient to cover the cost. if *fee.base_amount()? < cost { bail!( @@ -247,6 +305,14 @@ impl> VM { fn check_execution_internal(&self, execution: &Execution, is_partially_verified: bool) -> Result<()> { let timer = timer!("VM::check_execution"); + // Retrieve the block height. + let block_height = self.block_store().current_block_height(); + + // Ensure the execution does not contain any restricted transitions. + if self.restrictions.contains_restricted_transitions(execution, block_height) { + bail!("Execution verification failed - restricted transition found"); + } + // Verify the execution proof, if it has not been partially-verified before. let verification = match is_partially_verified { true => Ok(()), @@ -329,7 +395,7 @@ mod tests { account::{Address, ViewKey}, types::Field, }; - use ledger_block::{Block, Header, Metadata, Transaction}; + use ledger_block::{Block, Header, Metadata, Transaction, Transition}; type CurrentNetwork = test_helpers::CurrentNetwork; @@ -488,8 +554,18 @@ mod tests { let deployment_transaction = vm.deploy(&caller_private_key, &program, Some(credits), 10, None, rng).unwrap(); // Construct the new block header. - let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = - vm.speculate(sample_finalize_state(1), Some(0u64), vec![], None, [deployment_transaction].iter()).unwrap(); + let time_since_last_block = CurrentNetwork::BLOCK_TIME as i64; + let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = vm + .speculate( + sample_finalize_state(1), + time_since_last_block, + Some(0u64), + vec![], + &None.into(), + [deployment_transaction].iter(), + rng, + ) + .unwrap(); assert!(aborted_transaction_ids.is_empty()); // Construct the metadata associated with the block. @@ -503,7 +579,7 @@ mod tests { CurrentNetwork::GENESIS_PROOF_TARGET, genesis.last_coinbase_target(), genesis.last_coinbase_timestamp(), - CurrentNetwork::GENESIS_TIMESTAMP + 1, + genesis.timestamp().saturating_add(time_since_last_block), ) .unwrap(); @@ -524,7 +600,8 @@ mod tests { genesis.hash(), deployment_header, ratifications, - None, + None.into(), + vec![], transactions, aborted_transaction_ids, rng, @@ -585,4 +662,162 @@ function compute: // Ensure that the program can't be deployed. assert!(vm.deploy_raw(&program, rng).is_err()); } + + #[test] + fn test_check_mutated_execution() { + let rng = &mut TestRng::default(); + + // Initialize the VM. + let vm = crate::vm::test_helpers::sample_vm(); + // Fetch the caller's private key. + let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng); + // Initialize the genesis block. + let genesis = crate::vm::test_helpers::sample_genesis_block(rng); + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Fetch a valid execution transaction with a public fee. + let valid_transaction = crate::vm::test_helpers::sample_execution_transaction_with_public_fee(rng); + vm.check_transaction(&valid_transaction, None, rng).unwrap(); + + // Mutate the execution transaction by inserting a Field::Zero as an output. + let execution = valid_transaction.execution().unwrap(); + + // Extract the first transition from the execution. + let transitions: Vec<_> = execution.transitions().collect(); + assert_eq!(transitions.len(), 1); + let transition = transitions[0].clone(); + + // Mutate the transition by adding an additional `Field::zero` output. This is significant because the Varuna + // verifier pads the inputs with `Field::zero`s, which means that the same proof is valid for both the + // original and the mutated executions. + let added_output = Output::ExternalRecord(Field::zero()); + let mutated_outputs = [transition.outputs(), &[added_output]].concat(); + let mutated_transition = Transition::new( + *transition.program_id(), + *transition.function_name(), + transition.inputs().to_vec(), + mutated_outputs, + *transition.tpk(), + *transition.tcm(), + *transition.scm(), + ) + .unwrap(); + + // Construct the mutated execution. + let mutated_execution = Execution::from( + [mutated_transition].into_iter(), + execution.global_state_root(), + execution.proof().cloned(), + ) + .unwrap(); + + // Authorize the fee. + let authorization = vm + .authorize_fee_public( + &caller_private_key, + 10_000_000, + 100, + mutated_execution.to_execution_id().unwrap(), + rng, + ) + .unwrap(); + // Compute the fee. + let fee = vm.execute_fee_authorization(authorization, None, rng).unwrap(); + + // Construct the transaction. + let mutated_transaction = Transaction::from_execution(mutated_execution, Some(fee)).unwrap(); + + // Ensure that the mutated transaction fails verification due to an extra output. + assert!(vm.check_transaction(&mutated_transaction, None, rng).is_err()); + } + + #[cfg(feature = "test")] + #[test] + fn test_fee_migration() { + // This test will fail if the consensus v2 height is 0 + assert_ne!(0, CurrentNetwork::CONSENSUS_V2_HEIGHT); + + let minimum_credits_transfer_public_fee = 34_060; + let old_minimum_credits_transfer_public_fee = 51_060; + + let rng = &mut TestRng::default(); + + // Initialize the VM. + let vm = crate::vm::test_helpers::sample_vm(); + // Initialize the genesis block. + let genesis = crate::vm::test_helpers::sample_genesis_block(rng); + // Update the VM. + vm.add_next_block(&genesis).unwrap(); + + // Create the base transaction + let transaction = crate::vm::test_helpers::sample_execution_transaction_with_public_fee(rng); + + // Try to submit a tx with the new fee before the migration block height + let fee_too_low_transaction = crate::vm::test_helpers::create_new_transaction_with_different_fee( + rng, + transaction.clone(), + minimum_credits_transfer_public_fee, + ); + assert!(vm.check_transaction(&fee_too_low_transaction, None, rng).is_err()); + + // Try to submit a tx with the old fee before the migration block height + let old_valid_transaction = crate::vm::test_helpers::create_new_transaction_with_different_fee( + rng, + transaction.clone(), + old_minimum_credits_transfer_public_fee, + ); + assert!(vm.check_transaction(&old_valid_transaction, None, rng).is_ok()); + + // Update the VM to the migration block height + let private_key = test_helpers::sample_genesis_private_key(rng); + let transactions: [Transaction; 0] = []; + for _ in 0..CurrentNetwork::CONSENSUS_V2_HEIGHT { + // Call the function + let next_block = crate::vm::test_helpers::sample_next_block(&vm, &private_key, &transactions, rng).unwrap(); + vm.add_next_block(&next_block).unwrap(); + } + + // Create a new transaction with the new stateroot post migration block height + let transaction = { + let address = Address::try_from(&private_key).unwrap(); + let inputs = [ + Value::::from_str(&address.to_string()).unwrap(), + Value::::from_str("1u64").unwrap(), + ] + .into_iter(); + + // Execute. + let transaction_without_fee = + vm.execute(&private_key, ("credits.aleo", "transfer_public"), inputs, None, 0, None, rng).unwrap(); + let execution = transaction_without_fee.execution().unwrap().clone(); + + // Authorize the fee. + let authorization = vm + .authorize_fee_public(&private_key, 10_000_000, 100, execution.to_execution_id().unwrap(), rng) + .unwrap(); + // Compute the fee. + let fee = vm.execute_fee_authorization(authorization, None, rng).unwrap(); + + // Construct the transaction. + Transaction::from_execution(execution, Some(fee)).unwrap() + }; + + // Try to submit a tx with the old fee after the migration block height + // Should work as now the fee is just too high + let fee_too_high_transaction = crate::vm::test_helpers::create_new_transaction_with_different_fee( + rng, + transaction.clone(), + old_minimum_credits_transfer_public_fee, + ); + assert!(vm.check_transaction(&fee_too_high_transaction, None, rng).is_ok()); + + // Try to submit a tx with the new fee after the migration block height + let valid_transaction = crate::vm::test_helpers::create_new_transaction_with_different_fee( + rng, + transaction.clone(), + minimum_credits_transfer_public_fee, + ); + assert!(vm.check_transaction(&valid_transaction, None, rng).is_ok()); + } } diff --git a/synthesizer/tests/expectations/parser/instruction/instruction_pass.out b/synthesizer/tests/expectations/parser/instruction/instruction_pass.out index 7de1861e4b..add2fafbe9 100644 --- a/synthesizer/tests/expectations/parser/instruction/instruction_pass.out +++ b/synthesizer/tests/expectations/parser/instruction/instruction_pass.out @@ -62,3 +62,4 @@ - Parsing was successful. - Parsing was successful. - Parsing was successful. +- Parsing was successful. diff --git a/synthesizer/tests/expectations/parser/instruction/operand_pass.out b/synthesizer/tests/expectations/parser/instruction/operand_pass.out index df4a409fbc..ca15d75f4c 100644 --- a/synthesizer/tests/expectations/parser/instruction/operand_pass.out +++ b/synthesizer/tests/expectations/parser/instruction/operand_pass.out @@ -18,3 +18,4 @@ - Parsing was successful. - Parsing was successful. - Parsing was successful. +- Parsing was successful. diff --git a/synthesizer/tests/expectations/process/execute/lossy_casts.out b/synthesizer/tests/expectations/process/execute/lossy_casts.out new file mode 100644 index 0000000000..0a3a6279bc --- /dev/null +++ b/synthesizer/tests/expectations/process/execute/lossy_casts.out @@ -0,0 +1,62 @@ +errors: [] +outputs: +- - 93754672984613362290390329026198290544u128 + - 93754672984613362290390329026198290544i128 + - 16982649547548967024u64 + - -1464094526160584592i64 + - 446349424u32 + - 446349424i32 + - 49264u16 + - -16272i16 + - 112u8 + - 112i8 + - 'false' + - 4764330560507562969049837239139509827871889319573451509694277586124473432540group +- - 0u128 + - 0i128 + - 0u64 + - 0i64 + - 0u32 + - 0i32 + - 0u16 + - 0i16 + - 0u8 + - 0i8 + - 'false' + - 0group +- - 1u128 + - 1i128 + - 1u64 + - 1i64 + - 1u32 + - 1i32 + - 1u16 + - 1i16 + - 1u8 + - 1i8 + - 'true' + - 1540945439182663264862696551825005342995406165131907382295858612069623286213group +- - 0u128 + - 0i128 + - 0u64 + - 0i64 + - 0u32 + - 0i32 + - 0u16 + - 0i16 + - 0u8 + - 0i8 + - 'false' + - 340282366920938463463374607431768211456group +- - 1u128 + - 1i128 + - 1u64 + - 1i64 + - 1u32 + - 1i32 + - 1u16 + - 1i16 + - 1u8 + - 1i8 + - 'true' + - 2207376757013908562861143127796680436121374163712359508096962653679714303999group diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/arrays_in_finalize.out b/synthesizer/tests/expectations/vm/execute_and_finalize/arrays_in_finalize.out index 2f99747752..ee5469cc3d 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/arrays_in_finalize.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/arrays_in_finalize.out @@ -4,15 +4,15 @@ outputs: execute: arrays_in_finalize.aleo/test_arrays: outputs: - - '{"type":"public","id":"8423501051492945494142580898503776230777967039101310769883569628562838106961field","value":"[\n [\n true,\n false,\n true,\n false\n ]\n]"}' - - '{"type":"public","id":"6373810658910535946682884531888342268371302467625666065790785860646654788892field","value":"[\n [\n false,\n true,\n false,\n true\n ]\n]"}' - - '{"type":"public","id":"3091501445020687319877822274133758457934608796618645756988915091755405157586field","value":"[\n [\n false,\n false,\n false,\n false\n ]\n]"}' - - '{"type":"private","id":"6526736422839961003683955650152924988761580233649162767954364194151255194053field","value":"ciphertext1qvqr73dv3clq8jtx7trf8k9l3eshmh0tyvvp2ta7a0y3pedjj99eczrpwk6045wektcw7mmjzdrm8f67x7egd4dfch3slf4q6ag3lxn0p6cryuecunyl2d9ffr8ntj57dvmv9rg7fhlrtc995w2ruju7j20qgndw85u"}' - - '{"type":"future","id":"5831343183208330086568343850686282945376722092994016952161543991067519254136field","value":"{\n program_id: arrays_in_finalize.aleo,\n function_name: test_arrays,\n arguments: [\n [\n [\n true,\n false,\n true,\n false\n ]\n],\n [\n [\n false,\n true,\n false,\n true\n ]\n]\n ]\n}"}' + - '{"type":"public","id":"5118967490510389498563593408332855643361881818167099838056367495551683196086field","value":"[\n [\n true,\n false,\n true,\n false\n ]\n]"}' + - '{"type":"public","id":"161244190800350724515604266901291103671352113673202215208394633608141402826field","value":"[\n [\n false,\n true,\n false,\n true\n ]\n]"}' + - '{"type":"public","id":"732180900540213101598934684824468886231161382295639155627335564133876613960field","value":"[\n [\n false,\n false,\n false,\n false\n ]\n]"}' + - '{"type":"private","id":"3616430215374655411967163606466924889426035845343017410873880387198363014495field","value":"ciphertext1qvqrc4mrjecujgr0g5x0qm3ra4hexhgyg37yvvcmsa235vxy8zvscq9yvve3egaugcevxduuqpjfazej54lpjjtme2wflhzkwr2yzdcfpq0pmeuu5deqde6c9mqj93t7r66eytj7kpdwmqzlfyszqzph8cwq2rfmq75"}' + - '{"type":"future","id":"3184185279581827020862519880740546694254080631373935662875123969347427956025field","value":"{\n program_id: arrays_in_finalize.aleo,\n function_name: test_arrays,\n arguments: [\n [\n [\n true,\n false,\n true,\n false\n ]\n],\n [\n [\n false,\n true,\n false,\n true\n ]\n]\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. additional: - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"611935698929626281656171069026748974326705967123466685855354594539166326131field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1y9t0y4lvhm43qdzlfjmfzh8985vfnx9ms368p07x5lsemet5ey8qt0ssjn,\n 21758u64\n ]\n}"}' + - '{"type":"future","id":"3000589134503000271678431837168879644758861415863210971558080085500903023542field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1y9t0y4lvhm43qdzlfjmfzh8985vfnx9ms368p07x5lsemet5ey8qt0ssjn,\n 7030u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/branch_with_future.out b/synthesizer/tests/expectations/vm/execute_and_finalize/branch_with_future.out new file mode 100644 index 0000000000..cea3b38f8a --- /dev/null +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/branch_with_future.out @@ -0,0 +1,87 @@ +errors: [] +outputs: +- verified: true + execute: + branch_with_future.aleo/bar: + outputs: + - '{"type":"future","id":"1901721223736840349427585700021263388379767581008399009736938254771892005010field","value":"{\n program_id: branch_with_future.aleo,\n function_name: bar,\n arguments: [\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n false\n ]\n }\n \n ]\n}"}' + speculate: the execution was rejected + add_next_block: succeeded. +- verified: true + execute: + branch_with_future.aleo/baz: + outputs: + - '{"type":"future","id":"1228696003383050132266889674489868345643026254029592802751654436178885132079field","value":"{\n program_id: branch_with_future.aleo,\n function_name: baz,\n arguments: [\n true,\n true,\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n },\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n }\n \n ]\n}"}' + speculate: the execution was accepted + add_next_block: succeeded. +- verified: true + execute: + branch_with_future.aleo/baz: + outputs: + - '{"type":"future","id":"879289045619836306626870648843085153732274658528750377055734664982530581365field","value":"{\n program_id: branch_with_future.aleo,\n function_name: baz,\n arguments: [\n true,\n false,\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n },\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n }\n \n ]\n}"}' + speculate: the execution was rejected + add_next_block: succeeded. +- verified: true + execute: + branch_with_future.aleo/baz: + outputs: + - '{"type":"future","id":"2968372731533596222248603718368848747733103012276200825311164319889876057729field","value":"{\n program_id: branch_with_future.aleo,\n function_name: baz,\n arguments: [\n false,\n true,\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n },\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n }\n \n ]\n}"}' + speculate: the execution was rejected + add_next_block: succeeded. +- verified: true + execute: + branch_with_future.aleo/baz: + outputs: + - '{"type":"future","id":"156680474478658222397874990119431113642250358456541583625828235061767777479field","value":"{\n program_id: branch_with_future.aleo,\n function_name: baz,\n arguments: [\n false,\n false,\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n },\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n }\n \n ]\n}"}' + speculate: the execution was accepted + add_next_block: succeeded. +- verified: true + execute: + branch_with_future.aleo/qux: + outputs: + - '{"type":"future","id":"1044271547530566723253698133585207021073550216261586640127744587292737089669field","value":"{\n program_id: branch_with_future.aleo,\n function_name: qux,\n arguments: [\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n }\n \n ]\n}"}' + speculate: the execution was rejected + add_next_block: succeeded. +additional: +- child_outputs: + child.aleo/foo: + outputs: + - '{"type":"future","id":"1007218943892448396881984608789591386138448463982253582619598886555809869042field","value":"{\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n false\n ]\n}"}' + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"7279154627791442566716269908932031503401237694928695644266920103051053146747field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo19f7ldyn2txn950arxwzgmd69hc92agvaavuaghq3n86fv9sq25qsuu46xk,\n 3621u64\n ]\n}"}' +- child_outputs: + child.aleo/foo: + outputs: + - '{"type":"future","id":"6523588570064680536508996046957962672424151108590663750750787837041093106740field","value":"{\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n}"}' + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"2706575121475642341611541590945985021546461935095868862247496621536522314225field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo19f7ldyn2txn950arxwzgmd69hc92agvaavuaghq3n86fv9sq25qsuu46xk,\n 7974u64\n ]\n}"}' +- child_outputs: + child.aleo/foo: + outputs: + - '{"type":"future","id":"7099896312977564232797320902188423216986916921319466842263326120099548868611field","value":"{\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n}"}' + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"5609306293856270935956553758470706601318043257164762478045225948599710665248field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo19f7ldyn2txn950arxwzgmd69hc92agvaavuaghq3n86fv9sq25qsuu46xk,\n 7974u64\n ]\n}"}' +- child_outputs: + child.aleo/foo: + outputs: + - '{"type":"future","id":"7316695697531161977466260542069480710223810681294363821008640938964747660989field","value":"{\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n}"}' + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"4975770476920496431723834907301899193200403712078918738194361758999219139263field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo19f7ldyn2txn950arxwzgmd69hc92agvaavuaghq3n86fv9sq25qsuu46xk,\n 7974u64\n ]\n}"}' +- child_outputs: + child.aleo/foo: + outputs: + - '{"type":"future","id":"1227828349264772801087139238777793166868477097712714327572814639949280730734field","value":"{\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n}"}' + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"2067245925175924661138388013479706155165861522757906125647585548056761064730field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo19f7ldyn2txn950arxwzgmd69hc92agvaavuaghq3n86fv9sq25qsuu46xk,\n 7974u64\n ]\n}"}' +- child_outputs: + child.aleo/foo: + outputs: + - '{"type":"future","id":"772681503101026751767902223438249337461519645078898034778519190096015227607field","value":"{\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n true,\n true\n ]\n}"}' + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"2957923319159476718371769642772720537310282450705905850340576486880633947922field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo19f7ldyn2txn950arxwzgmd69hc92agvaavuaghq3n86fv9sq25qsuu46xk,\n 3521u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/child_and_parent.out b/synthesizer/tests/expectations/vm/execute_and_finalize/child_and_parent.out index cf83c9d485..0328cd2ae4 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/child_and_parent.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/child_and_parent.out @@ -4,30 +4,30 @@ outputs: execute: child.aleo/foo: outputs: - - '{"type":"public","id":"3583507900097573902692207210661581535840809808651900827750728854102720512424field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' - - '{"type":"public","id":"476166291720572191849579987891810720100233870490756615272004665719966045283field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' + - '{"type":"public","id":"990518176319329300540260363339673789976107460730294067348711019503474061851field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' + - '{"type":"public","id":"7571316186508319878827016469809649549608056961397657756993177747855651462866field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: parent.aleo/foo: outputs: - - '{"type":"public","id":"3761717515751581670491990458123447761370813910339791821189914541241041772398field","value":"aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy"}' - - '{"type":"public","id":"7311055836597830429601351369404551037507421904626326632284143897137420180918field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' - - '{"type":"public","id":"681818897459164396968079033669192296282137044899275115497211144004195398694field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' - - '{"type":"public","id":"3417320637392048962499244658848814085037481834432707606558978225870881469204field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' + - '{"type":"public","id":"1884811560356148016006955635652965080079915936694811538333847482246480744363field","value":"aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy"}' + - '{"type":"public","id":"5938049560052736143774141427220670377885179425739877702748657061561680738197field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' + - '{"type":"public","id":"6528548732759919272232987513159497491013177803981585005450673841162680315749field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' + - '{"type":"public","id":"5026832691298704787131751832692789283727293425012656525725701291723822396843field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' speculate: the execution was accepted add_next_block: succeeded. additional: - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"5245767978479482276373144091068362056657622227760198296183689243703275814117field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx,\n 1244u64\n ]\n}"}' + - '{"type":"future","id":"5082208301651373176623590811075106181267408732555436878022129644210755250685field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx,\n 1276u64\n ]\n}"}' - child_outputs: child.aleo/foo: outputs: - - '{"type":"public","id":"7812033131660295289207078830719348736788767283997224928167372421466500300696field","value":"aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy"}' - - '{"type":"public","id":"4227271453559074580761782898043117548320729393319599555165417123780466734088field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' + - '{"type":"public","id":"6466295524147957495454604434721348918327651050212037504999787142417111103417field","value":"aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy"}' + - '{"type":"public","id":"6332065223486256012523838059722457533475412222424700446882093528089704062322field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' credits.aleo/fee_public: outputs: - - '{"type":"future","id":"8216972065644000579816790328783540313220942313753411501386970051803831099199field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx,\n 2123u64\n ]\n}"}' + - '{"type":"future","id":"2655408226458975792257147092852146628510817001169201237526883739767924449396field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx,\n 2187u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/complex_finalization.out b/synthesizer/tests/expectations/vm/execute_and_finalize/complex_finalization.out index d413523f61..beb2cf653b 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/complex_finalization.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/complex_finalization.out @@ -4,23 +4,23 @@ outputs: execute: four_program.aleo/a: outputs: - - '{"type":"future","id":"665183472055988178271814702289264025474680637838536582821282925188065775088field","value":"{\n program_id: four_program.aleo,\n function_name: a,\n arguments: [\n {\n program_id: two_program.aleo,\n function_name: b,\n arguments: [\n {\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: three_program.aleo,\n function_name: e,\n arguments: [\n {\n program_id: two_program.aleo,\n function_name: b,\n arguments: [\n {\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n}"}' + - '{"type":"future","id":"8130018480615734196139013351437032069739242149156249631016045139853287093979field","value":"{\n program_id: four_program.aleo,\n function_name: a,\n arguments: [\n {\n program_id: two_program.aleo,\n function_name: b,\n arguments: [\n {\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: three_program.aleo,\n function_name: e,\n arguments: [\n {\n program_id: two_program.aleo,\n function_name: b,\n arguments: [\n {\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. additional: - child_outputs: zero_program.aleo/c: outputs: - - '{"type":"future","id":"1480766593085211098189114488792207994373740214001639330000129810788271883137field","value":"{\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n}"}' + - '{"type":"future","id":"2900271611655635528941678281510364041201830022813871095471877119312300779936field","value":"{\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n}"}' one_program.aleo/d: outputs: - - '{"type":"future","id":"6874436412573820073608038525233877999669336342335693667065896409420053741810field","value":"{\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n}"}' + - '{"type":"future","id":"1637337749821658761939392325641974939781345565015247398167259587180469940497field","value":"{\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n}"}' two_program.aleo/b: outputs: - - '{"type":"future","id":"439911297771864655257183196286454333195715414280549536084302592849654672842field","value":"{\n program_id: two_program.aleo,\n function_name: b,\n arguments: [\n {\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n}"}' + - '{"type":"future","id":"7281040962848614445322216992881261514828409296479704331863755128953658708630field","value":"{\n program_id: two_program.aleo,\n function_name: b,\n arguments: [\n {\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n}"}' three_program.aleo/e: outputs: - - '{"type":"future","id":"6324349534667114127832388996854882573236888808429320919855235417654165379333field","value":"{\n program_id: three_program.aleo,\n function_name: e,\n arguments: [\n {\n program_id: two_program.aleo,\n function_name: b,\n arguments: [\n {\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n}"}' + - '{"type":"future","id":"5525233450353730940847963432645555356450610982360915223305979656896688583051field","value":"{\n program_id: three_program.aleo,\n function_name: e,\n arguments: [\n {\n program_id: two_program.aleo,\n function_name: b,\n arguments: [\n {\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: one_program.aleo,\n function_name: d,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n {\n program_id: zero_program.aleo,\n function_name: c,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n },\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8\n ]\n}"}' credits.aleo/fee_public: outputs: - - '{"type":"future","id":"2642525527921148655203140665689909230400981948693155278410222306693462629362field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8,\n 1312883u64\n ]\n}"}' + - '{"type":"future","id":"2476029211140164583406148846888488002590412173500688831483102837916326251877field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8,\n 267576u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/count_usages.out b/synthesizer/tests/expectations/vm/execute_and_finalize/count_usages.out index bc0c5af71d..f63740483a 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/count_usages.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/count_usages.out @@ -4,20 +4,20 @@ outputs: execute: count_usages.aleo/add_and_subtract: outputs: - - '{"type":"private","id":"3123182017432916757124403751790889348245620410758014315114714729237515860473field","value":"ciphertext1qyqwsyyjjx85zuu3rh9ujc7lt33dgqj28xcpxa5vz0uscttkelcm2yglca4ja"}' - - '{"type":"future","id":"3075184327471252279705776826446991266718083739660015565935642091055852740382field","value":"{\n program_id: count_usages.aleo,\n function_name: add_and_subtract,\n arguments: [\n {\n program_id: basic_math.aleo,\n function_name: add_and_count,\n arguments: [\n aleo1mrughg5ssadd9fc2uwve7l6u24xn76kyz24zsjtzta03vgkq4vpqggl6fg\n ]\n },\n {\n program_id: basic_math.aleo,\n function_name: sub_and_count,\n arguments: [\n aleo1mrughg5ssadd9fc2uwve7l6u24xn76kyz24zsjtzta03vgkq4vpqggl6fg\n ]\n }\n \n ]\n}"}' + - '{"type":"private","id":"8025726332455529469861621128940817257864772349923128467234740989329902604473field","value":"ciphertext1qyqfup87pnm7e4d4tmxnwsqgttw0vh706ampljq46puzqtcmfrrjvzgd8mfq5"}' + - '{"type":"future","id":"447994789052632012998133268353748451374161019548829203650569518403555383774field","value":"{\n program_id: count_usages.aleo,\n function_name: add_and_subtract,\n arguments: [\n {\n program_id: basic_math.aleo,\n function_name: add_and_count,\n arguments: [\n aleo1mrughg5ssadd9fc2uwve7l6u24xn76kyz24zsjtzta03vgkq4vpqggl6fg\n ]\n },\n {\n program_id: basic_math.aleo,\n function_name: sub_and_count,\n arguments: [\n aleo1mrughg5ssadd9fc2uwve7l6u24xn76kyz24zsjtzta03vgkq4vpqggl6fg\n ]\n }\n \n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. additional: - child_outputs: basic_math.aleo/add_and_count: outputs: - - '{"type":"private","id":"8146495595200999887858412726015174541046002665643175756153664146614367276693field","value":"ciphertext1qyqgrgmhxyfjr3cvy50sy2hg8y56suw5wgvytygzms53mp4ms3v26rg226k3t"}' - - '{"type":"future","id":"4731072368922094762332855593966999173744758108005904730949638980529645559135field","value":"{\n program_id: basic_math.aleo,\n function_name: add_and_count,\n arguments: [\n aleo1mrughg5ssadd9fc2uwve7l6u24xn76kyz24zsjtzta03vgkq4vpqggl6fg\n ]\n}"}' + - '{"type":"private","id":"5275033890974719864618755320118789008496864993638234934817992876415596007788field","value":"ciphertext1qyqzjf0yj9kectcvg7u3dramjqfkady9n85lfsnt5t76hrufgdtd5qgzl8axw"}' + - '{"type":"future","id":"3797505847103929698534733656753772431719587131875982928485169994137133253960field","value":"{\n program_id: basic_math.aleo,\n function_name: add_and_count,\n arguments: [\n aleo1mrughg5ssadd9fc2uwve7l6u24xn76kyz24zsjtzta03vgkq4vpqggl6fg\n ]\n}"}' basic_math.aleo/sub_and_count: outputs: - - '{"type":"private","id":"961409263208860904485872221121989324413563522578995015597420037381610399703field","value":"ciphertext1qyqv6unr5dg8tj228pl0vgv32p92mcyxxyf9368salhtfqh0hd4scqc89y5m4"}' - - '{"type":"future","id":"4663027849889985446453275863200868545411574358675486387787337708909316167962field","value":"{\n program_id: basic_math.aleo,\n function_name: sub_and_count,\n arguments: [\n aleo1mrughg5ssadd9fc2uwve7l6u24xn76kyz24zsjtzta03vgkq4vpqggl6fg\n ]\n}"}' + - '{"type":"private","id":"5306487522628771911536425647010519062243539602607185695916137180263907877845field","value":"ciphertext1qyqtm7ftauwqqdeulvte8ju2tlh63r2zasjkn0sllu90544x4y48jzcxr46pm"}' + - '{"type":"future","id":"7178387428289602600711092668076659846217709523786758217423314545472680326773field","value":"{\n program_id: basic_math.aleo,\n function_name: sub_and_count,\n arguments: [\n aleo1mrughg5ssadd9fc2uwve7l6u24xn76kyz24zsjtzta03vgkq4vpqggl6fg\n ]\n}"}' credits.aleo/fee_public: outputs: - - '{"type":"future","id":"3084534457419184182612834880575828543753579447019853593724174249884664876235field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8,\n 263392u64\n ]\n}"}' + - '{"type":"future","id":"4545791856085096226280028672626922044233856981347579201659401898452378055384field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1kw4knandael9qcpxs6g36rr6h7dwvjz6q25ueah6zz9v57zjlvxsx5llq8,\n 54628u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/out_of_order_await_fail.out b/synthesizer/tests/expectations/vm/execute_and_finalize/future_not_all_awaited_fail.out similarity index 55% rename from synthesizer/tests/expectations/vm/execute_and_finalize/out_of_order_await_fail.out rename to synthesizer/tests/expectations/vm/execute_and_finalize/future_not_all_awaited_fail.out index 7d4109cee6..1a5ea465e8 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/out_of_order_await_fail.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/future_not_all_awaited_fail.out @@ -1,3 +1,3 @@ errors: -- 'Failed to run `VM::deploy for program parent.aleo: Futures in finalize ''foo'' are not awaited in the order they are passed in.' +- 'Failed to run `VM::deploy for program parent.aleo: Futures in finalize ''foo'' are not all awaited.' outputs: [] diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/future_out_of_order_fail.out b/synthesizer/tests/expectations/vm/execute_and_finalize/future_not_all_passed_to_async_call_fail.out similarity index 73% rename from synthesizer/tests/expectations/vm/execute_and_finalize/future_out_of_order_fail.out rename to synthesizer/tests/expectations/vm/execute_and_finalize/future_not_all_passed_to_async_call_fail.out index 0cea7546f1..97eece89e3 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/future_out_of_order_fail.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/future_not_all_passed_to_async_call_fail.out @@ -1,3 +1,3 @@ errors: -- 'Failed to run `VM::deploy for program parent.aleo: Function ''foo'' contains futures, but the ''async'' instruction does not consume all of them in the order they were produced' +- 'Failed to run `VM::deploy for program parent.aleo: Function ''foo'' contains futures, but the ''async'' instruction does not consume all of the ones produced.' outputs: [] diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/future_out_of_order.out b/synthesizer/tests/expectations/vm/execute_and_finalize/future_out_of_order.out new file mode 100644 index 0000000000..37c0cec8cc --- /dev/null +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/future_out_of_order.out @@ -0,0 +1,20 @@ +errors: [] +outputs: +- verified: true + execute: + parent.aleo/foo: + outputs: + - '{"type":"future","id":"7394141067016125812495697738481918699806105328524107874699813647057124800624field","value":"{\n program_id: parent.aleo,\n function_name: foo,\n arguments: [\n {\n program_id: child.aleo,\n function_name: boo,\n arguments: [\n aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy\n ]\n },\n {\n program_id: child.aleo,\n function_name: boo,\n arguments: [\n aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy\n ]\n },\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy\n ]\n },\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy\n ]\n },\n {\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy\n ]\n },\n {\n program_id: child.aleo,\n function_name: boo,\n arguments: [\n aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy\n ]\n }\n \n ]\n}"}' + speculate: the execution was accepted + add_next_block: succeeded. +additional: +- child_outputs: + child.aleo/foo: + outputs: + - '{"type":"future","id":"6485462397262850046279599964897487902629807964673846177946918357772313064816field","value":"{\n program_id: child.aleo,\n function_name: foo,\n arguments: [\n aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy\n ]\n}"}' + child.aleo/boo: + outputs: + - '{"type":"future","id":"4231693232342038432096905559496831296662691811920617963100466383368358118453field","value":"{\n program_id: child.aleo,\n function_name: boo,\n arguments: [\n aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy\n ]\n}"}' + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"6200338300657724671187031761556738257498692708872458275509558643397811394605field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx,\n 170808u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/hello.out b/synthesizer/tests/expectations/vm/execute_and_finalize/hello.out index 4ee4b5c467..9ae4a9721c 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/hello.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/hello.out @@ -4,46 +4,46 @@ outputs: execute: hello.aleo/hello: outputs: - - '{"type":"private","id":"6254379462913920094060616443827416926361791013133233839133894947200598009041field","value":"ciphertext1qyqpmnatnq3sjej6qves695qtxu5r6lqnfnx8ck87ce3pez28x90qzgzeh4qh"}' + - '{"type":"private","id":"5131573882884355182257903682248009545514589905872111590766989489749736641421field","value":"ciphertext1qyqxs4ww08ecfsfuzv3lvu2ylddz566evdd0kn2kq7tffa0jfvhrvzguk9nns"}' speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: hello.aleo/hello: outputs: - - '{"type":"private","id":"4161183151518570414349285932182760288961689691043823886807644299644687930091field","value":"ciphertext1qyqreg8a27jzsgm7m5umh98nr9nwyxhkv3aus5htm6vepdkr67zh5zqc4uzpd"}' + - '{"type":"private","id":"6540258413886922786374562206523527552103922311417806085516123700513573545786field","value":"ciphertext1qyqvn6jqqsvl59jdxc56fvgrthy7s29uy59y0q2854ule9eaa3qryrgch9lan"}' speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: hello.aleo/goodbye: outputs: - - '{"type":"public","id":"5242826180235740795678885917758843199455932502638973701040836238216490364326field","value":"1u32"}' - - '{"type":"future","id":"5032744372214352919665806641360511690042524830912111693095233654380228978511field","value":"{\n program_id: hello.aleo,\n function_name: goodbye,\n arguments: [\n 1u32,\n 1u32\n ]\n}"}' + - '{"type":"public","id":"6552887319744710599952238134121182296015937968688536410722019448386949169427field","value":"1u32"}' + - '{"type":"future","id":"5050616512049212243885955271314949172240054022718808683458392630651227324539field","value":"{\n program_id: hello.aleo,\n function_name: goodbye,\n arguments: [\n 1u32,\n 1u32\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: hello.aleo/goodbye: outputs: - - '{"type":"public","id":"5954748469306089505201665920330448486455515953532955699388262149494774760375field","value":"1u32"}' - - '{"type":"future","id":"4063241715105271542572794266017703704121932214929814829482077839560118863776field","value":"{\n program_id: hello.aleo,\n function_name: goodbye,\n arguments: [\n 0u32,\n 1u32\n ]\n}"}' + - '{"type":"public","id":"6400980542699018627296357305462852503933659601582924856954999457729562650216field","value":"1u32"}' + - '{"type":"future","id":"7006417515763656381602371422606135723079202677418702102733862526204379263166field","value":"{\n program_id: hello.aleo,\n function_name: goodbye,\n arguments: [\n 0u32,\n 1u32\n ]\n}"}' speculate: the execution was rejected add_next_block: succeeded. additional: - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"5633762070565015506869877991983247311752566772551740661334199093127666173285field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 1285u64\n ]\n}"}' + - '{"type":"future","id":"4794226115128098661953863457300334535735190584732192888559305107927143173518field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 1317u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"4168535226825329132770722118865464284070271653060849404506023921600553004505field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 1285u64\n ]\n}"}' + - '{"type":"future","id":"5133026235053133038853489406821436126957097823152662530596593777687622314058field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 1317u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"7264507997475302694771209211625280132862970630053323876707987175500028146955field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 5334u64\n ]\n}"}' + - '{"type":"future","id":"8038906995585515708485738975797104585040095967461431356593208300992698109622field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 2366u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"2296589459402270097535149680764663519350069575816165257148428557434644368237field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 5334u64\n ]\n}"}' + - '{"type":"future","id":"4944753227454044798048990117828783917614367206136243192189386592713292937485field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 2366u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/many_input_and_output.out b/synthesizer/tests/expectations/vm/execute_and_finalize/many_input_and_output.out new file mode 100644 index 0000000000..c2b7225a7d --- /dev/null +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/many_input_and_output.out @@ -0,0 +1,147 @@ +errors: [] +outputs: +- verified: true + execute: + gas_dos.aleo/make_trash_empty: + outputs: [] + speculate: the execution was accepted + add_next_block: succeeded. +- verified: true + execute: + gas_dos.aleo/make_trash: + outputs: + - '{"type":"public","id":"4613003495305280459172342896551360642380671085549872261236450521478375822923field","value":"0u8"}' + - '{"type":"public","id":"4743973134972472397815524098463791938088484597045636063046205639313933518929field","value":"1u8"}' + - '{"type":"public","id":"555760781568939132183826755180684628980232466161467457554743035258901627869field","value":"2u8"}' + - '{"type":"public","id":"3157694875275263094900138843883455412991376860903973463649620138981676546252field","value":"3u8"}' + - '{"type":"public","id":"4762500691148246777860506295457421886000017089715781091140762580325095831542field","value":"4u8"}' + - '{"type":"public","id":"1619722509495388564896980055966430841124315339169633235607412171424218427952field","value":"5u8"}' + - '{"type":"public","id":"8354514207710319608700853875463103658360125733069755379916199418993984711704field","value":"6u8"}' + - '{"type":"public","id":"6146446795421276186773995055780858309920249415477095573801103513078202466762field","value":"7u8"}' + - '{"type":"public","id":"2318001922627984302376561180924956547473501650251936319394563635511287937792field","value":"8u8"}' + - '{"type":"public","id":"4335724698080250340144894758211764587953579002993217725228936749078063414122field","value":"9u8"}' + - '{"type":"public","id":"8087676879614137262566286145836111514718966108005879865108580502029152532529field","value":"10u8"}' + - '{"type":"public","id":"294493159771562529206823786373039528720886487276115087913605316823853612607field","value":"11u8"}' + - '{"type":"public","id":"7204985738453874970058286203045669825080258822596932900829393698406829649806field","value":"12u8"}' + - '{"type":"public","id":"830263914519050309337445423798113726576252534917054054561542101941345296949field","value":"13u8"}' + - '{"type":"public","id":"1469344004751424930670484441438499660924597114570570881074573778558606199421field","value":"14u8"}' + - '{"type":"public","id":"3951700828605478129702178277179066393576016187563440775486667382338991730643field","value":"15u8"}' + speculate: the execution was accepted + add_next_block: succeeded. +- verified: true + execute: + gas_dos.aleo/make_trash_private: + outputs: + - '{"type":"private","id":"5075362786697228215074472689942282701176231326430148288153418644541993540260field","value":"ciphertext1qyq8e9mevs4f9d59m6euas8grjuh4ng9ra32wwalxrnmaqmt7zyhkrscfm5fc"}' + - '{"type":"private","id":"5215225807132022158772545163740191062021730292490702535858154988807087753346field","value":"ciphertext1qyq2n8kh9husn8fhthnjgl8pjx6rc4g8c8tww2cae8zgjvsyuczxwpsanm54z"}' + - '{"type":"private","id":"6175485655830032812766870418391865949244585379793763982149649085962245726608field","value":"ciphertext1qyq0er0k7vk5hl2aue0sk90qz73ck8megp55r7wq5f2sc6te5e05crsghch95"}' + - '{"type":"private","id":"5292275369500734838902716815450230196630574445733214603628601920690693640207field","value":"ciphertext1qyq88qsgf25luc6e9hlaf95zd85gv7mx9dds396g3sd2j5xq7duu6rgwm52s2"}' + - '{"type":"private","id":"5381081294119826457204466226498552808197680922513323705838868647170112039605field","value":"ciphertext1qyqwagaeurk00c7am8u9h3tp8junvm87tq8pj95s5gt986plh8ezjqc4rtrmd"}' + - '{"type":"private","id":"1338461598474952534342699170627985736475769297938400754126083218144339953603field","value":"ciphertext1qyqgfdavmh84hfusth9cx0ctlx4v9pha3x09ufemkr2yk0drj5795zsxsa4lj"}' + - '{"type":"private","id":"4001260300537073559558326413857426277645481169425487516456210690061410740879field","value":"ciphertext1qyqqmuarzt3dgqrkvdrtnekzsfskq7lh44ljteez87fx2hzm6w0egqcd8dlnf"}' + - '{"type":"private","id":"5227242698626712211718588424963656563037146375530018083082654862574376070199field","value":"ciphertext1qyqtt366wyukvrej944ejpm6v8ac48lraf5ma0mpehkq0j6v5f8y2qswy7gjt"}' + - '{"type":"private","id":"7483071445708773648853126565285398442732297851577050757881107945512071186435field","value":"ciphertext1qyqgkmpfnmz3ewj6k44xtr6l5y0plar2txg0zdwhckuh9kj863gh7pck3nxvn"}' + - '{"type":"private","id":"4981561573377555124720956600158756464459035871604435708642730148102441448296field","value":"ciphertext1qyq2crnyagzpqttanxm8lseaca7rsedajjfnm8wd8ejs4cdjpwjgxyqesl8tj"}' + - '{"type":"private","id":"2218867027475576562642471060864076730679142980473955816748250394152189017698field","value":"ciphertext1qyqrcaa9t2j4366qlp032zpsxtz3zpdfsxcdfn582py42pmtawf42rgx00mtc"}' + - '{"type":"private","id":"7393332991553464721374713719439977665925434096754056861442821575301509587543field","value":"ciphertext1qyqq3z6rz487swgnucql7e5uy484uha55lqvahhe43p9unl9h82guqq9ntknu"}' + - '{"type":"private","id":"4508485010608517903938357676657986339889610151407496428609804193804937924386field","value":"ciphertext1qyq2lrkauz3xquc54vcxyyte4694xnjxty2qt0nzy7q7swv6d4jwkpga37eyg"}' + - '{"type":"private","id":"5742046849120914998776327076031156076910427012002979898907493381061401274278field","value":"ciphertext1qyqz53j22apn3j6ztuucxnscmqyf98swr77l007qcs0jmam748vauygp2meg9"}' + - '{"type":"private","id":"955655251996890605872283601090881531746554959441612709205216411773137158294field","value":"ciphertext1qyqz5jat55vkglewug0nrpuhag5kc7n686wpfsu5hax2r2kj3d9x6pcmf5vay"}' + - '{"type":"private","id":"4373428812215437035380352561693300320904292383523519816271482268910523671786field","value":"ciphertext1qyq0vfet29vt9zgcta0js2m8t55yuvtjxzrml37hn2sfjc3km84lgpslud9mn"}' + speculate: the execution was accepted + add_next_block: succeeded. +- verified: true + execute: + gas_dos.aleo/make_trash_u64: + outputs: + - '{"type":"public","id":"6561159162501436151833081072814273870341639293232110695344791012569330235567field","value":"0u64"}' + - '{"type":"public","id":"7976342331909399277968579813342476842205479436517570814610848133471694590264field","value":"1u64"}' + - '{"type":"public","id":"7959564125019725319347269801297404917426966769897554182837555918999454670634field","value":"2u64"}' + - '{"type":"public","id":"3238578569461990585696007719064622713088324042084449251953551113405629735368field","value":"3u64"}' + - '{"type":"public","id":"2652351791392146183676186801776231305352586712963350968069669298772399762725field","value":"4u64"}' + - '{"type":"public","id":"2478951039021272007380220086890354432897243703808216707237374481504263920606field","value":"5u64"}' + - '{"type":"public","id":"6972212493349432022365386848181522590861575488437719975243869032659990316485field","value":"6u64"}' + - '{"type":"public","id":"770689646887905178427189789229328921942429186529411387025482086356305613402field","value":"7u64"}' + - '{"type":"public","id":"2553434581363211725353578850893508886122005522502786996883588898494362910064field","value":"8u64"}' + - '{"type":"public","id":"789035962301829680165600926334353315362445916301262938083061420271282046080field","value":"9u64"}' + - '{"type":"public","id":"2055266195117958331915570632100818483950700115783436413748712133711381881360field","value":"10u64"}' + - '{"type":"public","id":"3383469571899269330052105933946449998458706830571461636127918368823078955516field","value":"11u64"}' + - '{"type":"public","id":"6861968034072116205338864606251025191903009704131735615422207451203652008789field","value":"12u64"}' + - '{"type":"public","id":"3625546002618020464563336277084886351400397856943513367013736399595665961595field","value":"13u64"}' + - '{"type":"public","id":"6365291161772542284506285608326579244113169513684131987526845079850460097561field","value":"14u64"}' + - '{"type":"public","id":"6911075033623689961880813487820362603810774997714972050027042318795566339300field","value":"15u64"}' + speculate: the execution was accepted + add_next_block: succeeded. +- verified: true + execute: + gas_dos.aleo/make_trash_call_inner: + outputs: [] + speculate: the execution was accepted + add_next_block: succeeded. +- verified: true + execute: + gas_dos.aleo/make_trash_call_inner_private: + outputs: [] + speculate: the execution was accepted + add_next_block: succeeded. +additional: +- child_outputs: + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"30377576158265317558755379954993028591609254873982684478794593156637801471field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 1153u64\n ]\n}"}' +- child_outputs: + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"7152805026835105172873716091653957285497801764420533865012961263887557911642field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 2363u64\n ]\n}"}' +- child_outputs: + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"5397557371756282637972927997465824050186286008844168472103952190845537160019field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 3331u64\n ]\n}"}' +- child_outputs: + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"8367501851131349939921973827792399149698467053837913250296494006847175395216field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 2591u64\n ]\n}"}' +- child_outputs: + child.aleo/inner_trash: + outputs: + - '{"type":"public","id":"4258324859805218266091084729946080164724004439941647295375853291687898384011field","value":"0u8"}' + - '{"type":"public","id":"3595631725148264940723309249621738480517311836274280006312645287099329149900field","value":"1u8"}' + - '{"type":"public","id":"2208089297394694158284480136926424455853818009780901740335992064322863047854field","value":"2u8"}' + - '{"type":"public","id":"5688569742397292953325301820131013260933141797177046282596309663462217883051field","value":"3u8"}' + - '{"type":"public","id":"2589267864343727922187358819999124949209392983206592238621055394960841163796field","value":"4u8"}' + - '{"type":"public","id":"5570995534518087989637976676554735206972855495625472364363176802857733417627field","value":"5u8"}' + - '{"type":"public","id":"8196563339749078100880844141424856480535908196271709028877208224433618877988field","value":"6u8"}' + - '{"type":"public","id":"7148315770592140943513870153102249250228881430428702700808302274830524589712field","value":"7u8"}' + - '{"type":"public","id":"6663559720474154178048021670448619949127654696632516449974104667634461721117field","value":"8u8"}' + - '{"type":"public","id":"4262855828324563363534601768851246835981293807453200126654359299458266116785field","value":"9u8"}' + - '{"type":"public","id":"6521499071950259584214330036864628156304358707158918480447672091139469907706field","value":"10u8"}' + - '{"type":"public","id":"2780007533160863507824876124934740257440095453590254944663640741879602528021field","value":"11u8"}' + - '{"type":"public","id":"721098730065242758038656029883330636635690005801014175788365363405106507710field","value":"12u8"}' + - '{"type":"public","id":"1618474055793768647053046125452575920962293293427476033678666992071443340286field","value":"13u8"}' + - '{"type":"public","id":"7590795669806505477347034268411170284443113115706119538121917286692343733758field","value":"14u8"}' + - '{"type":"public","id":"1746336793593389412246115464856173762500352378534009993091610413102060730893field","value":"15u8"}' + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"5250440250402479079384063487005279094696810892831249221778965713200207755186field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 11424u64\n ]\n}"}' +- child_outputs: + child.aleo/inner_trash_private: + outputs: + - '{"type":"private","id":"7104678975139771363369594082563366139468419554792208200047887347265545145473field","value":"ciphertext1qyq9csv2ts7auvzxrkgn59a6rf8rqp6x2lf3w8ylt420d4kdtjdn6ygx59j9y"}' + - '{"type":"private","id":"4926801310215014544954805559748287683167556580631648005183029762556664410062field","value":"ciphertext1qyq0x7ckpfm9u4rgk63hu7hccv0lde7qrtk90jxz4yvc3s27ya4zspsh64e4t"}' + - '{"type":"private","id":"3025158373600515167086001776793503086916479802702564323801256579855996236632field","value":"ciphertext1qyqgfpx70l4hhrpakl68z2wk2pval26vdwcjmjxxn6frkfauerdzsqq4py8pj"}' + - '{"type":"private","id":"91252220510257006296141223052114223378062152895167144867716852708928779745field","value":"ciphertext1qyq8q940d2j3zqu70f36xxe9che64zr2dxmuj75al3s0szts5ged5qcd459hc"}' + - '{"type":"private","id":"5222252760545452319316061497006736874983610477915769389758850306932549009630field","value":"ciphertext1qyqv6srxvu332xw3fua0al4wyzl49trvf7zn494j9leqvlahjpd5vrqh7jvyq"}' + - '{"type":"private","id":"6570786723987093104854522607966362693823233854131838411624481962428800920246field","value":"ciphertext1qyqv9ynxzkjmgjz66lrk3m2u9ntnfyvtl7s53l9dv3ar6y7x3nhlgpgaty4gy"}' + - '{"type":"private","id":"2683545714029027507827575346619167326043917479293098006245564541553014010650field","value":"ciphertext1qyqrnaw6d35mje37hld3wl4e8t80cch3r4hatemlzp7f5vt37wyturqcgnkqn"}' + - '{"type":"private","id":"979466994657219968516975870288881292162693708243771712684837117887100077495field","value":"ciphertext1qyqzmsqd9qpj6pwjc6955em3vedjc0s7h9gh74740kgxc5yzt6dmszqaqu62w"}' + - '{"type":"private","id":"148667955008751009932158730385746655132283758474039163840641702069085619092field","value":"ciphertext1qyqwrn34ueq83rw56avjhqe5kf7thtycr9dykavv0cag665len6z2yqpq5pty"}' + - '{"type":"private","id":"7440731129863281004684810942181870487300540297612431366993708247292317262618field","value":"ciphertext1qyqghgjccg8mjwn6mfk83gtpdejh6h5kgs8qngk6ylphuh8g02ma7rgpe9dda"}' + - '{"type":"private","id":"5901834737807982708978098599410021094561231224925091918983759660264223855752field","value":"ciphertext1qyqyz9pm6vgud68p0fda6lhzyfhrxhz369futwgyng93su8scrxp2yqjcg5ru"}' + - '{"type":"private","id":"7104894195533495611191959689141824024501967138573740980071353687538059813029field","value":"ciphertext1qyqr9sk4jws9ay4ujvlcf9xpzuhv2pnrujnv4nd467zkjv4ur66f7pgw5ppfm"}' + - '{"type":"private","id":"3048268228937191827597549490157315246711775336097603143181590343332295202352field","value":"ciphertext1qyqv58yu833x9zepyqfdq3fga79zcrpakeum5asuhn3st9aqeud0gzctx80jg"}' + - '{"type":"private","id":"4285685390670718078925042810300519660137065409265643363257317816624967274406field","value":"ciphertext1qyqfglq63hwn08zasfr82mpk550ctlx7k4d75hns5xaah4y6e36rvpgtw0rvq"}' + - '{"type":"private","id":"3025983048580884853315325717609008421056210836218565341349583681822517287251field","value":"ciphertext1qyqx8mrevae4zw38t3lpyw797hml2ff8v6u84fksax87fym54s7yxqc2zzmn8"}' + - '{"type":"private","id":"2779056585045156925102248171451904784889711185488933072280044292443284680942field","value":"ciphertext1qyqg7e5rdtam09s2zwzmg3j3ppfppnczyvrrwaezg5xtv60njx0vjpcm0pvrh"}' + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"4439477569395306322955911813937256917619490308008069715554457025369290347633field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo10knkelvnd55fsaarm25wch7p9suf2tqlgwy5k4nxwms6d262xyfqm2tccr,\n 26165u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/mapping_operations.out b/synthesizer/tests/expectations/vm/execute_and_finalize/mapping_operations.out index 6b2773e6cf..26f74a152e 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/mapping_operations.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/mapping_operations.out @@ -4,44 +4,44 @@ outputs: execute: mapping_operations.aleo/empty_remove: outputs: - - '{"type":"future","id":"7635640739633293853436744163909014640199975942090334368682977334784204769011field","value":"{\n program_id: mapping_operations.aleo,\n function_name: empty_remove,\n arguments: [\n 10u8\n ]\n}"}' + - '{"type":"future","id":"2995172019915059564169965195925439506348172779175289540071594220373700362692field","value":"{\n program_id: mapping_operations.aleo,\n function_name: empty_remove,\n arguments: [\n 10u8\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: mapping_operations.aleo/insert_contains_remove: outputs: - - '{"type":"future","id":"2222820579352641087756930842916349134795974577897148450258189134473958563715field","value":"{\n program_id: mapping_operations.aleo,\n function_name: insert_contains_remove,\n arguments: [\n 0u8,\n 0u8\n ]\n}"}' + - '{"type":"future","id":"4734089311297117835126604932112275842487641749640619553922194716113265671275field","value":"{\n program_id: mapping_operations.aleo,\n function_name: insert_contains_remove,\n arguments: [\n 0u8,\n 0u8\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: mapping_operations.aleo/insert_contains_remove: outputs: - - '{"type":"future","id":"7976126249407457464284575267611007374057326939931567034459595303517614384513field","value":"{\n program_id: mapping_operations.aleo,\n function_name: insert_contains_remove,\n arguments: [\n 0u8,\n 0u8\n ]\n}"}' + - '{"type":"future","id":"230840103691729731055170563366218895016668781612853841661286026410302607495field","value":"{\n program_id: mapping_operations.aleo,\n function_name: insert_contains_remove,\n arguments: [\n 0u8,\n 0u8\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: mapping_operations.aleo/insert_contains_remove: outputs: - - '{"type":"future","id":"7584999017838461056060100707559452462656710499900127442904227073384510302747field","value":"{\n program_id: mapping_operations.aleo,\n function_name: insert_contains_remove,\n arguments: [\n 0u8,\n 1u8\n ]\n}"}' + - '{"type":"future","id":"3315769874935654804431942155043603401753352960520513759478780430664575888438field","value":"{\n program_id: mapping_operations.aleo,\n function_name: insert_contains_remove,\n arguments: [\n 0u8,\n 1u8\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. additional: - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"3701652920213282423281084685169254121653756184853703028504071363673532942725field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1eakarna6a70pg9r0l9qal20faejwctgur5xt7lnc2a42wj2yssfqc89rk8,\n 11245u64\n ]\n}"}' + - '{"type":"future","id":"2881122525232065385481796721562444359720272068488472880078531341886151580916field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1eakarna6a70pg9r0l9qal20faejwctgur5xt7lnc2a42wj2yssfqc89rk8,\n 11277u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"767852843394263062723803642109980847781175859546892255347263461730875281315field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1eakarna6a70pg9r0l9qal20faejwctgur5xt7lnc2a42wj2yssfqc89rk8,\n 154810u64\n ]\n}"}' + - '{"type":"future","id":"6719612682279408983981783077880397063556905449118263853724176678274966881762field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1eakarna6a70pg9r0l9qal20faejwctgur5xt7lnc2a42wj2yssfqc89rk8,\n 53072u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"5831877738131393412656336446760308055442933218729238434398743654782252530700field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1eakarna6a70pg9r0l9qal20faejwctgur5xt7lnc2a42wj2yssfqc89rk8,\n 154810u64\n ]\n}"}' + - '{"type":"future","id":"6685223531240969717295379114037138437571065736359141263535338788158408659918field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1eakarna6a70pg9r0l9qal20faejwctgur5xt7lnc2a42wj2yssfqc89rk8,\n 53072u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"3924911723698610328779426182874581891939297874519691347932588542992608923909field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1eakarna6a70pg9r0l9qal20faejwctgur5xt7lnc2a42wj2yssfqc89rk8,\n 154810u64\n ]\n}"}' + - '{"type":"future","id":"6136819185906425044619698216040414457898459958353995998170624664122379782065field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1eakarna6a70pg9r0l9qal20faejwctgur5xt7lnc2a42wj2yssfqc89rk8,\n 53072u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/mint_and_split.out b/synthesizer/tests/expectations/vm/execute_and_finalize/mint_and_split.out index bd63f8cfca..9f13732cf1 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/mint_and_split.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/mint_and_split.out @@ -4,7 +4,7 @@ outputs: execute: mint_and_split.aleo/mint: outputs: - - '{"type":"record","id":"7334558502140616765536611609313499148179717945955456292257315684677266501449field","checksum":"281154250604636828435706866945909260040573817788279288153963030037316744168field","value":"record1qyqsp9pr7qlgedcywvyk5lsnpuqpepyuv9hseec63eacjpn8d0rpmwgsqyxx66trwfhkxun9v35hguerqqpqzq9ql0hu0da6wuzrm0a7ms3kfvj5279e43rulstm9plhzs0z0xe6p52cn7pdz7x5hkwhz905kp56f4fuq08k9maf57qteekdv9yddk8sqxq4d98"}' + - '{"type":"record","id":"5362233052560846238226654677312070784713895947130881249083843529510916944031field","checksum":"7816912889670526743054988042995440028407660195896606816511174108297987149569field","value":"record1qyqsqh5ywrvf42cljl67xcgzp39wdhlygqmkjkuwgaj827945h9wgfcgqyxx66trwfhkxun9v35hguerqqpqzqzu388z96mn6rf76798hkmwp9753jyjz72qhr8xxqkxv6smct5upj9v8v5krsdhxk3hculcusw7mj54de50d5g9seqdey800qseawz3y2tgsyg"}' speculate: the execution was accepted add_next_block: succeeded. - execute: Commitment '1266307482263846358970326041806201638141701138269282465033372005968041137990field' does not exist @@ -13,6 +13,6 @@ additional: - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"2224596965693604846363254284152512550549945382876106932610187515185636813504field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo19e6k5ferx3k8a9k79xtj4uuaztt2jl4eza7k43pygsu977yazypqqwdmw6,\n 1414u64\n ]\n}"}' + - '{"type":"future","id":"2562090260329031660713384309168507515341431313675137173177615123065204014729field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo19e6k5ferx3k8a9k79xtj4uuaztt2jl4eza7k43pygsu977yazypqqwdmw6,\n 1446u64\n ]\n}"}' - {} - {} diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/program_callable.out b/synthesizer/tests/expectations/vm/execute_and_finalize/program_callable.out index 8bb0637e68..20ccef0610 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/program_callable.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/program_callable.out @@ -5,10 +5,10 @@ outputs: execute: parent.aleo/foo: outputs: - - '{"type":"public","id":"7957417389566842019333476383015223465797041221984916169491225413765492389707field","value":"aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy"}' - - '{"type":"public","id":"5660332966063165816193998255057769236492104556419359071777110117631685203432field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' - - '{"type":"public","id":"119590126009840588550727571915536854356547100414781210870229193044716803923field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' - - '{"type":"public","id":"3955648008862663886784245642019540732803638576128766893102159939289033551109field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' + - '{"type":"public","id":"3914637036303864526243159286220007976533170083569928638487262238892809970742field","value":"aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy"}' + - '{"type":"public","id":"937398777111453785192036425221737880852307156425401363223955833596768256674field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' + - '{"type":"public","id":"3760234756062381156062268377754871790067277250188262172583636143907064923470field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' + - '{"type":"public","id":"5488414192083883572281689896150580843935493231906795299005325757111494763599field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' speculate: the execution was accepted add_next_block: succeeded. additional: @@ -16,8 +16,8 @@ additional: - child_outputs: child.aleo/foo: outputs: - - '{"type":"public","id":"5860672233404277218165914850445330702482897594856038385529876412918074003384field","value":"aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy"}' - - '{"type":"public","id":"7032360703707892728582573080419248600535906704593225990910797295396231122684field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' + - '{"type":"public","id":"7280898116097274651284715158779545453186426181228488452909864525015787112960field","value":"aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy"}' + - '{"type":"public","id":"4075151575211412636182527473997668377132540629423063277503775378409385373898field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' credits.aleo/fee_public: outputs: - - '{"type":"future","id":"3173434315503739455207432985984041544966817001490874630397863189982314711932field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx,\n 2123u64\n ]\n}"}' + - '{"type":"future","id":"7802751002421695323881906367190483603442707786944479318276597578348108753232field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx,\n 2187u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/public_wallet.out b/synthesizer/tests/expectations/vm/execute_and_finalize/public_wallet.out index cbb7f2d77c..9f771050cb 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/public_wallet.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/public_wallet.out @@ -4,14 +4,14 @@ outputs: execute: public_wallet.aleo/init: outputs: - - '{"type":"future","id":"2740109864087873652477151933781698204925175410187376817867987810696050546048field","value":"{\n program_id: public_wallet.aleo,\n function_name: init,\n arguments: [\n {\n program_id: token.aleo,\n function_name: mint_public,\n arguments: [\n aleo1sry3pke49ykrf0aeshf889tr98r4c86p5f4ms766795ssdwfdyqq9jdg0j,\n 10u64\n ]\n }\n \n ]\n}"}' + - '{"type":"future","id":"8260497972742778111367097052162295474031012001184713805972943051311817949697field","value":"{\n program_id: public_wallet.aleo,\n function_name: init,\n arguments: [\n {\n program_id: token.aleo,\n function_name: mint_public,\n arguments: [\n aleo1sry3pke49ykrf0aeshf889tr98r4c86p5f4ms766795ssdwfdyqq9jdg0j,\n 10u64\n ]\n }\n \n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. additional: - child_outputs: token.aleo/mint_public: outputs: - - '{"type":"future","id":"2095235103073153862497986952383880687050623273703041876358116424903602929020field","value":"{\n program_id: token.aleo,\n function_name: mint_public,\n arguments: [\n aleo1sry3pke49ykrf0aeshf889tr98r4c86p5f4ms766795ssdwfdyqq9jdg0j,\n 10u64\n ]\n}"}' + - '{"type":"future","id":"8286939272855752797035017591517297078431849718370537735860811608893885242485field","value":"{\n program_id: token.aleo,\n function_name: mint_public,\n arguments: [\n aleo1sry3pke49ykrf0aeshf889tr98r4c86p5f4ms766795ssdwfdyqq9jdg0j,\n 10u64\n ]\n}"}' credits.aleo/fee_public: outputs: - - '{"type":"future","id":"4373249435479943424484888940718424132561120812144078253060284512525421799293field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1d3e2je2m2hsxwdsvntvf4jnnlj459ywfry6ch2qwrpy6l6r6yvpq8e88h5,\n 131201u64\n ]\n}"}' + - '{"type":"future","id":"7334131816336578548207468749349798727140016102586366303966330861449690845886field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1d3e2je2m2hsxwdsvntvf4jnnlj459ywfry6ch2qwrpy6l6r6yvpq8e88h5,\n 27585u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/read_external_mapping.out b/synthesizer/tests/expectations/vm/execute_and_finalize/read_external_mapping.out index a729b3163e..4b81518d24 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/read_external_mapping.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/read_external_mapping.out @@ -4,70 +4,92 @@ outputs: execute: relay.aleo/send: outputs: - - '{"type":"record","id":"5505341694097720023583674648027312667621444458172921945164834002648638744768field","checksum":"4170712463954366904268628656227022271867279479485549214633981747772705648157field","value":"record1qyqsp358e054av498aavwel28wr36tg0ay27k4fc539ffmwz2nddl8gqqyzxgct5vy3sqqspqpfgwnp3rnwprhd2q3h8gmxcnldlczrvszade4vzxlu7dmfeg6j3rd8mwuzysqtgl6603ey2zzry8hjwmn3pt3twclpkkvssc4l4jzsvd6lxar"}' - - '{"type":"future","id":"5336913895922947334887041593466841136470735988519588898509306662059714980450field","value":"{\n program_id: relay.aleo,\n function_name: send,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' + - '{"type":"record","id":"7968575772902157337987790733839692617009611839021233180102360727599749340064field","checksum":"6485720190771667896136202589799315744497017899341299453023655037633886111955field","value":"record1qyqsqa8wejf3pktamg3d4zjzg60t4dagq3qv9l0t4em98x0l9yz4wtc9qyzxgct5vy3sqqspqp6k9wcd0r5n0zv2zfj64kn6g6lvhd6qmzhyftycf2jptp0z7mqqr24jykrxzjjh327raww8grz503e0kndrqszz65x3pp6tvr8fedqy55ahc4"}' + - '{"type":"future","id":"4831496979974153421195875947823828412750550539628662893314839630114070713887field","value":"{\n program_id: relay.aleo,\n function_name: send,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' speculate: the execution was rejected add_next_block: succeeded. - verified: true execute: relay.aleo/send_without_check: outputs: - - '{"type":"record","id":"4755207731349921544198839760105069860415948248486655350742993041864954064196field","checksum":"7848435433502532569425287419063381736913355859517668180377091558079541996646field","value":"record1qyqsp83ncqrtrev57v03h3j8qcysfgef256zh7pmh7zgj83h6g7tfkq0qyzxgct5vy3sqqspqzx4ww05zz3grf6hxgr46csu2vmzr2lgq0f48kxp4j383l68ufqsq45f8wqk6jxfnkm6v92cq48xea0tfrg0fwwr249m95t4eka6jkgv0c5y7k"}' - - '{"type":"future","id":"1027044606530325120447980237911983680107621060206232306337126914234987187002field","value":"{\n program_id: relay.aleo,\n function_name: send_without_check,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' + - '{"type":"record","id":"2107603422312742796848682783963122836002371588713615328290812324544088758847field","checksum":"8275335694262210679186802244264061517465864466037908296140182924461667936315field","value":"record1qyqsp7uvd7gsea34c3arhfjr5setujmdex2hr6c5nvw3wuhjpz3r6uszqyzxgct5vy3sqqspqzac5vgg52z3jshxttd4ekmnq59l39qt9gg3v0y700xtnlqfmq0p9kqrjkktnje0v2cu8d3xa8d0m8dee9umhsmr27qqqz42rlzwtqsqmke8me"}' + - '{"type":"future","id":"1466198210314069047165522334753605767036936785663542828862455797550717023142field","value":"{\n program_id: relay.aleo,\n function_name: send_without_check,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. +- verified: true + execute: + relay.aleo/check_has_registered: + outputs: + - '{"type":"future","id":"2177670626770212991926988612892200016040439353062111366356381933892230577888field","value":"{\n program_id: relay.aleo,\n function_name: check_has_registered,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' + speculate: the execution was rejected + add_next_block: succeeded. - verified: true execute: registry.aleo/register: outputs: - - '{"type":"future","id":"4059159583881077685368973757192878822018897618745592372395499886263264340961field","value":"{\n program_id: registry.aleo,\n function_name: register,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' + - '{"type":"future","id":"3113417577108523663600456494916638919964966001158208014797265008275831629467field","value":"{\n program_id: registry.aleo,\n function_name: register,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' + speculate: the execution was accepted + add_next_block: succeeded. +- verified: true + execute: + relay.aleo/check_has_registered: + outputs: + - '{"type":"future","id":"1703350848802287338721207414343167409705599156052884130496399876478780340060field","value":"{\n program_id: relay.aleo,\n function_name: check_has_registered,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: relay.aleo/send: outputs: - - '{"type":"record","id":"2277384653342632398532359071690090462344215994043547853708800775056671259572field","checksum":"3071210942562837171924171313096615835242397071199450951002063969440885822680field","value":"record1qyqspfwaru0f2lj0s2k6p9jfmmkzyvkzl5qpagt00edyuf9qn3gnu5g9qyzxgct5vy3sqqspqrncgctd3wfmz2ggx0v7l5cggxxad49wcmtlyrjnk8fqulmkg3h3rleuqh8nmwn5d9z8cpf6z75sy880xenua6hu9wk6ptzwh9vnzps3l7743a"}' - - '{"type":"future","id":"6015012441862221318333000102440691156905727650418067306609473392233853855381field","value":"{\n program_id: relay.aleo,\n function_name: send,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' + - '{"type":"record","id":"7784769523872898393965408106309655747503106463617903095092460909370003882784field","checksum":"2925477402483393855889468048478541640771723677960433859781919033690325058874field","value":"record1qyqspf6yc43x2jdwg6wshazt7uzuk7etqpez0khvelc6s63uzc827kgsqyzxgct5vy3sqqspqqdyxpuk6dv98fzpe4ssg7lkda8pxg67gxktg62smrlwksgy0a4s6cv957l8wdrsn4r2kqc3d4fppny8jzntf7sc8rn3yyuzctx9wygtww8l7w"}' + - '{"type":"future","id":"3826201585361431846590743971353230409815759916830496075267102612167070324224field","value":"{\n program_id: relay.aleo,\n function_name: send,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: registry.aleo/unregister: outputs: - - '{"type":"future","id":"621057053984946494815874859056940220465065220086041076777338967969133345871field","value":"{\n program_id: registry.aleo,\n function_name: unregister,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' + - '{"type":"future","id":"7725538601531127136662536220663788769690295240695862649177442475416323740861field","value":"{\n program_id: registry.aleo,\n function_name: unregister,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: relay.aleo/send: outputs: - - '{"type":"record","id":"6497977440830787207175874226764101265608813002804421333613230199582364410758field","checksum":"319323911748946858530605909565888788506340329996151513367076865761846915611field","value":"record1qyqsqnajqear5neee3l8fykp4vcq35sgwreyz7hz3png3cn2yyljdscfqyzxgct5vy3sqqspqzu6lezptk9xjpx35xdrv5tztz0v9qs9xx803pyqury2j47x2d5seymhf3xa2wefz7mkas7r7m3uf4kte7fdwm00ral53q2mhclx95qte8mpvc"}' - - '{"type":"future","id":"2216932771373637316148105432054544027092193801977530259105019952220093166242field","value":"{\n program_id: relay.aleo,\n function_name: send,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' + - '{"type":"record","id":"282511750976822837525798970098987139068940238662361142561500666668419713067field","checksum":"2184994739195312494194079865075999113453863903186003085162715556506200707392field","value":"record1qyqspka5axladyfnx3j6m2tk3vt63x7u2mma940kf5wsvh59xdjuv5q3qyzxgct5vy3sqqspqrhwlpkd60jsc3yr5xsqchasz8la83lez4u4j3qlzvp285uz5nzsm7xvxe59u9j5rapncfaglaz8lecu0pz6jtextqlguqcy25lawlgtzmlru0"}' + - '{"type":"future","id":"3122341733121312071339023730127307311054004252496267855252114291543616014967field","value":"{\n program_id: relay.aleo,\n function_name: send,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm\n ]\n}"}' speculate: the execution was rejected add_next_block: succeeded. additional: - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"2373837014611692049497129045871775574464197133932453792739782919776486496194field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1xe2fps8f9xpdas2q0fqy22uraenk84tvvzetrsyxgnwy6445h59s6wv78x,\n 28479u64\n ]\n}"}' + - '{"type":"future","id":"5066847057031924678017880129890545515288601946330211438081820697831246609514field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1xe2fps8f9xpdas2q0fqy22uraenk84tvvzetrsyxgnwy6445h59s6wv78x,\n 12331u64\n ]\n}"}' +- child_outputs: + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"3440391664364771291373877997019861365141059738596076856295449837482536036847field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1xe2fps8f9xpdas2q0fqy22uraenk84tvvzetrsyxgnwy6445h59s6wv78x,\n 12359u64\n ]\n}"}' +- child_outputs: + credits.aleo/fee_public: + outputs: + - '{"type":"future","id":"6067586553805461002652098047959226436380135730552833805752117986651131431751field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1xe2fps8f9xpdas2q0fqy22uraenk84tvvzetrsyxgnwy6445h59s6wv78x,\n 12149u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"6963949699870804211203514659901328830518734684604845622658837353595728006898field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1xe2fps8f9xpdas2q0fqy22uraenk84tvvzetrsyxgnwy6445h59s6wv78x,\n 28507u64\n ]\n}"}' + - '{"type":"future","id":"5190423787375252433831556836413378994143365939958931399671537580774742441501field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm,\n 14542u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"786151097471386478439918490898626420968604200995134718973623517242949574field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm,\n 101210u64\n ]\n}"}' + - '{"type":"future","id":"6012250561080400779848346517044817117765603129638144755490871744716735055256field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1xe2fps8f9xpdas2q0fqy22uraenk84tvvzetrsyxgnwy6445h59s6wv78x,\n 12149u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"7962216909726487379370954492051267200961073450060603523391007597642835489177field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1xe2fps8f9xpdas2q0fqy22uraenk84tvvzetrsyxgnwy6445h59s6wv78x,\n 28479u64\n ]\n}"}' + - '{"type":"future","id":"4078983310461938707355609419119773094714436925171206922865794410810132768408field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1xe2fps8f9xpdas2q0fqy22uraenk84tvvzetrsyxgnwy6445h59s6wv78x,\n 12331u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"5340444358291789813118792762028331134214990505407681376089964565359528622453field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm,\n 101214u64\n ]\n}"}' + - '{"type":"future","id":"4718327215449200025648673668371101175829725629919656989177747688320957470308field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm,\n 14546u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"7708776674386621879381619680665250794376507748822342974632850445134733330595field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1xe2fps8f9xpdas2q0fqy22uraenk84tvvzetrsyxgnwy6445h59s6wv78x,\n 28479u64\n ]\n}"}' + - '{"type":"future","id":"8401929608727184541382889469312440652682460087199782119730570970943355959220field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1xe2fps8f9xpdas2q0fqy22uraenk84tvvzetrsyxgnwy6445h59s6wv78x,\n 12331u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/test_branch.out b/synthesizer/tests/expectations/vm/execute_and_finalize/test_branch.out index 7c414c0ce3..d88f5dd066 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/test_branch.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/test_branch.out @@ -4,33 +4,33 @@ outputs: execute: test_branch.aleo/run_test: outputs: - - '{"type":"future","id":"6853588955800014673009987953241306389090845327747907984198222141108269232573field","value":"{\n program_id: test_branch.aleo,\n function_name: run_test,\n arguments: [\n 1u8,\n 1u8\n ]\n}"}' + - '{"type":"future","id":"3737232062249529150138932693955398881668644103622567558835586062596389824604field","value":"{\n program_id: test_branch.aleo,\n function_name: run_test,\n arguments: [\n 1u8,\n 1u8\n ]\n}"}' speculate: the execution was rejected add_next_block: succeeded. - verified: true execute: test_branch.aleo/run_test: outputs: - - '{"type":"future","id":"7316910653703512796159979382480893246542312648132879967453276886284034879075field","value":"{\n program_id: test_branch.aleo,\n function_name: run_test,\n arguments: [\n 0u8,\n 1u8\n ]\n}"}' + - '{"type":"future","id":"2839212090251948040934158633764862330933299393598341999009181801836696965367field","value":"{\n program_id: test_branch.aleo,\n function_name: run_test,\n arguments: [\n 0u8,\n 1u8\n ]\n}"}' speculate: the execution was rejected add_next_block: succeeded. - verified: true execute: test_branch.aleo/run_test: outputs: - - '{"type":"future","id":"6402417637041760480107523094357167265585878714433227566435547816691472198663field","value":"{\n program_id: test_branch.aleo,\n function_name: run_test,\n arguments: [\n 0u8,\n 0u8\n ]\n}"}' + - '{"type":"future","id":"6861288483994776877281706816951915077787425159195353214277004687152283823579field","value":"{\n program_id: test_branch.aleo,\n function_name: run_test,\n arguments: [\n 0u8,\n 0u8\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. additional: - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"8176559465483810586872674176090912007328770812617215482809916166686904238834field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1x3r205zqql5ywy0cqqt74k0r0htuusn0d037ycxe8ftt9ep8hyzsmqz4dh,\n 17268u64\n ]\n}"}' + - '{"type":"future","id":"380666872983254596471877288883774301967831022825979316512636463061242206552field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1x3r205zqql5ywy0cqqt74k0r0htuusn0d037ycxe8ftt9ep8hyzsmqz4dh,\n 3500u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"885516194992930770292437059317184478627651975125735363573325083543887608918field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1x3r205zqql5ywy0cqqt74k0r0htuusn0d037ycxe8ftt9ep8hyzsmqz4dh,\n 17268u64\n ]\n}"}' + - '{"type":"future","id":"1149597548019710132122321749446181378057338947597516816061468439476407924951field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1x3r205zqql5ywy0cqqt74k0r0htuusn0d037ycxe8ftt9ep8hyzsmqz4dh,\n 3500u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"6884773732489674095657820682011451719106395760464004244662697484163781295818field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1x3r205zqql5ywy0cqqt74k0r0htuusn0d037ycxe8ftt9ep8hyzsmqz4dh,\n 17268u64\n ]\n}"}' + - '{"type":"future","id":"2128802402437912236919291162449765933396168235458827108383886305423871549239field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1x3r205zqql5ywy0cqqt74k0r0htuusn0d037ycxe8ftt9ep8hyzsmqz4dh,\n 3500u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/test_rand.out b/synthesizer/tests/expectations/vm/execute_and_finalize/test_rand.out index 4fefc62cfd..6380117c04 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/test_rand.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/test_rand.out @@ -4,44 +4,44 @@ outputs: execute: test_rand.aleo/rand_chacha_with_literals: outputs: - - '{"type":"future","id":"859791478012828215720348494076914719205244104520150752280307504054509554398field","value":"{\n program_id: test_rand.aleo,\n function_name: rand_chacha_with_literals,\n arguments: [\n 0scalar,\n 0group,\n 0u8,\n 2i16,\n 4u32,\n 7i64,\n 8u128,\n 10field\n ]\n}"}' + - '{"type":"future","id":"3051485481913361775826744416280406419787734940058310766095173488908684408941field","value":"{\n program_id: test_rand.aleo,\n function_name: rand_chacha_with_literals,\n arguments: [\n 0scalar,\n 0group,\n 0u8,\n 2i16,\n 4u32,\n 7i64,\n 8u128,\n 10field\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: test_rand.aleo/rand_chacha_with_struct: outputs: - - '{"type":"future","id":"1067916594854496467910772380664552622025523070198727493475463622599909707249field","value":"{\n program_id: test_rand.aleo,\n function_name: rand_chacha_with_struct,\n arguments: [\n {\n first: 0field,\n second: 0field,\n third: 0field,\n fourth: 0field,\n fifth: 0field\n}\n ]\n}"}' + - '{"type":"future","id":"5324538037254734381263298163254525700334315803949307776069573574643667789515field","value":"{\n program_id: test_rand.aleo,\n function_name: rand_chacha_with_struct,\n arguments: [\n {\n first: 0field,\n second: 0field,\n third: 0field,\n fourth: 0field,\n fifth: 0field\n}\n ]\n}"}' speculate: the execution was accepted add_next_block: succeeded. - verified: true execute: test_rand.aleo/rand_chacha_check: outputs: - - '{"type":"future","id":"3721325135151760660773959530505944451747681933722462808964783147996869797702field","value":"{\n program_id: test_rand.aleo,\n function_name: rand_chacha_check,\n arguments: [\n 0field,\n false\n ]\n}"}' - speculate: the execution was accepted + - '{"type":"future","id":"3094014759641313043901697261267946468626327163450942596641947962222295207390field","value":"{\n program_id: test_rand.aleo,\n function_name: rand_chacha_check,\n arguments: [\n 0field,\n false\n ]\n}"}' + speculate: the execution was rejected add_next_block: succeeded. - verified: true execute: test_rand.aleo/rand_chacha_check: outputs: - - '{"type":"future","id":"887371549615679800380522845098080464570119184210350810479392117984911457950field","value":"{\n program_id: test_rand.aleo,\n function_name: rand_chacha_check,\n arguments: [\n 1field,\n true\n ]\n}"}' - speculate: the execution was accepted + - '{"type":"future","id":"818878742790741579153893179075772445872751227433677932822653185952935999557field","value":"{\n program_id: test_rand.aleo,\n function_name: rand_chacha_check,\n arguments: [\n 1field,\n true\n ]\n}"}' + speculate: the execution was rejected add_next_block: succeeded. additional: - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"6314628133780265670801554258125814886017405269745792760682853845340140460175field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1uchf7kruskpp8thlnfeya9qeklcjss27j6rtu74zz7ch559neqystgslsp,\n 601806u64\n ]\n}"}' + - '{"type":"future","id":"121306501224681157597193186410746475033514025731628517615093553600181539558field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1uchf7kruskpp8thlnfeya9qeklcjss27j6rtu74zz7ch559neqystgslsp,\n 601838u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"3725939744341267737290273038160661629630343114766507174134842826652488781816field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1uchf7kruskpp8thlnfeya9qeklcjss27j6rtu74zz7ch559neqystgslsp,\n 26679u64\n ]\n}"}' + - '{"type":"future","id":"372387797317258515886290332539955510428039667099515014147500070605443070643field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1uchf7kruskpp8thlnfeya9qeklcjss27j6rtu74zz7ch559neqystgslsp,\n 26711u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"5227003534986816857285932061757797688706802206018964764622184983760566708322field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1uchf7kruskpp8thlnfeya9qeklcjss27j6rtu74zz7ch559neqystgslsp,\n 28344u64\n ]\n}"}' + - '{"type":"future","id":"819663813855093908211899344309437376318059680751092090723025520667746540822field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1uchf7kruskpp8thlnfeya9qeklcjss27j6rtu74zz7ch559neqystgslsp,\n 26876u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"5806769723479332130567002952494928256138310337461654699762319212831997850826field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1uchf7kruskpp8thlnfeya9qeklcjss27j6rtu74zz7ch559neqystgslsp,\n 28344u64\n ]\n}"}' + - '{"type":"future","id":"8063948964124424703025348936079361092327181010572643865591831235545568925744field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1uchf7kruskpp8thlnfeya9qeklcjss27j6rtu74zz7ch559neqystgslsp,\n 26876u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/timelock.out b/synthesizer/tests/expectations/vm/execute_and_finalize/timelock.out index 425f80af2e..489e49ae0f 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/timelock.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/timelock.out @@ -4,22 +4,22 @@ outputs: execute: timelock.aleo/lock: outputs: - - '{"type":"future","id":"5726101227699718662507291026879175619949633046158707589853378418659241463316field","value":"{\n program_id: timelock.aleo,\n function_name: lock,\n arguments: []\n}"}' + - '{"type":"future","id":"6658700112390809298568131732578454166620828658145139230021000997557464148749field","value":"{\n program_id: timelock.aleo,\n function_name: lock,\n arguments: []\n}"}' speculate: the execution was rejected add_next_block: succeeded. - verified: true execute: timelock.aleo/lock: outputs: - - '{"type":"future","id":"5825781590715337627504208073275179158827587281138872289977731167576414664969field","value":"{\n program_id: timelock.aleo,\n function_name: lock,\n arguments: []\n}"}' + - '{"type":"future","id":"4552284556317614698302755676987365520737661551926416127102861613249304034947field","value":"{\n program_id: timelock.aleo,\n function_name: lock,\n arguments: []\n}"}' speculate: the execution was rejected add_next_block: succeeded. additional: - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"2868527388214006275127069563021857572887489216649877337285946162120321568912field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo12tksdptp7hvxly8tkm3um08fvf53qpehsgdgqfvy9pe3sewcq5ysjg5myy,\n 5164u64\n ]\n}"}' + - '{"type":"future","id":"8348146946615998276874385214136272238568613488992445452960641768056647996497field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo12tksdptp7hvxly8tkm3um08fvf53qpehsgdgqfvy9pe3sewcq5ysjg5myy,\n 2196u64\n ]\n}"}' - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"3666380379303443004933801395245329857516145915761366182794264005536589963556field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo12tksdptp7hvxly8tkm3um08fvf53qpehsgdgqfvy9pe3sewcq5ysjg5myy,\n 5164u64\n ]\n}"}' + - '{"type":"future","id":"982556877652028784867244374145661434115160127655345369458709244869192972372field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo12tksdptp7hvxly8tkm3um08fvf53qpehsgdgqfvy9pe3sewcq5ysjg5myy,\n 2196u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/unawaited_future_fail.out b/synthesizer/tests/expectations/vm/execute_and_finalize/unawaited_future_fail.out deleted file mode 100644 index 7d4109cee6..0000000000 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/unawaited_future_fail.out +++ /dev/null @@ -1,3 +0,0 @@ -errors: -- 'Failed to run `VM::deploy for program parent.aleo: Futures in finalize ''foo'' are not awaited in the order they are passed in.' -outputs: [] diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/unused_future_fail.out b/synthesizer/tests/expectations/vm/execute_and_finalize/unused_future_fail.out deleted file mode 100644 index 0cea7546f1..0000000000 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/unused_future_fail.out +++ /dev/null @@ -1,3 +0,0 @@ -errors: -- 'Failed to run `VM::deploy for program parent.aleo: Function ''foo'' contains futures, but the ''async'' instruction does not consume all of them in the order they were produced' -outputs: [] diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/unused_position.out b/synthesizer/tests/expectations/vm/execute_and_finalize/unused_position.out index c5e300b026..b1bed94843 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/unused_position.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/unused_position.out @@ -4,11 +4,11 @@ outputs: execute: unused_position.aleo/foo: outputs: - - '{"type":"future","id":"4435915382452600913825742955271157728527943603774006701552876898718102875463field","value":"{\n program_id: unused_position.aleo,\n function_name: foo,\n arguments: []\n}"}' + - '{"type":"future","id":"1790580141778087233710017444717735846711836561595379002028367169462349892136field","value":"{\n program_id: unused_position.aleo,\n function_name: foo,\n arguments: []\n}"}' speculate: the execution was accepted add_next_block: succeeded. additional: - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"5889749875317192883762347751185109427367185401929794748301981981444845203330field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo12tksdptp7hvxly8tkm3um08fvf53qpehsgdgqfvy9pe3sewcq5ysjg5myy,\n 2176u64\n ]\n}"}' + - '{"type":"future","id":"5672533630623788440632164866520422788597095754178549239294815812922538158034field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo12tksdptp7hvxly8tkm3um08fvf53qpehsgdgqfvy9pe3sewcq5ysjg5myy,\n 1308u64\n ]\n}"}' diff --git a/synthesizer/tests/expectations/vm/execute_and_finalize/user_callable.out b/synthesizer/tests/expectations/vm/execute_and_finalize/user_callable.out index 85f3df23fb..8bd4f802b0 100644 --- a/synthesizer/tests/expectations/vm/execute_and_finalize/user_callable.out +++ b/synthesizer/tests/expectations/vm/execute_and_finalize/user_callable.out @@ -4,8 +4,8 @@ outputs: execute: child.aleo/foo: outputs: - - '{"type":"public","id":"3583507900097573902692207210661581535840809808651900827750728854102720512424field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' - - '{"type":"public","id":"476166291720572191849579987891810720100233870490756615272004665719966045283field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' + - '{"type":"public","id":"990518176319329300540260363339673789976107460730294067348711019503474061851field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' + - '{"type":"public","id":"7571316186508319878827016469809649549608056961397657756993177747855651462866field","value":"aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx"}' speculate: the execution was accepted add_next_block: succeeded. - execute: 'Failed to evaluate instruction (call child.aleo/foo into r0 r1;): Failed to evaluate instruction (assert.eq self.caller self.signer ;): ''assert.eq'' failed: ''aleo16w8t56s7v6ud7vu33fr388ph0dq0c7yhp597cyjt88rr3nultcyqcyk9yy'' is not equal to ''aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx'' (should be equal)' @@ -13,5 +13,5 @@ additional: - child_outputs: credits.aleo/fee_public: outputs: - - '{"type":"future","id":"5245767978479482276373144091068362056657622227760198296183689243703275814117field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx,\n 1244u64\n ]\n}"}' + - '{"type":"future","id":"5082208301651373176623590811075106181267408732555436878022129644210755250685field","value":"{\n program_id: credits.aleo,\n function_name: fee_public,\n arguments: [\n aleo1qr2ha4pfs5l28aze88yn6fhleeythklkczrule2v838uwj65n5gqxt9djx,\n 1276u64\n ]\n}"}' - {} diff --git a/synthesizer/tests/test_command_parse.rs b/synthesizer/tests/test_command_parse.rs index f8402b0061..d6cbd0e112 100644 --- a/synthesizer/tests/test_command_parse.rs +++ b/synthesizer/tests/test_command_parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/tests/test_instruction_parse.rs b/synthesizer/tests/test_instruction_parse.rs index 2c4f8ff58f..116967c607 100644 --- a/synthesizer/tests/test_instruction_parse.rs +++ b/synthesizer/tests/test_instruction_parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/tests/test_process_execute.rs b/synthesizer/tests/test_process_execute.rs index d57b5b91cf..8d63e707fd 100644 --- a/synthesizer/tests/test_process_execute.rs +++ b/synthesizer/tests/test_process_execute.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -58,7 +59,7 @@ fn run_test(process: Process, test: &ProgramTest) -> serde_yaml: for program in test.programs() { if let Err(err) = process.add_program(program) { output - .get_mut(&serde_yaml::Value::String("errors".to_string())) + .get_mut(serde_yaml::Value::String("errors".to_string())) .unwrap() .as_sequence_mut() .unwrap() diff --git a/synthesizer/tests/test_program_parse.rs b/synthesizer/tests/test_program_parse.rs index 17c06e272b..c51a6ecaeb 100644 --- a/synthesizer/tests/test_program_parse.rs +++ b/synthesizer/tests/test_program_parse.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/tests/test_vm_execute_and_finalize.rs b/synthesizer/tests/test_vm_execute_and_finalize.rs index 21a5b4e234..c15e42c4db 100644 --- a/synthesizer/tests/test_vm_execute_and_finalize.rs +++ b/synthesizer/tests/test_vm_execute_and_finalize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -17,7 +18,7 @@ mod utilities; use console::{ account::{PrivateKey, ViewKey}, network::prelude::*, - program::{Entry, Identifier, Literal, Plaintext, ProgramID, Record, Value, U64}, + program::{Entry, Identifier, Literal, Plaintext, ProgramID, Record, U64, Value}, types::{Boolean, Field}, }; use ledger_block::{ @@ -30,15 +31,14 @@ use ledger_block::{ Transactions, Transition, }; -use ledger_store::{helpers::memory::ConsensusMemory, ConsensusStorage, ConsensusStore}; -use snarkvm_synthesizer::{program::FinalizeOperation, VM}; +use ledger_store::{ConsensusStorage, ConsensusStore, helpers::memory::ConsensusMemory}; +use snarkvm_synthesizer::{VM, program::FinalizeOperation}; use synthesizer_program::FinalizeGlobalState; use anyhow::Result; use console::account::Address; use indexmap::IndexMap; use rayon::prelude::*; -use std::borrow::Borrow; use utilities::*; #[test] @@ -90,12 +90,23 @@ fn run_test(test: &ProgramTest) -> serde_yaml::Mapping { rng, ) .unwrap(); - let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = - vm.speculate(construct_finalize_global_state(&vm), Some(0u64), vec![], None, [transaction].iter()).unwrap(); + let time_since_last_block = CurrentNetwork::BLOCK_TIME as i64; + let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = vm + .speculate( + construct_finalize_global_state(&vm), + time_since_last_block, + Some(0u64), + vec![], + &None.into(), + [transaction].iter(), + rng, + ) + .unwrap(); assert!(aborted_transaction_ids.is_empty()); let block = construct_next_block( &vm, + time_since_last_block, &genesis_private_key, ratifications, transactions, @@ -126,12 +137,23 @@ fn run_test(test: &ProgramTest) -> serde_yaml::Mapping { } }; - let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = - vm.speculate(construct_finalize_global_state(&vm), Some(0u64), vec![], None, [transaction].iter()).unwrap(); + let time_since_last_block = CurrentNetwork::BLOCK_TIME as i64; + let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = vm + .speculate( + construct_finalize_global_state(&vm), + time_since_last_block, + Some(0u64), + vec![], + &None.into(), + [transaction].iter(), + rng, + ) + .unwrap(); assert!(aborted_transaction_ids.is_empty()); let block = construct_next_block( &vm, + time_since_last_block, &genesis_private_key, ratifications, transactions, @@ -264,9 +286,17 @@ fn run_test(test: &ProgramTest) -> serde_yaml::Mapping { ); // Speculate on the ratifications, solutions, and transaction. + let time_since_last_block = CurrentNetwork::BLOCK_TIME as i64; let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = match vm - .speculate(construct_finalize_global_state(&vm), Some(0u64), vec![], None, [transaction].iter()) - { + .speculate( + construct_finalize_global_state(&vm), + time_since_last_block, + Some(0u64), + vec![], + &None.into(), + [transaction].iter(), + rng, + ) { Ok((ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations)) => { result.insert( serde_yaml::Value::String("speculate".to_string()), @@ -296,6 +326,7 @@ fn run_test(test: &ProgramTest) -> serde_yaml::Mapping { // Construct the next block. let block = construct_next_block( &vm, + time_since_last_block, &private_key, ratifications, transactions, @@ -400,13 +431,24 @@ fn construct_fee_records, R: Rng + CryptoRng } } - let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = - vm.speculate(construct_finalize_global_state(vm), Some(0u64), vec![], None, transactions.iter()).unwrap(); + let time_since_last_block = CurrentNetwork::BLOCK_TIME as i64; + let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = vm + .speculate( + construct_finalize_global_state(vm), + time_since_last_block, + Some(0u64), + vec![], + &None.into(), + transactions.iter(), + rng, + ) + .unwrap(); assert!(aborted_transaction_ids.is_empty()); // Create a block for the fee transactions and add them to the VM. let block = construct_next_block( vm, + time_since_last_block, private_key, ratifications, transactions, @@ -424,8 +466,10 @@ fn construct_fee_records, R: Rng + CryptoRng } // A helper function to construct the next block. +#[allow(clippy::too_many_arguments)] fn construct_next_block, R: Rng + CryptoRng>( vm: &VM, + time_since_last_block: i64, private_key: &PrivateKey, ratifications: Ratifications, transactions: Transactions, @@ -434,8 +478,7 @@ fn construct_next_block, R: Rng + CryptoRng> rng: &mut R, ) -> Result> { // Get the most recent block. - let block_hash = - vm.block_store().get_block_hash(*vm.block_store().heights().max().unwrap().borrow()).unwrap().unwrap(); + let block_hash = vm.block_store().get_block_hash(vm.block_store().max_height().unwrap()).unwrap().unwrap(); let previous_block = vm.block_store().get_block(&block_hash).unwrap().unwrap(); // Construct the metadata associated with the block. @@ -449,7 +492,7 @@ fn construct_next_block, R: Rng + CryptoRng> CurrentNetwork::GENESIS_PROOF_TARGET, previous_block.last_coinbase_target(), previous_block.last_coinbase_timestamp(), - CurrentNetwork::GENESIS_TIMESTAMP + 1, + previous_block.timestamp().saturating_add(time_since_last_block), )?; // Construct the block header. let header = Header::from( @@ -468,7 +511,8 @@ fn construct_next_block, R: Rng + CryptoRng> previous_block.hash(), header, ratifications, - None, + None.into(), + vec![], transactions, aborted_transaction_ids, rng, @@ -499,7 +543,7 @@ fn construct_finalize_global_state>( vm: &VM, ) -> FinalizeGlobalState { // Retrieve the latest block. - let block_height = *vm.block_store().heights().max().unwrap().clone(); + let block_height = vm.block_store().max_height().unwrap(); let latest_block_hash = vm.block_store().get_block_hash(block_height).unwrap().unwrap(); let latest_block = vm.block_store().get_block(&latest_block_hash).unwrap().unwrap(); // Retrieve the latest round. diff --git a/synthesizer/tests/tests/parser/instruction/instruction_pass.aleo b/synthesizer/tests/tests/parser/instruction/instruction_pass.aleo index f5d2aafa1e..f0df1195e9 100644 --- a/synthesizer/tests/tests/parser/instruction/instruction_pass.aleo +++ b/synthesizer/tests/tests/parser/instruction/instruction_pass.aleo @@ -7,6 +7,7 @@ and r0 r1 into r2; assert.eq r0 r1; assert.neq r0 r1; assert.eq block.height block.height; +assert.eq network.id network.id; call foo; call foo r0; call foo r0 into r1; diff --git a/synthesizer/tests/tests/parser/instruction/operand_pass.aleo b/synthesizer/tests/tests/parser/instruction/operand_pass.aleo index 4009a2eb87..14c0ff455e 100644 --- a/synthesizer/tests/tests/parser/instruction/operand_pass.aleo +++ b/synthesizer/tests/tests/parser/instruction/operand_pass.aleo @@ -1,5 +1,6 @@ assert.eq self.caller self.caller; assert.eq block.height block.height; +assert.eq network.id network.id; assert.eq r88 r101; assert.eq hello.aleo goodbye.aleo; assert.eq aleo1dg722m22fzpz6xjdrvl9tzu5t68zmypj5p74khlqcac0gvednygqxaax0j aleo1dg722m22fzpz6xjdrvl9tzu5t68zmypj5p74khlqcac0gvednygqxaax0j; diff --git a/synthesizer/tests/tests/process/execute/lossy_casts.aleo b/synthesizer/tests/tests/process/execute/lossy_casts.aleo new file mode 100644 index 0000000000..6513c1bb00 --- /dev/null +++ b/synthesizer/tests/tests/process/execute/lossy_casts.aleo @@ -0,0 +1,50 @@ +/* +randomness: 902384 +cases: + - program: lossy_casts.aleo + function: test_lossy_cast + inputs: [79363714989903307245735717098563574705733591463163614225748337416674727625843187853442697973404985688481508350822field] + - program: lossy_casts.aleo + function: test_lossy_cast + inputs: [0field] + - program: lossy_casts.aleo + function: test_lossy_cast + inputs: [1field] + - program: lossy_casts.aleo + function: test_lossy_cast + inputs: [340_282_366_920_938_463_463_374_607_431_768_211_456field] + - program: lossy_casts.aleo + function: test_lossy_cast + inputs: [340_282_366_920_938_463_463_374_607_431_768_211_457field] + + +*/ + +program lossy_casts.aleo; + +function test_lossy_cast: + input r0 as field.private; + cast.lossy r0 into r1 as u128; + cast.lossy r0 into r2 as i128; + cast.lossy r0 into r3 as u64; + cast.lossy r0 into r4 as i64; + cast.lossy r0 into r5 as u32; + cast.lossy r0 into r6 as i32; + cast.lossy r0 into r7 as u16; + cast.lossy r0 into r8 as i16; + cast.lossy r0 into r9 as u8; + cast.lossy r0 into r10 as i8; + cast.lossy r0 into r11 as boolean; + cast.lossy r0 into r12 as group; + output r1 as u128.private; + output r2 as i128.private; + output r3 as u64.private; + output r4 as i64.private; + output r5 as u32.private; + output r6 as i32.private; + output r7 as u16.private; + output r8 as i16.private; + output r9 as u8.private; + output r10 as i8.private; + output r11 as boolean.private; + output r12 as group.private; diff --git a/synthesizer/tests/tests/vm/execute_and_finalize/branch_with_future.aleo b/synthesizer/tests/tests/vm/execute_and_finalize/branch_with_future.aleo new file mode 100644 index 0000000000..927e4b0db3 --- /dev/null +++ b/synthesizer/tests/tests/vm/execute_and_finalize/branch_with_future.aleo @@ -0,0 +1,89 @@ +/* +randomness: 95043801 +cases: + - program: branch_with_future.aleo + function: bar + inputs: [] + - program: branch_with_future.aleo + function: baz + inputs: [true, true] + - program: branch_with_future.aleo + function: baz + inputs: [true, false] + - program: branch_with_future.aleo + function: baz + inputs: [false, true] + - program: branch_with_future.aleo + function: baz + inputs: [false, false] + - program: branch_with_future.aleo + function: qux + inputs: [] +*/ + +program child.aleo; + +function foo: + input r0 as boolean.public; + input r1 as boolean.public; + async foo r0 r1 into r2; + output r2 as child.aleo/foo.future; + +finalize foo: + input r0 as boolean.public; + input r1 as boolean.public; + assert.eq r0 r1; + + +///////////////////////////////////////////////// + +import child.aleo; + +program branch_with_future.aleo; + +function bar: + call child.aleo/foo true false into r0; + async bar r0 into r1; + output r1 as branch_with_future.aleo/bar.future; + +finalize bar: + input r0 as child.aleo/foo.future; + branch.eq true true to exit; + await r0; + position exit; + +function baz: + input r0 as boolean.public; + input r1 as boolean.public; + call child.aleo/foo true true into r2; + call child.aleo/foo true true into r3; + async baz r0 r1 r2 r3 into r4; + output r4 as branch_with_future.aleo/baz.future; + +finalize baz: + input r0 as boolean.public; + input r1 as boolean.public; + input r2 as child.aleo/foo.future; + input r3 as child.aleo/foo.future; + branch.eq r0 false to skip1; + await r2; + branch.eq true true to next; + position skip1; + await r3; + position next; + branch.eq r1 false to skip2; + await r3; + branch.eq true true to end; + position skip2; + await r2; + position end; + +function qux: + call child.aleo/foo true true into r0; + async qux r0 into r1; + output r1 as branch_with_future.aleo/qux.future; + +finalize qux: + input r0 as child.aleo/foo.future; + await r0; + await r0; diff --git a/synthesizer/tests/tests/vm/execute_and_finalize/future_not_all_awaited_fail.aleo b/synthesizer/tests/tests/vm/execute_and_finalize/future_not_all_awaited_fail.aleo new file mode 100644 index 0000000000..21f282a4d7 --- /dev/null +++ b/synthesizer/tests/tests/vm/execute_and_finalize/future_not_all_awaited_fail.aleo @@ -0,0 +1,60 @@ +/* +randomness: 45791624 +cases: [] +*/ + +program child.aleo; + +mapping count: + key as address.public; + value as field.public; + +function foo: + async foo self.caller into r0; + output r0 as child.aleo/foo.future; + +finalize foo: + input r0 as address.public; + get.or_use count[r0] 0field into r1; + add r1 1field into r2; + set r2 into count[r0]; + +function boo: + async boo self.caller into r0; + output r0 as child.aleo/boo.future; + +finalize boo: + input r0 as address.public; + get.or_use count[r0] 0field into r1; + add r1 1field into r2; + set r2 into count[r0]; + +///////////////////////////////////////////////// + +import child.aleo; + +program parent.aleo; + +function foo: + call child.aleo/foo into r0; + call child.aleo/foo into r1; + call child.aleo/foo into r2; + call child.aleo/boo into r3; + call child.aleo/boo into r4; + call child.aleo/boo into r5; + async foo r5 r4 r1 r0 r2 r3 into r6; + output r6 as parent.aleo/foo.future; + +finalize foo: + input r0 as child.aleo/boo.future; + input r1 as child.aleo/boo.future; + input r2 as child.aleo/foo.future; + input r3 as child.aleo/foo.future; + input r4 as child.aleo/foo.future; + input r5 as child.aleo/boo.future; + await r4; + await r1; + await r2; + await r0; + await r5; + diff --git a/synthesizer/tests/tests/vm/execute_and_finalize/future_not_all_passed_to_async_call_fail.aleo b/synthesizer/tests/tests/vm/execute_and_finalize/future_not_all_passed_to_async_call_fail.aleo new file mode 100644 index 0000000000..a6b168e07c --- /dev/null +++ b/synthesizer/tests/tests/vm/execute_and_finalize/future_not_all_passed_to_async_call_fail.aleo @@ -0,0 +1,59 @@ +/* +randomness: 45791624 +cases: [] +*/ + +program child.aleo; + +mapping count: + key as address.public; + value as field.public; + +function foo: + async foo self.caller into r0; + output r0 as child.aleo/foo.future; + +finalize foo: + input r0 as address.public; + get.or_use count[r0] 0field into r1; + add r1 1field into r2; + set r2 into count[r0]; + +function boo: + async boo self.caller into r0; + output r0 as child.aleo/boo.future; + +finalize boo: + input r0 as address.public; + get.or_use count[r0] 0field into r1; + add r1 1field into r2; + set r2 into count[r0]; + +///////////////////////////////////////////////// + +import child.aleo; + +program parent.aleo; + +function foo: + call child.aleo/foo into r0; + call child.aleo/foo into r1; + call child.aleo/foo into r2; + call child.aleo/boo into r3; + call child.aleo/boo into r4; + call child.aleo/boo into r5; + async foo r5 r4 r1 r0 r2 into r6; + output r6 as parent.aleo/foo.future; + +finalize foo: + input r0 as child.aleo/boo.future; + input r1 as child.aleo/boo.future; + input r2 as child.aleo/foo.future; + input r3 as child.aleo/foo.future; + input r4 as child.aleo/foo.future; + await r4; + await r1; + await r3; + await r2; + await r0; + diff --git a/synthesizer/tests/tests/vm/execute_and_finalize/future_out_of_order.aleo b/synthesizer/tests/tests/vm/execute_and_finalize/future_out_of_order.aleo new file mode 100644 index 0000000000..fa23c85051 --- /dev/null +++ b/synthesizer/tests/tests/vm/execute_and_finalize/future_out_of_order.aleo @@ -0,0 +1,64 @@ +/* +randomness: 45791624 +cases: + - program: parent.aleo + function: foo + inputs: [] +*/ + +program child.aleo; + +mapping count: + key as address.public; + value as field.public; + +function foo: + async foo self.caller into r0; + output r0 as child.aleo/foo.future; + +finalize foo: + input r0 as address.public; + get.or_use count[r0] 0field into r1; + add r1 1field into r2; + set r2 into count[r0]; + +function boo: + async boo self.caller into r0; + output r0 as child.aleo/boo.future; + +finalize boo: + input r0 as address.public; + get.or_use count[r0] 0field into r1; + add r1 1field into r2; + set r2 into count[r0]; + +///////////////////////////////////////////////// + +import child.aleo; + +program parent.aleo; + +function foo: + call child.aleo/foo into r0; + call child.aleo/foo into r1; + call child.aleo/foo into r2; + call child.aleo/boo into r3; + call child.aleo/boo into r4; + call child.aleo/boo into r5; + async foo r5 r4 r1 r0 r2 r3 into r6; + output r6 as parent.aleo/foo.future; + +finalize foo: + input r0 as child.aleo/boo.future; + input r1 as child.aleo/boo.future; + input r2 as child.aleo/foo.future; + input r3 as child.aleo/foo.future; + input r4 as child.aleo/foo.future; + input r5 as child.aleo/boo.future; + await r4; + await r1; + await r3; + await r2; + await r0; + await r5; + diff --git a/synthesizer/tests/tests/vm/execute_and_finalize/future_out_of_order_fail.aleo b/synthesizer/tests/tests/vm/execute_and_finalize/future_out_of_order_fail.aleo deleted file mode 100644 index f2b6225a55..0000000000 --- a/synthesizer/tests/tests/vm/execute_and_finalize/future_out_of_order_fail.aleo +++ /dev/null @@ -1,39 +0,0 @@ -/* -randomness: 45791624 -cases: [] -*/ - -program child.aleo; - -mapping count: - key as address.public; - value as field.public; - -function foo: - async foo self.caller into r0; - output r0 as child.aleo/foo.future; - -finalize foo: - input r0 as address.public; - get.or_use count[r0] 0field into r1; - add r1 1field into r2; - set r2 into count[r0]; - -///////////////////////////////////////////////// - -import child.aleo; - -program parent.aleo; - -function foo: - call child.aleo/foo into r0; - call child.aleo/foo into r1; - async foo r1 r0 into r2; - output r2 as parent.aleo/foo.future; - -finalize foo: - input r0 as child.aleo/foo.future; - input r1 as child.aleo/foo.future; - await r0; - await r1; - diff --git a/synthesizer/tests/tests/vm/execute_and_finalize/many_input_and_output.aleo b/synthesizer/tests/tests/vm/execute_and_finalize/many_input_and_output.aleo new file mode 100644 index 0000000000..94f680ded5 --- /dev/null +++ b/synthesizer/tests/tests/vm/execute_and_finalize/many_input_and_output.aleo @@ -0,0 +1,226 @@ +/* +randomness: 12345 +cases: + - program: gas_dos.aleo + function: make_trash_empty + inputs: [] + - program: gas_dos.aleo + function: make_trash + inputs: [0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8] + - program: gas_dos.aleo + function: make_trash_private + inputs: [0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8] + - program: gas_dos.aleo + function: make_trash_u64 + inputs: [0u64, 1u64, 2u64, 3u64, 4u64, 5u64, 6u64, 7u64, 8u64, 9u64, 10u64, 11u64, 12u64, 13u64, 14u64, 15u64] + - program: gas_dos.aleo + function: make_trash_call_inner + inputs: [] + - program: gas_dos.aleo + function: make_trash_call_inner_private + inputs: [] +*/ + + +program child.aleo; + +function inner_trash_single: + input r0 as u8.public; + output r0 as u8.public; + +function inner_trash: + input r0 as u8.public; + input r1 as u8.public; + input r2 as u8.public; + input r3 as u8.public; + input r4 as u8.public; + input r5 as u8.public; + input r6 as u8.public; + input r7 as u8.public; + input r8 as u8.public; + input r9 as u8.public; + input r10 as u8.public; + input r11 as u8.public; + input r12 as u8.public; + input r13 as u8.public; + input r14 as u8.public; + input r15 as u8.public; + + output r0 as u8.public; + output r1 as u8.public; + output r2 as u8.public; + output r3 as u8.public; + output r4 as u8.public; + output r5 as u8.public; + output r6 as u8.public; + output r7 as u8.public; + output r8 as u8.public; + output r9 as u8.public; + output r10 as u8.public; + output r11 as u8.public; + output r12 as u8.public; + output r13 as u8.public; + output r14 as u8.public; + output r15 as u8.public; + +function inner_trash_private: + input r0 as u8.private; + input r1 as u8.private; + input r2 as u8.private; + input r3 as u8.private; + input r4 as u8.private; + input r5 as u8.private; + input r6 as u8.private; + input r7 as u8.private; + input r8 as u8.private; + input r9 as u8.private; + input r10 as u8.private; + input r11 as u8.private; + input r12 as u8.private; + input r13 as u8.private; + input r14 as u8.private; + input r15 as u8.private; + + output r0 as u8.private; + output r1 as u8.private; + output r2 as u8.private; + output r3 as u8.private; + output r4 as u8.private; + output r5 as u8.private; + output r6 as u8.private; + output r7 as u8.private; + output r8 as u8.private; + output r9 as u8.private; + output r10 as u8.private; + output r11 as u8.private; + output r12 as u8.private; + output r13 as u8.private; + output r14 as u8.private; + output r15 as u8.private; + + +///////////////////////////////////////////////// + +import child.aleo; + +program gas_dos.aleo; + +function make_trash_empty: + +function make_trash: + input r0 as u8.public; + input r1 as u8.public; + input r2 as u8.public; + input r3 as u8.public; + input r4 as u8.public; + input r5 as u8.public; + input r6 as u8.public; + input r7 as u8.public; + input r8 as u8.public; + input r9 as u8.public; + input r10 as u8.public; + input r11 as u8.public; + input r12 as u8.public; + input r13 as u8.public; + input r14 as u8.public; + input r15 as u8.public; + + output r0 as u8.public; + output r1 as u8.public; + output r2 as u8.public; + output r3 as u8.public; + output r4 as u8.public; + output r5 as u8.public; + output r6 as u8.public; + output r7 as u8.public; + output r8 as u8.public; + output r9 as u8.public; + output r10 as u8.public; + output r11 as u8.public; + output r12 as u8.public; + output r13 as u8.public; + output r14 as u8.public; + output r15 as u8.public; + +function make_trash_private: + input r0 as u8.private; + input r1 as u8.private; + input r2 as u8.private; + input r3 as u8.private; + input r4 as u8.private; + input r5 as u8.private; + input r6 as u8.private; + input r7 as u8.private; + input r8 as u8.private; + input r9 as u8.private; + input r10 as u8.private; + input r11 as u8.private; + input r12 as u8.private; + input r13 as u8.private; + input r14 as u8.private; + input r15 as u8.private; + + output r0 as u8.private; + output r1 as u8.private; + output r2 as u8.private; + output r3 as u8.private; + output r4 as u8.private; + output r5 as u8.private; + output r6 as u8.private; + output r7 as u8.private; + output r8 as u8.private; + output r9 as u8.private; + output r10 as u8.private; + output r11 as u8.private; + output r12 as u8.private; + output r13 as u8.private; + output r14 as u8.private; + output r15 as u8.private; + + +function make_trash_u64: + input r0 as u64.public; + input r1 as u64.public; + input r2 as u64.public; + input r3 as u64.public; + input r4 as u64.public; + input r5 as u64.public; + input r6 as u64.public; + input r7 as u64.public; + input r8 as u64.public; + input r9 as u64.public; + input r10 as u64.public; + input r11 as u64.public; + input r12 as u64.public; + input r13 as u64.public; + input r14 as u64.public; + input r15 as u64.public; + + output r0 as u64.public; + output r1 as u64.public; + output r2 as u64.public; + output r3 as u64.public; + output r4 as u64.public; + output r5 as u64.public; + output r6 as u64.public; + output r7 as u64.public; + output r8 as u64.public; + output r9 as u64.public; + output r10 as u64.public; + output r11 as u64.public; + output r12 as u64.public; + output r13 as u64.public; + output r14 as u64.public; + output r15 as u64.public; + +function make_trash_call_inner: + call child.aleo/inner_trash 0u8 1u8 2u8 3u8 4u8 5u8 6u8 7u8 8u8 9u8 10u8 11u8 12u8 13u8 14u8 15u8 into r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15; + call child.aleo/inner_trash 0u8 1u8 2u8 3u8 4u8 5u8 6u8 7u8 8u8 9u8 10u8 11u8 12u8 13u8 14u8 15u8 into r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31; + call child.aleo/inner_trash 0u8 1u8 2u8 3u8 4u8 5u8 6u8 7u8 8u8 9u8 10u8 11u8 12u8 13u8 14u8 15u8 into r32 r33 r34 r35 r36 r37 r38 r39 r40 r41 r42 r43 r44 r45 r46 r47; + call child.aleo/inner_trash 0u8 1u8 2u8 3u8 4u8 5u8 6u8 7u8 8u8 9u8 10u8 11u8 12u8 13u8 14u8 15u8 into r48 r49 r50 r51 r52 r53 r54 r55 r56 r57 r58 r59 r60 r61 r62 r63; + +function make_trash_call_inner_private: + call child.aleo/inner_trash_private 0u8 1u8 2u8 3u8 4u8 5u8 6u8 7u8 8u8 9u8 10u8 11u8 12u8 13u8 14u8 15u8 into r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15; + call child.aleo/inner_trash_private 0u8 1u8 2u8 3u8 4u8 5u8 6u8 7u8 8u8 9u8 10u8 11u8 12u8 13u8 14u8 15u8 into r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31; + call child.aleo/inner_trash_private 0u8 1u8 2u8 3u8 4u8 5u8 6u8 7u8 8u8 9u8 10u8 11u8 12u8 13u8 14u8 15u8 into r32 r33 r34 r35 r36 r37 r38 r39 r40 r41 r42 r43 r44 r45 r46 r47; + call child.aleo/inner_trash_private 0u8 1u8 2u8 3u8 4u8 5u8 6u8 7u8 8u8 9u8 10u8 11u8 12u8 13u8 14u8 15u8 into r48 r49 r50 r51 r52 r53 r54 r55 r56 r57 r58 r59 r60 r61 r62 r63; diff --git a/synthesizer/tests/tests/vm/execute_and_finalize/out_of_order_await_fail.aleo b/synthesizer/tests/tests/vm/execute_and_finalize/out_of_order_await_fail.aleo deleted file mode 100644 index b86f29b8b5..0000000000 --- a/synthesizer/tests/tests/vm/execute_and_finalize/out_of_order_await_fail.aleo +++ /dev/null @@ -1,39 +0,0 @@ -/* -randomness: 45791624 -cases: [] -*/ - -program child.aleo; - -mapping count: - key as address.public; - value as field.public; - -function foo: - async foo self.caller into r0; - output r0 as child.aleo/foo.future; - -finalize foo: - input r0 as address.public; - get.or_use count[r0] 0field into r1; - add r1 1field into r2; - set r2 into count[r0]; - -///////////////////////////////////////////////// - -import child.aleo; - -program parent.aleo; - -function foo: - call child.aleo/foo into r0; - call child.aleo/foo into r1; - async foo r0 r1 into r2; - output r2 as parent.aleo/foo.future; - -finalize foo: - input r0 as child.aleo/foo.future; - input r1 as child.aleo/foo.future; - await r1; - await r0; - diff --git a/synthesizer/tests/tests/vm/execute_and_finalize/read_external_mapping.aleo b/synthesizer/tests/tests/vm/execute_and_finalize/read_external_mapping.aleo index 20ad427064..0dfdf9e79f 100644 --- a/synthesizer/tests/tests/vm/execute_and_finalize/read_external_mapping.aleo +++ b/synthesizer/tests/tests/vm/execute_and_finalize/read_external_mapping.aleo @@ -9,10 +9,16 @@ cases: - program: relay.aleo function: send_without_check inputs: [aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm, 0u8] + - program: relay.aleo + function: check_has_registered + inputs: [aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm] - program: registry.aleo function: register inputs: [] private_key: APrivateKey1zkpABon5degxuW8JnBniSXgN1C4eAGKfDH8qRPZe1geHpWp + - program: relay.aleo + function: check_has_registered + inputs: [aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm] - program: relay.aleo function: send inputs: [aleo1f6eg623knp66cwx0926w3plgdgzcmfpgyrzgnjz90mucgs3z7s9qls4upm, 1u8] @@ -57,6 +63,16 @@ record message: owner as address.private; data as u8.private; +function check_has_registered: + input r0 as address.public; + async check_has_registered r0 into r1; + output r1 as relay.aleo/check_has_registered.future; + +finalize check_has_registered: + input r0 as address.public; + contains registry.aleo/users[r0] into r1; + assert.eq r1 true; + function send: input r0 as address.public; input r1 as u8.public; diff --git a/synthesizer/tests/tests/vm/execute_and_finalize/unawaited_future_fail.aleo b/synthesizer/tests/tests/vm/execute_and_finalize/unawaited_future_fail.aleo deleted file mode 100644 index 26736dca73..0000000000 --- a/synthesizer/tests/tests/vm/execute_and_finalize/unawaited_future_fail.aleo +++ /dev/null @@ -1,38 +0,0 @@ -/* -randomness: 45791624 -cases: [] -*/ - -program child.aleo; - -mapping count: - key as address.public; - value as field.public; - -function foo: - async foo self.caller into r0; - output r0 as child.aleo/foo.future; - -finalize foo: - input r0 as address.public; - get.or_use count[r0] 0field into r1; - add r1 1field into r2; - set r2 into count[r0]; - -///////////////////////////////////////////////// - -import child.aleo; - -program parent.aleo; - -function foo: - call child.aleo/foo into r0; - call child.aleo/foo into r1; - async foo r0 r1 into r2; - output r2 as parent.aleo/foo.future; - -finalize foo: - input r0 as child.aleo/foo.future; - input r1 as child.aleo/foo.future; - await r0; - diff --git a/synthesizer/tests/tests/vm/execute_and_finalize/unused_future_fail.aleo b/synthesizer/tests/tests/vm/execute_and_finalize/unused_future_fail.aleo deleted file mode 100644 index 9277b9a3dd..0000000000 --- a/synthesizer/tests/tests/vm/execute_and_finalize/unused_future_fail.aleo +++ /dev/null @@ -1,37 +0,0 @@ -/* -randomness: 45791624 -cases: [] -*/ - -program child.aleo; - -mapping count: - key as address.public; - value as field.public; - -function foo: - async foo self.caller into r0; - output r0 as child.aleo/foo.future; - -finalize foo: - input r0 as address.public; - get.or_use count[r0] 0field into r1; - add r1 1field into r2; - set r2 into count[r0]; - -///////////////////////////////////////////////// - -import child.aleo; - -program parent.aleo; - -function foo: - call child.aleo/foo into r0; - call child.aleo/foo into r1; - async foo r0 into r2; - output r2 as parent.aleo/foo.future; - -finalize foo: - input r0 as child.aleo/foo.future; - await r0; - diff --git a/synthesizer/tests/utilities/expectation.rs b/synthesizer/tests/utilities/expectation.rs index 549718ba7c..47e2a9f0cf 100644 --- a/synthesizer/tests/utilities/expectation.rs +++ b/synthesizer/tests/utilities/expectation.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/tests/utilities/mod.rs b/synthesizer/tests/utilities/mod.rs index 36bbebaadc..74b45bc6d6 100644 --- a/synthesizer/tests/utilities/mod.rs +++ b/synthesizer/tests/utilities/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -25,7 +26,7 @@ #![allow(unused)] pub type CurrentAleo = circuit::network::AleoV0; -pub type CurrentNetwork = console::network::Testnet3; +pub type CurrentNetwork = console::network::MainnetV0; pub mod expectation; pub use expectation::*; diff --git a/synthesizer/tests/utilities/tests/file_parse_test.rs b/synthesizer/tests/utilities/tests/file_parse_test.rs index 035811d6b1..66da5c350a 100644 --- a/synthesizer/tests/utilities/tests/file_parse_test.rs +++ b/synthesizer/tests/utilities/tests/file_parse_test.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,9 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{get_expectation_path, print_difference, ExpectedTest}; +use crate::{ExpectedTest, get_expectation_path, print_difference}; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use std::path::{Path, PathBuf}; /// A test for a parser, where the entire file is the test input. diff --git a/synthesizer/tests/utilities/tests/line_parse_test.rs b/synthesizer/tests/utilities/tests/line_parse_test.rs index 5456f26bb5..af27483727 100644 --- a/synthesizer/tests/utilities/tests/line_parse_test.rs +++ b/synthesizer/tests/utilities/tests/line_parse_test.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,9 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{get_expectation_path, print_difference, ExpectedTest}; +use crate::{ExpectedTest, get_expectation_path, print_difference}; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use itertools::Itertools; use std::path::{Path, PathBuf}; diff --git a/synthesizer/tests/utilities/tests/mod.rs b/synthesizer/tests/utilities/tests/mod.rs index f42ebac475..941df4b18a 100644 --- a/synthesizer/tests/utilities/tests/mod.rs +++ b/synthesizer/tests/utilities/tests/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/synthesizer/tests/utilities/tests/program_test.rs b/synthesizer/tests/utilities/tests/program_test.rs index 71290b0a0b..713b700f5e 100644 --- a/synthesizer/tests/utilities/tests/program_test.rs +++ b/synthesizer/tests/utilities/tests/program_test.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,12 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{get_expectation_path, print_difference, CurrentNetwork, ExpectedTest}; +use crate::{CurrentNetwork, ExpectedTest, get_expectation_path, print_difference}; use console::{account::PrivateKey, program::Identifier}; use snarkvm_synthesizer::program::Program; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use itertools::Itertools; use serde_yaml::{Mapping, Sequence, Value}; use std::{ @@ -140,8 +141,8 @@ impl ExpectedTest for ProgramTest { if !self.rewrite { // Check that the errors match. let expected_errors = - self.expected.get(&Value::String("errors".to_string())).unwrap().as_sequence().unwrap(); - let actual_errors = output.get(&Value::String("errors".to_string())).unwrap().as_sequence().unwrap(); + self.expected.get(Value::String("errors".to_string())).unwrap().as_sequence().unwrap(); + let actual_errors = output.get(Value::String("errors".to_string())).unwrap().as_sequence().unwrap(); expected_errors.iter().zip_eq(actual_errors.iter()).for_each(|(expected, actual)| { if expected != actual { let expected = @@ -152,8 +153,8 @@ impl ExpectedTest for ProgramTest { }); // Check that the outputs match. let expected_outputs = - self.expected.get(&Value::String("outputs".to_string())).unwrap().as_sequence().unwrap(); - let actual_outputs = output.get(&Value::String("outputs".to_string())).unwrap().as_sequence().unwrap(); + self.expected.get(Value::String("outputs".to_string())).unwrap().as_sequence().unwrap(); + let actual_outputs = output.get(Value::String("outputs".to_string())).unwrap().as_sequence().unwrap(); self.cases.iter().zip_eq(expected_outputs.iter().zip_eq(actual_outputs.iter())).for_each( |(test, (expected, actual))| { if expected != actual { diff --git a/utilities/Cargo.toml b/utilities/Cargo.toml index 0614b4f1f9..8d6ca632a4 100644 --- a/utilities/Cargo.toml +++ b/utilities/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-utilities" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Utilities for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -25,7 +25,7 @@ edition = "2021" [dependencies.snarkvm-utilities-derives] path = "./derives" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.aleo-std] diff --git a/utilities/derives/Cargo.toml b/utilities/derives/Cargo.toml index 560b7cfdff..c92d70cf86 100644 --- a/utilities/derives/Cargo.toml +++ b/utilities/derives/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-utilities-derives" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "Canonical serialization for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", diff --git a/utilities/derives/src/canonical_deserialize.rs b/utilities/derives/src/canonical_deserialize.rs index 7dfc4397c4..1349f0a199 100644 --- a/utilities/derives/src/canonical_deserialize.rs +++ b/utilities/derives/src/canonical_deserialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/utilities/derives/src/canonical_serialize.rs b/utilities/derives/src/canonical_serialize.rs index 794eec190a..3e7d8b2053 100644 --- a/utilities/derives/src/canonical_serialize.rs +++ b/utilities/derives/src/canonical_serialize.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,7 +14,7 @@ // limitations under the License. use proc_macro2::TokenStream; -use quote::{quote, ToTokens}; +use quote::{ToTokens, quote}; use syn::{Data, Index, Type}; pub(crate) enum IdentOrIndex { diff --git a/utilities/derives/src/lib.rs b/utilities/derives/src/lib.rs index 7e1938bbc9..13e24006b2 100644 --- a/utilities/derives/src/lib.rs +++ b/utilities/derives/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/utilities/src/biginteger/bigint_256.rs b/utilities/src/biginteger/bigint_256.rs index 02c8438379..ac9f78d7db 100644 --- a/utilities/src/biginteger/bigint_256.rs +++ b/utilities/src/biginteger/bigint_256.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,21 +14,21 @@ // limitations under the License. use crate::{ - biginteger::BigInteger, - bititerator::{BitIteratorBE, BitIteratorLE}, - io::{Read, Result as IoResult, Write}, FromBits, FromBytes, ToBits, ToBytes, + biginteger::BigInteger, + bititerator::{BitIteratorBE, BitIteratorLE}, + io::{Read, Result as IoResult, Write}, }; use anyhow::Result; use core::fmt::{Debug, Display}; use num_bigint::BigUint; use rand::{ - distributions::{Distribution, Standard}, Rng, + distributions::{Distribution, Standard}, }; use zeroize::Zeroize; @@ -229,12 +230,16 @@ impl crate::biginteger::BigInteger for BigInteger256 { impl ToBits for BigInteger256 { #[doc = " Returns `self` as a boolean array in little-endian order, with trailing zeros."] fn write_bits_le(&self, vec: &mut Vec) { - vec.extend(BitIteratorLE::new(self)); + let iter = BitIteratorLE::new(self); + vec.reserve(iter.len()); + vec.extend(iter); } #[doc = " Returns `self` as a boolean array in big-endian order, with leading zeros."] fn write_bits_be(&self, vec: &mut Vec) { - vec.extend(BitIteratorBE::new(self)); + let iter = BitIteratorBE::new(self); + vec.reserve(iter.len()); + vec.extend(iter); } } diff --git a/utilities/src/biginteger/bigint_384.rs b/utilities/src/biginteger/bigint_384.rs index 6177a5cffa..4ee46574a5 100644 --- a/utilities/src/biginteger/bigint_384.rs +++ b/utilities/src/biginteger/bigint_384.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,21 +14,21 @@ // limitations under the License. use crate::{ - biginteger::BigInteger, - bititerator::{BitIteratorBE, BitIteratorLE}, - io::{Read, Result as IoResult, Write}, FromBits, FromBytes, ToBits, ToBytes, + biginteger::BigInteger, + bititerator::{BitIteratorBE, BitIteratorLE}, + io::{Read, Result as IoResult, Write}, }; use anyhow::Result; use core::fmt::{Debug, Display}; use num_bigint::BigUint; use rand::{ - distributions::{Distribution, Standard}, Rng, + distributions::{Distribution, Standard}, }; use zeroize::Zeroize; diff --git a/utilities/src/biginteger/mod.rs b/utilities/src/biginteger/mod.rs index 34fe2e1d4b..e404bb1648 100644 --- a/utilities/src/biginteger/mod.rs +++ b/utilities/src/biginteger/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{rand::Uniform, FromBits, FromBytes, ToBits, ToBytes}; +use crate::{FromBits, FromBytes, ToBits, ToBytes, rand::Uniform}; use num_bigint::BigUint; use std::fmt::{Debug, Display}; diff --git a/utilities/src/biginteger/tests.rs b/utilities/src/biginteger/tests.rs index d76b7d72f6..f21af15a30 100644 --- a/utilities/src/biginteger/tests.rs +++ b/utilities/src/biginteger/tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/utilities/src/bititerator.rs b/utilities/src/bititerator.rs index 90b2340b0f..53b46f7279 100644 --- a/utilities/src/bititerator.rs +++ b/utilities/src/bititerator.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/utilities/src/bits.rs b/utilities/src/bits.rs index 53e9a04c44..257ebff250 100644 --- a/utilities/src/bits.rs +++ b/utilities/src/bits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use crate::Vec; -use anyhow::{ensure, Result}; +use anyhow::{Result, ensure}; /// Takes as input a sequence of objects, and converts them to a series of little-endian bits. /// All traits that implement `ToBits` can be automatically converted to bits in this manner. @@ -318,7 +319,7 @@ mod tests { use crate::{TestRng, Uniform}; use anyhow::Result; - use rand::{distributions::Alphanumeric, Rng}; + use rand::{Rng, distributions::Alphanumeric}; const ITERATIONS: u64 = 10000; diff --git a/utilities/src/bytes.rs b/utilities/src/bytes.rs index 9a7ba1d824..d7e7477559 100644 --- a/utilities/src/bytes.rs +++ b/utilities/src/bytes.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,17 +14,17 @@ // limitations under the License. use crate::{ + Vec, error, fmt, io::{Read, Result as IoResult, Write}, marker::PhantomData, - Vec, }; use serde::{ - de::{self, Error, SeqAccess, Visitor}, - ser::{self, SerializeTuple}, Deserializer, Serializer, + de::{self, Error, SeqAccess, Visitor}, + ser::{self, SerializeTuple}, }; use smol_str::SmolStr; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; @@ -80,7 +81,7 @@ pub trait FromBytes { } } -pub struct ToBytesSerializer(String, Option, PhantomData); +pub struct ToBytesSerializer(PhantomData); impl ToBytesSerializer { /// Serializes a static-sized object as a byte array (without length encoding). @@ -100,7 +101,7 @@ impl ToBytesSerializer { } } -pub struct FromBytesDeserializer(String, Option, PhantomData); +pub struct FromBytesDeserializer(PhantomData); impl<'de, T: FromBytes> FromBytesDeserializer { /// Deserializes a static-sized byte array (without length encoding). @@ -166,12 +167,12 @@ impl<'de, T: FromBytes> FromBytesDeserializer { } } -pub struct FromBytesVisitor<'a>(&'a mut Vec, SmolStr, Option); +pub struct FromBytesVisitor<'a>(&'a mut Vec, SmolStr); impl<'a> FromBytesVisitor<'a> { /// Initializes a new `FromBytesVisitor` with the given `buffer` and `name`. pub fn new(buffer: &'a mut Vec, name: &str) -> Self { - Self(buffer, SmolStr::new(name), None) + Self(buffer, SmolStr::new(name)) } } @@ -456,7 +457,7 @@ impl<'a, T: 'a + ToBytes> ToBytes for &'a T { } #[inline] -pub fn bits_from_bytes_le(bytes: &[u8]) -> impl Iterator + DoubleEndedIterator + '_ { +pub fn bits_from_bytes_le(bytes: &[u8]) -> impl DoubleEndedIterator + '_ { bytes.iter().flat_map(|byte| (0..8).map(move |i| (*byte >> i) & 1 == 1)) } @@ -478,6 +479,40 @@ pub fn bytes_from_bits_le(bits: &[bool]) -> Vec { bytes } +/// A wrapper around a `Write` instance that limits the number of bytes that can be written. +pub struct LimitedWriter { + writer: W, + limit: usize, + remaining: usize, +} + +impl LimitedWriter { + pub fn new(writer: W, limit: usize) -> Self { + Self { writer, limit, remaining: limit } + } +} + +impl Write for LimitedWriter { + fn write(&mut self, buf: &[u8]) -> IoResult { + if self.remaining == 0 && !buf.is_empty() { + return Err(std::io::Error::new(std::io::ErrorKind::Other, format!("Byte limit exceeded: {}", self.limit))); + } + + let max_write = std::cmp::min(buf.len(), self.remaining); + match self.writer.write(&buf[..max_write]) { + Ok(n) => { + self.remaining -= n; + Ok(n) + } + Err(e) => Err(e), + } + } + + fn flush(&mut self) -> IoResult<()> { + self.writer.flush() + } +} + #[cfg(test)] mod test { use super::*; diff --git a/utilities/src/error.rs b/utilities/src/error.rs index 97ab38bc65..4de22d2c1e 100644 --- a/utilities/src/error.rs +++ b/utilities/src/error.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -38,11 +39,11 @@ impl Error for crate::String {} #[cfg(not(feature = "std"))] impl Error for crate::io::Error {} -/// This purpose of this macro is to catch the instances of halting -/// without producing logs looking like unexpected panics. It prints -/// to stderr using the format: "Halted at : ". +/// This macro provides a VM runtime environment which will safely halt +/// without producing logs that look like unexpected behavior. +/// In debug mode, it prints to stderr using the format: "VM safely halted at : ". #[macro_export] -macro_rules! handle_halting { +macro_rules! try_vm_runtime { ($e:expr) => {{ use std::panic; @@ -52,12 +53,13 @@ macro_rules! handle_halting { let msg = e.to_string(); let msg = msg.split_ascii_whitespace().skip_while(|&word| word != "panicked").collect::>(); let mut msg = msg.join(" "); - msg = msg.replacen("panicked", "Halted", 1); + msg = msg.replacen("panicked", "VM safely halted", 1); + #[cfg(debug_assertions)] eprintln!("{msg}"); })); // Perform the operation that may panic. - let result = panic::catch_unwind($e); + let result = panic::catch_unwind(panic::AssertUnwindSafe($e)); // Restore the standard panic hook. let _ = panic::take_hook(); diff --git a/utilities/src/io.rs b/utilities/src/io.rs index a52d4a8205..2b94680da0 100644 --- a/utilities/src/io.rs +++ b/utilities/src/io.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/utilities/src/iterator.rs b/utilities/src/iterator.rs index df3a7f2a0b..4a5b11dc08 100644 --- a/utilities/src/iterator.rs +++ b/utilities/src/iterator.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/utilities/src/lib.rs b/utilities/src/lib.rs index a6c5fd85d3..4991cbc8a5 100644 --- a/utilities/src/lib.rs +++ b/utilities/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/utilities/src/parallel.rs b/utilities/src/parallel.rs index 73bc141709..6c998b96ec 100644 --- a/utilities/src/parallel.rs +++ b/utilities/src/parallel.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -196,6 +197,20 @@ macro_rules! cfg_reduce_with { }}; } +/// Turns a collection into an iterator. +#[macro_export] +macro_rules! cfg_keys { + ($e: expr) => {{ + #[cfg(not(feature = "serial"))] + let result = $e.par_keys(); + + #[cfg(feature = "serial")] + let result = $e.keys(); + + result + }}; +} + /// Turns a collection into an iterator. #[macro_export] macro_rules! cfg_values { @@ -254,3 +269,43 @@ macro_rules! cfg_zip_fold { result }}; } + +/// Performs an unstable sort +#[macro_export] +macro_rules! cfg_sort_unstable_by { + ($self: expr, $closure: expr) => {{ + #[cfg(feature = "serial")] + $self.sort_unstable_by($closure); + + #[cfg(not(feature = "serial"))] + $self.par_sort_unstable_by($closure); + }}; +} + +/// Performs a sort that caches the extracted keys +#[macro_export] +macro_rules! cfg_sort_by_cached_key { + ($self: expr, $closure: expr) => {{ + #[cfg(feature = "serial")] + $self.sort_by_cached_key($closure); + + #[cfg(not(feature = "serial"))] + $self.par_sort_by_cached_key($closure); + }}; +} + +/// Returns a sorted, by-value iterator for the given IndexMap/IndexSet +#[macro_export] +macro_rules! cfg_sorted_by { + ($self: expr, $closure: expr) => {{ + #[cfg(feature = "serial")] + { + $self.sorted_by($closure) + } + + #[cfg(not(feature = "serial"))] + { + $self.par_sorted_by($closure) + } + }}; +} diff --git a/utilities/src/rand.rs b/utilities/src/rand.rs index b92f0e95da..b93671256a 100644 --- a/utilities/src/rand.rs +++ b/utilities/src/rand.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,10 +14,10 @@ // limitations under the License. use rand::{ - distributions::{Distribution, Standard}, - rngs::StdRng, Rng, SeedableRng, + distributions::{Distribution, Standard}, + rngs::StdRng, }; use rand_xorshift::XorShiftRng; diff --git a/utilities/src/serialize/error.rs b/utilities/src/serialize/error.rs index c98779005b..8231015387 100644 --- a/utilities/src/serialize/error.rs +++ b/utilities/src/serialize/error.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/utilities/src/serialize/flags.rs b/utilities/src/serialize/flags.rs index 436c66f3fc..026f394f6b 100644 --- a/utilities/src/serialize/flags.rs +++ b/utilities/src/serialize/flags.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/utilities/src/serialize/helpers.rs b/utilities/src/serialize/helpers.rs index 53600b66f8..3385795a99 100644 --- a/utilities/src/serialize/helpers.rs +++ b/utilities/src/serialize/helpers.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,12 +14,12 @@ // limitations under the License. pub use crate::{ - io::{self, Read, Write}, FromBytes, ToBytes, Vec, + io::{self, Read, Write}, }; -use crate::{serialize::traits::*, SerializationError}; +use crate::{SerializationError, serialize::traits::*}; /// Serialize a Vector's elements without serializing the Vector's length /// If you want to serialize the full Vector, use `CanonicalSerialize for Vec` diff --git a/utilities/src/serialize/impls.rs b/utilities/src/serialize/impls.rs index ee09a23478..e20d707d3a 100644 --- a/utilities/src/serialize/impls.rs +++ b/utilities/src/serialize/impls.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -13,12 +14,12 @@ // limitations under the License. pub use crate::{ - io::{Read, Write}, FromBytes, ToBytes, Vec, + io::{Read, Write}, }; -use crate::{serialize::traits::*, SerializationError}; +use crate::{SerializationError, serialize::traits::*}; use bincode::Options; diff --git a/utilities/src/serialize/mod.rs b/utilities/src/serialize/mod.rs index 00048a9ea2..68328d63a6 100644 --- a/utilities/src/serialize/mod.rs +++ b/utilities/src/serialize/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/utilities/src/serialize/traits.rs b/utilities/src/serialize/traits.rs index 373ca02abd..8e4e3702f7 100644 --- a/utilities/src/serialize/traits.rs +++ b/utilities/src/serialize/traits.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,8 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub use crate::io::{Read, Write}; use crate::SerializationError; +pub use crate::io::{Read, Write}; use serde::de::{self, DeserializeOwned, Deserializer}; diff --git a/vm/cli/cli.rs b/vm/cli/cli.rs index deb1c70d97..6597cf1012 100644 --- a/vm/cli/cli.rs +++ b/vm/cli/cli.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,7 +17,7 @@ use crate::cli::commands::{Build, Clean, Execute, New, Run, Update}; use anstyle::{AnsiColor, Color, Style}; use anyhow::Result; -use clap::{builder::Styles, Parser}; +use clap::{Parser, builder::Styles}; const HEADER_COLOR: Option = Some(Color::Ansi(AnsiColor::Yellow)); const LITERAL_COLOR: Option = Some(Color::Ansi(AnsiColor::Green)); diff --git a/vm/cli/commands/build.rs b/vm/cli/commands/build.rs index 671ca61554..4ca5023f9a 100644 --- a/vm/cli/commands/build.rs +++ b/vm/cli/commands/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -41,7 +42,7 @@ impl Build { // package.build::(match self.offline { // true => None, - // false => Some(endpoint.unwrap_or("https://vm.aleo.org/testnet3/build".to_string())), + // false => Some(endpoint.unwrap_or("https://api.explorer.aleo.org/v0/mainnet/build".to_string())), // })?; // Prepare the path string. diff --git a/vm/cli/commands/clean.rs b/vm/cli/commands/clean.rs index 7662f40acc..a3d25050ea 100644 --- a/vm/cli/commands/clean.rs +++ b/vm/cli/commands/clean.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/vm/cli/commands/execute.rs b/vm/cli/commands/execute.rs index 6fd0f50164..1d7eea971c 100644 --- a/vm/cli/commands/execute.rs +++ b/vm/cli/commands/execute.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/vm/cli/commands/mod.rs b/vm/cli/commands/mod.rs index 68f71186e3..5fe8695be7 100644 --- a/vm/cli/commands/mod.rs +++ b/vm/cli/commands/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -44,5 +45,5 @@ use std::collections::HashMap; pub const LOCALE: &num_format::Locale = &num_format::Locale::en; -pub(crate) type CurrentNetwork = crate::prelude::Testnet3; +pub(crate) type CurrentNetwork = crate::prelude::MainnetV0; pub(crate) type Aleo = crate::circuit::AleoV0; diff --git a/vm/cli/commands/new.rs b/vm/cli/commands/new.rs index 9c54d3bae2..c555aeeba5 100644 --- a/vm/cli/commands/new.rs +++ b/vm/cli/commands/new.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/vm/cli/commands/run.rs b/vm/cli/commands/run.rs index 285b46034b..7a98e075fb 100644 --- a/vm/cli/commands/run.rs +++ b/vm/cli/commands/run.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -100,7 +101,7 @@ impl Run { mod tests { use super::*; use crate::{ - cli::{Command, CLI}, + cli::{CLI, Command}, prelude::{Identifier, Value}, }; diff --git a/vm/cli/commands/update.rs b/vm/cli/commands/update.rs index 84fd1966b4..eeb6f46355 100644 --- a/vm/cli/commands/update.rs +++ b/vm/cli/commands/update.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/vm/cli/errors.rs b/vm/cli/errors.rs index e82b80920b..ff2f8aacc4 100644 --- a/vm/cli/errors.rs +++ b/vm/cli/errors.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/vm/cli/helpers/env.rs b/vm/cli/helpers/env.rs index ed41cafc72..e4b2111b6d 100644 --- a/vm/cli/helpers/env.rs +++ b/vm/cli/helpers/env.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,11 +15,11 @@ use crate::{cli::CurrentNetwork, console::account::PrivateKey}; -use anyhow::{anyhow, Result}; +use anyhow::{Result, anyhow}; fn env_template() -> String { r#" -NETWORK=testnet3 +NETWORK=mainnet PRIVATE_KEY={{PASTE_YOUR_PRIVATE_KEY_HERE}} "# .to_string() diff --git a/vm/cli/helpers/mod.rs b/vm/cli/helpers/mod.rs index 564a3181a7..76ce3d7ce6 100644 --- a/vm/cli/helpers/mod.rs +++ b/vm/cli/helpers/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/vm/cli/helpers/updater.rs b/vm/cli/helpers/updater.rs index 47c8769b2b..7912cdfa03 100644 --- a/vm/cli/helpers/updater.rs +++ b/vm/cli/helpers/updater.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -16,7 +17,7 @@ use crate::cli::errors::UpdaterError; use anyhow::Result; use colored::Colorize; -use self_update::{backends::github, version::bump_is_greater, Status}; +use self_update::{Status, backends::github, version::bump_is_greater}; pub struct Updater; @@ -24,7 +25,7 @@ pub struct Updater; impl Updater { const SNARKVM_BIN_NAME: &'static str = "snarkvm"; const SNARKVM_REPO_NAME: &'static str = "snarkvm"; - const SNARKVM_REPO_OWNER: &'static str = "AleoHQ"; + const SNARKVM_REPO_OWNER: &'static str = "AleoNet"; /// Show all available releases for `snarkvm`. #[allow(clippy::format_push_string)] diff --git a/vm/cli/main.rs b/vm/cli/main.rs index 2d5de7b2ae..402532954c 100644 --- a/vm/cli/main.rs +++ b/vm/cli/main.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use snarkvm::cli::{Updater, CLI}; +use snarkvm::cli::{CLI, Updater}; use clap::Parser; diff --git a/vm/cli/mod.rs b/vm/cli/mod.rs index 765e3d8ea7..8276ba33b5 100644 --- a/vm/cli/mod.rs +++ b/vm/cli/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/vm/file/aleo.rs b/vm/file/aleo.rs index bae28c6b2c..9eaecd769f 100644 --- a/vm/file/aleo.rs +++ b/vm/file/aleo.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -18,7 +19,7 @@ use crate::{ synthesizer::Program, }; -use anyhow::{anyhow, bail, ensure, Result}; +use anyhow::{Result, anyhow, bail, ensure}; use core::str::FromStr; use std::{ fs::{self, File}, @@ -241,7 +242,7 @@ mod tests { use super::*; use crate::prelude::Parser; - type CurrentNetwork = snarkvm_console::network::Testnet3; + type CurrentNetwork = snarkvm_console::network::MainnetV0; fn temp_dir() -> std::path::PathBuf { tempfile::tempdir().expect("Failed to open temporary directory").into_path() diff --git a/vm/file/avm.rs b/vm/file/avm.rs index ac252d87ed..ee0b7443a5 100644 --- a/vm/file/avm.rs +++ b/vm/file/avm.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -17,7 +18,7 @@ use crate::{ synthesizer::Program, }; -use anyhow::{anyhow, ensure, Result}; +use anyhow::{Result, anyhow, ensure}; use std::{ fs::{self, File}, io::Write, @@ -181,7 +182,7 @@ mod tests { use super::*; use crate::prelude::Parser; - type CurrentNetwork = snarkvm_console::network::Testnet3; + type CurrentNetwork = snarkvm_console::network::MainnetV0; fn temp_dir() -> std::path::PathBuf { tempfile::tempdir().expect("Failed to open temporary directory").into_path() diff --git a/vm/file/manifest.rs b/vm/file/manifest.rs index af3a1aa23c..e9e4ee68a1 100644 --- a/vm/file/manifest.rs +++ b/vm/file/manifest.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -17,7 +18,7 @@ use crate::{ synthesizer::Program, }; -use anyhow::{anyhow, ensure, Result}; +use anyhow::{Result, anyhow, ensure}; use core::str::FromStr; use std::{ fs::{self, File}, diff --git a/vm/file/mod.rs b/vm/file/mod.rs index 43d7141f5f..645b25f763 100644 --- a/vm/file/mod.rs +++ b/vm/file/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/vm/file/prover.rs b/vm/file/prover.rs index 69d4ad8369..1bac807b46 100644 --- a/vm/file/prover.rs +++ b/vm/file/prover.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,10 +15,10 @@ use crate::{ prelude::{FromBytes, Identifier, IoResult, Network, Read, ToBytes}, - synthesizer::{snark::ProvingKey, Program}, + synthesizer::{Program, snark::ProvingKey}, }; -use anyhow::{anyhow, bail, ensure, Result}; +use anyhow::{Result, anyhow, bail, ensure}; use std::{ fs::{self, File}, io::Write, @@ -198,7 +199,7 @@ mod tests { synthesizer::Process, }; - type CurrentNetwork = snarkvm_console::network::Testnet3; + type CurrentNetwork = snarkvm_console::network::MainnetV0; type CurrentAleo = snarkvm_circuit::AleoV0; fn temp_dir() -> std::path::PathBuf { diff --git a/vm/file/readme_file.rs b/vm/file/readme_file.rs index 687780ca89..8b5e049c18 100644 --- a/vm/file/readme_file.rs +++ b/vm/file/readme_file.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -17,7 +18,7 @@ use crate::{ synthesizer::Program, }; -use anyhow::{ensure, Result}; +use anyhow::{Result, ensure}; use std::{ fs::File, io::Write, diff --git a/vm/file/verifier.rs b/vm/file/verifier.rs index aaa664bd43..af0b4f9673 100644 --- a/vm/file/verifier.rs +++ b/vm/file/verifier.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,10 +15,10 @@ use crate::{ prelude::{FromBytes, Identifier, IoResult, Network, Read, ToBytes}, - synthesizer::{snark::VerifyingKey, Program}, + synthesizer::{Program, snark::VerifyingKey}, }; -use anyhow::{anyhow, bail, ensure, Result}; +use anyhow::{Result, anyhow, bail, ensure}; use std::{ fs::{self, File}, io::Write, @@ -198,7 +199,7 @@ mod tests { synthesizer::Process, }; - type CurrentNetwork = snarkvm_console::network::Testnet3; + type CurrentNetwork = snarkvm_console::network::MainnetV0; type CurrentAleo = snarkvm_circuit::AleoV0; fn temp_dir() -> std::path::PathBuf { diff --git a/vm/lib.rs b/vm/lib.rs index 60d18da0df..2b7c215ada 100644 --- a/vm/lib.rs +++ b/vm/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/vm/package/build.rs b/vm/package/build.rs index d7057df8e6..251e8cf1b5 100644 --- a/vm/package/build.rs +++ b/vm/package/build.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 diff --git a/vm/package/clean.rs b/vm/package/clean.rs index 561041c6d1..9ca16756a2 100644 --- a/vm/package/clean.rs +++ b/vm/package/clean.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -49,7 +50,7 @@ impl Package { mod tests { use super::*; - type CurrentNetwork = snarkvm_console::network::Testnet3; + type CurrentNetwork = snarkvm_console::network::MainnetV0; type CurrentAleo = snarkvm_circuit::network::AleoV0; #[test] diff --git a/vm/package/deploy.rs b/vm/package/deploy.rs index cc3ec45644..f423ed51de 100644 --- a/vm/package/deploy.rs +++ b/vm/package/deploy.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -168,7 +169,7 @@ impl Package { mod tests { use super::*; - type CurrentNetwork = snarkvm_console::network::Testnet3; + type CurrentNetwork = snarkvm_console::network::MainnetV0; type CurrentAleo = snarkvm_circuit::network::AleoV0; #[test] diff --git a/vm/package/execute.rs b/vm/package/execute.rs index e075e8de86..e848a14ad9 100644 --- a/vm/package/execute.rs +++ b/vm/package/execute.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -117,7 +118,7 @@ mod tests { type CurrentAleo = snarkvm_circuit::network::AleoV0; - // TODO: Re-enable this test after `staging` is merged into `testnet3` for the October 18, 2023 calibration reset. + // TODO: Re-enable this test after `mainnet`. #[test] #[ignore] fn test_execute() { diff --git a/vm/package/is_build_required.rs b/vm/package/is_build_required.rs index 0ce4a9253f..dfaa62390d 100644 --- a/vm/package/is_build_required.rs +++ b/vm/package/is_build_required.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -65,17 +66,17 @@ impl Package { #[cfg(test)] mod tests { use super::*; - use snarkvm_console::network::Testnet3; + use snarkvm_console::network::MainnetV0; use std::{fs::File, io::Write}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; type Aleo = crate::circuit::AleoV0; fn temp_dir() -> PathBuf { tempfile::tempdir().expect("Failed to open temporary directory").into_path() } - fn initialize_unbuilt_package(valid: bool) -> Result> { + fn initialize_unbuilt_package(valid: bool) -> Result> { // Initialize a temporary directory. let directory = temp_dir(); @@ -99,7 +100,7 @@ mod tests { std::fs::create_dir_all(build_directory).unwrap(); // Open the package at the temporary directory. - Package::::open(&directory) + Package::::open(&directory) } fn program_with_id(id: &str) -> String { diff --git a/vm/package/mod.rs b/vm/package/mod.rs index 87f383df83..678d892400 100644 --- a/vm/package/mod.rs +++ b/vm/package/mod.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -28,7 +29,7 @@ use crate::{ network::Network, program::{Identifier, Locator, ProgramID, Response, Value}, }, - file::{AVMFile, AleoFile, Manifest, ProverFile, VerifierFile, README}, + file::{AVMFile, AleoFile, Manifest, ProverFile, README, VerifierFile}, ledger::{block::Execution, query::Query, store::helpers::memory::BlockMemory}, prelude::{Deserialize, Deserializer, Serialize, SerializeStruct, Serializer}, synthesizer::{ @@ -38,7 +39,7 @@ use crate::{ }, }; -use anyhow::{bail, ensure, Error, Result}; +use anyhow::{Error, Result, bail, ensure}; use core::str::FromStr; use rand::{CryptoRng, Rng}; use std::path::{Path, PathBuf}; @@ -180,11 +181,11 @@ impl Package { #[cfg(test)] pub(crate) mod test_helpers { use super::*; - use snarkvm_console::{account::Address, network::Testnet3, prelude::TestRng}; + use snarkvm_console::{account::Address, network::MainnetV0, prelude::TestRng}; use std::{fs::File, io::Write}; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; fn temp_dir() -> PathBuf { tempfile::tempdir().expect("Failed to open temporary directory").into_path() @@ -389,7 +390,7 @@ function main: let _manifest_file = Manifest::create(&directory, main_program_id).unwrap(); // Open the package at the temporary directory. - let package = Package::::open(&directory).unwrap(); + let package = Package::::open(&directory).unwrap(); assert_eq!(package.program_id(), main_program_id); // Return the temporary directory and the package. @@ -465,11 +466,11 @@ function main: #[cfg(test)] mod tests { use super::*; - use crate::prelude::Testnet3; + use crate::prelude::MainnetV0; use snarkvm_utilities::TestRng; type CurrentAleo = snarkvm_circuit::network::AleoV0; - type CurrentNetwork = Testnet3; + type CurrentNetwork = MainnetV0; #[test] fn test_imports_directory() { diff --git a/vm/package/run.rs b/vm/package/run.rs index 54b1520ead..5cfb358741 100644 --- a/vm/package/run.rs +++ b/vm/package/run.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -53,7 +54,7 @@ impl Package { // Initialize the call stack. let call_stack = CallStack::PackageRun(vec![request], *private_key, assignments.clone()); // Synthesize the circuit. - let response = stack.execute_function::(call_stack, None, rng)?; + let response = stack.execute_function::(call_stack, None, None, rng)?; // Retrieve the call metrics. let call_metrics = assignments.read().iter().map(|(_, metrics)| *metrics).collect::>(); // Return the response and call metrics. diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index 4183bbf38c..7d39c22718 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "snarkvm-wasm" -version = "0.16.19" +version = "1.1.0" authors = [ "The Aleo Team " ] description = "WASM for a decentralized virtual machine" homepage = "https://aleo.org" -repository = "https://github.com/AleoHQ/snarkVM" +repository = "https://github.com/AleoNet/snarkVM" keywords = [ "aleo", "cryptography", @@ -51,54 +51,54 @@ utilities = [ "snarkvm-utilities" ] [dependencies.snarkvm-circuit-network] path = "../circuit/network" -version = "=0.16.19" +version = "=1.1.0" features = [ "wasm" ] optional = true [dependencies.snarkvm-console] path = "../console" -version = "=0.16.19" +version = "=1.1.0" features = [ "wasm" ] optional = true [dependencies.snarkvm-curves] path = "../curves" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-fields] path = "../fields" -version = "=0.16.19" +version = "=1.1.0" optional = true [dependencies.snarkvm-ledger-block] path = "../ledger/block" -version = "=0.16.19" +version = "=1.1.0" features = [ "wasm" ] optional = true [dependencies.snarkvm-ledger-query] path = "../ledger/query" -version = "=0.16.19" +version = "=1.1.0" features = [ "async", "wasm" ] optional = true [dependencies.snarkvm-ledger-store] path = "../ledger/store" -version = "=0.16.19" +version = "=1.1.0" features = [ "wasm" ] optional = true [dependencies.snarkvm-synthesizer] path = "../synthesizer" -version = "=0.16.19" +version = "=1.1.0" default-features = false features = [ "async", "wasm" ] optional = true [dependencies.snarkvm-utilities] path = "../utilities" -version = "=0.16.19" +version = "=1.1.0" features = [ "wasm" ] optional = true diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs index 2d9e723294..3477882213 100644 --- a/wasm/src/lib.rs +++ b/wasm/src/lib.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -12,12 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#[cfg(feature = "network")] -pub use snarkvm_circuit_network as circuit_network; #[cfg(feature = "console")] pub use snarkvm_console as console; -#[cfg(feature = "network")] -pub use snarkvm_console::network as console_network; #[cfg(feature = "curves")] pub use snarkvm_curves as curves; #[cfg(feature = "fields")] diff --git a/wasm/src/tests.rs b/wasm/src/tests.rs index 8cdc5e17f8..1d3f2f843b 100644 --- a/wasm/src/tests.rs +++ b/wasm/src/tests.rs @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023 Aleo Systems Inc. +// Copyright 2024 Aleo Network Foundation // This file is part of the snarkVM library. // 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 @@ -14,7 +15,7 @@ use snarkvm_console::{ account::{Address, PrivateKey, ViewKey}, - network::Testnet3, + network::MainnetV0, }; use snarkvm_utilities::TestRng; @@ -29,7 +30,7 @@ fn test_account() { const ALEO_VIEW_KEY: &str = "AViewKey1n1n3ZbnVEtXVe3La2xWkUvY3EY7XaCG6RZJJ3tbvrrrD"; const ALEO_ADDRESS: &str = "aleo1wvgwnqvy46qq0zemj0k6sfp3zv0mp77rw97khvwuhac05yuwscxqmfyhwf"; - let private_key = PrivateKey::::from_str(ALEO_PRIVATE_KEY).unwrap(); + let private_key = PrivateKey::::from_str(ALEO_PRIVATE_KEY).unwrap(); assert_eq!(ALEO_PRIVATE_KEY, private_key.to_string()); let view_key = ViewKey::try_from(&private_key).unwrap(); @@ -45,7 +46,7 @@ fn test_account_sign() { for _ in 0..ITERATIONS { // Sample a new private key and address. - let private_key = PrivateKey::::new(&mut rng).unwrap(); + let private_key = PrivateKey::::new(&mut rng).unwrap(); let address = Address::try_from(&private_key).unwrap(); // Sign a message with the account private key.
Howard Wu
Howard Wu

💻 🚧 🤔 👀
Raymond Chu
Raymond Chu

💻 🚧 🤔 👀
d0cd
d0cd

💻 🚧 🤔 👀
Pratyush Mishra
Pratyush Mishra

💻 🚧 🤔 👀
vicsn
vicsn

💻 🚧 📖 👀
ljedrz
ljedrz

💻 🔧 👀
Mike Turner
Mike Turner

💻 📖 👀
Howard Wu
Howard Wu

💻 🚧 🤔 👀
Raymond Chu
Raymond Chu

💻 🚧 🤔 👀
d0cd
d0cd

💻 🚧 🤔 👀
Pratyush Mishra
Pratyush Mishra

💻 🚧 🤔 👀
vicsn
vicsn

💻 🚧 📖 👀
ljedrz
ljedrz

💻 🔧 👀
Mike Turner
Mike Turner

💻 📖 👀
Collin Chin
Collin Chin

💻 📖 👀
Alessandro Coglio
Alessandro Coglio

💻 📖 ⚠️
Niklas Long
Niklas Long

💻
jules
jules

💻
Ali Mousa
Ali Mousa

💻
Weikeng Chen
Weikeng Chen

💻
Evan Schott
Evan Schott

💻
Collin Chin
Collin Chin

💻 📖 👀
Alessandro Coglio
Alessandro Coglio

💻 📖 ⚠️
Niklas Long
Niklas Long

💻
jules
jules

💻
Ali Mousa
Ali Mousa

💻
Weikeng Chen
Weikeng Chen

💻
Evan Schott
Evan Schott

💻
Max Bruce
Max Bruce

💻
zhiqiangxu
zhiqiangxu

💻
Javier Rodríguez Chatruc
Javier Rodríguez Chatruc

💻
Eduardo Morais
Eduardo Morais

💻
Maciej Zwoliński
Maciej Zwoliński

💻
Ivan Litteri
Ivan Litteri

💻
Francisco Strambini
Francisco Strambini

💻
Max Bruce
Max Bruce

💻
zhiqiangxu
zhiqiangxu

💻
Javier Rodríguez Chatruc
Javier Rodríguez Chatruc

💻
Eduardo Morais
Eduardo Morais

💻
Maciej Zwoliński
Maciej Zwoliński

💻
Ivan Litteri
Ivan Litteri

💻
Francisco Strambini
Francisco Strambini

💻
Haruka
Haruka

🐛 💻
StarLI-Trapdoor
StarLI-Trapdoor

💻
Vesa-Ville
Vesa-Ville

💻
Jos Dehaes
Jos Dehaes

💻
apruden2008
apruden2008

💻
Evan Marshall
Evan Marshall

🐛 💻
Psi Vesely
Psi Vesely

💻
Haruka
Haruka

🐛 💻
StarLI-Trapdoor
StarLI-Trapdoor

💻
Vesa-Ville
Vesa-Ville

💻
Jos Dehaes
Jos Dehaes

💻
apruden2008
apruden2008

💻
Evan Marshall
Evan Marshall

🐛 💻
Psi Vesely
Psi Vesely

💻
swift-mx
swift-mx

💻
Nacho Avecilla
Nacho Avecilla

💻
qy3u
qy3u

💻
Yt
Yt

💻
Kostyan
Kostyan

💻
stanlagermin
stanlagermin

💻
Sukey
Sukey

💻
swift-mx
swift-mx

💻
Nacho Avecilla
Nacho Avecilla

💻
qy3u
qy3u

💻
Yt
Yt

💻
Kostyan
Kostyan

💻
stanlagermin
stanlagermin

💻
Sukey
Sukey

💻
Alex Zhao
Alex Zhao

💻
ghost ant
ghost ant

💻
Psi Vesely
Psi Vesely

💻
Dependabot
Dependabot

💻
Dependabot Preview
Dependabot Preview

💻
All Contributors
All Contributors

📖
Alex Zhao
Alex Zhao

💻
ghost ant
ghost ant

💻
Psi Vesely
Psi Vesely

💻
Dependabot
Dependabot

💻
Dependabot Preview
Dependabot Preview

💻
All Contributors
All Contributors

📖