diff --git a/.github/workflows/bitcoin-canister-update.yml b/.github/workflows/bitcoin-canister-update.yml new file mode 100644 index 0000000000..55dad64246 --- /dev/null +++ b/.github/workflows/bitcoin-canister-update.yml @@ -0,0 +1,69 @@ +name: Check Bitcoin Canister Release Update + +on: + workflow_dispatch: + schedule: + - cron: '0 0 * * *' # Runs at UTC midnight every day + +jobs: + check-update: + runs-on: ubuntu-latest + + steps: + - name: Checkout dfx repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Fetch Bitcoin Canister latest release tag + env: + GH_TOKEN: "${{ secrets.NIV_UPDATER_TOKEN }}" + run: | + LATEST_TAG=$(gh release view --repo dfinity/bitcoin-canister --json tagName -q .tagName) + echo "Latest tag is $LATEST_TAG" + echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV + + - name: Check if the latest release tag has been updated + run: | + URL_ENCODED_CURRENT_TAG=$(jq -r '.["ic-btc-canister"].version' nix/sources.json) + CURRENT_TAG=$(python -c "import sys, urllib.parse as ul; print(ul.unquote_plus(sys.argv[1]))" "$URL_ENCODED_CURRENT_TAG") + echo "Current tag is $CURRENT_TAG" + if [[ "$CURRENT_TAG" == "$LATEST_TAG" ]]; then + echo "No update is required." + exit 1 + else + echo "An update is required." + fi + + + - name: install Nix + uses: cachix/install-nix-action@v21 + with: + nix_path: nixpkgs=channel:nixos-unstable + + - name: install niv (dependency manager for Nix projects) + run: nix-env -i niv -f '' + + - name: install packages from nix/sources.json + run: niv update + + - name: update sources + run: | + URL_ENCODED_LATEST_TAG=$(echo -n "$LATEST_TAG" | python -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip(), safe=""))') + niv update ic-btc-canister -a version=$URL_ENCODED_LATEST_TAG + ./scripts/write-dfx-asset-sources.sh + + - name: Update dfx to use the latest Bitcoin Canister version + env: + GH_TOKEN: "${{ secrets.NIV_UPDATER_TOKEN }}" + run: | + git config user.name github-actions + git config user.email github-actions@github.com + git checkout -b bot/update-bitcoin-canister/$LATEST_TAG + git add . + git commit -m "Update Bitcoin Canister to $LATEST_TAG" + git push --set-upstream origin bot/update-bitcoin-canister/$LATEST_TAG + PR_TITLE="chore: Update Bitcoin Canister Version to $LATEST_TAG" + PR_BODY="This PR updates the Bitcoin Canister version to the latest tag: $LATEST_TAG" + gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base master --head $(git branch --show-current) + diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 9b468bffef..41bed9aa7e 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -97,6 +97,10 @@ jobs: path: /usr/local/bin - name: Setup dfx binary run: chmod +x /usr/local/bin/dfx + - name: Disable query verification in ic-ref + if: ${{ matrix.backend == 'ic-ref' }} + run: | + echo DFX_DISABLE_QUERY_VERIFICATION=1 >> $GITHUB_ENV - name: start and deploy run: | pwd diff --git a/CHANGELOG.md b/CHANGELOG.md index a496863420..e4d6102937 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,31 @@ # UNRELEASED +=== fix: `dfx canister delete ` removes the related entry from the canister id store + +Previously, deleting a canister in the project by id rather than by name +would leave the canister id in the canister id store. This would cause +`dfx deploy` to fail. + +=== fix: dfx extension install can no longer create a corrupt cache directory + +Running `dfx cache delete && dfx extension install nns` would previously +create a cache directory containing only an `extensions` subdirectory. +dfx only looks for the existence of a cache version subdirectory to +determine whether it has been installed. The end result was that later +commands would fail when the cache did not contain expected files. + +=== fix: output_env_file is now considered relative to project root + +The .env file location, whether specified as `output_env_file` in dfx.json +or `--output-env-file ` on the commandline, is now considered relative +to the project root, rather than relative to the current working directory. + +=== feat: Read dfx canister install argument from a file + +Enables passing large arguments that cannot be passed directly in the command line using the `--argument-file` flag. For example `dfx canister install --argument-file ./my/argument/file.txt my_canister_name`. + + ### feat: change `list_permitted` and `list_authorized` to an update call. This requires the `list_authorized` and `list_permitted` methods to be called as an update and disables the ability to @@ -24,7 +49,7 @@ Added the following subcommands: ### Motoko -Updated Motoko to [0.10.1](https://github.com/dfinity/motoko/releases/tag/0.10.1) +Updated Motoko to [0.10.2](https://github.com/dfinity/motoko/releases/tag/0.10.2) ### Frontend canister @@ -51,6 +76,10 @@ This incorporates the following executed proposals: - [124858](https://dashboard.internetcomputer.org/proposal/124858) - [124857](https://dashboard.internetcomputer.org/proposal/124857) +### Bitcoin canister + +Updated Bitcoin canister to [release/2023-10-13](https://github.com/dfinity/bitcoin-canister/releases/tag/release%2F2023-10-13) + # 0.15.1 ### feat: Added support for reserved_cycles and reserved_cycles_limit diff --git a/Cargo.lock b/Cargo.lock index 7a5695181b..f62c4bec0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,6 +177,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -723,6 +729,19 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cached" +version = "0.46.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c8c50262271cdf5abc979a5f76515c234e764fa025d1ba4862c0f0bcda0e95" +dependencies = [ + "ahash 0.8.6", + "hashbrown 0.14.2", + "instant", + "once_cell", + "thiserror", +] + [[package]] name = "candid" version = "0.8.4" @@ -1191,6 +1210,19 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core", + "subtle-ng", + "zeroize", +] + [[package]] name = "cvt" version = "0.1.2" @@ -1352,7 +1384,7 @@ checksum = "6a1abaf4d861455be59f64fd2b55606cb151fce304ede7165f410243ce96bde6" [[package]] name = "dfx" -version = "0.15.2-beta.1" +version = "0.15.2-beta.2" dependencies = [ "actix", "aes-gcm", @@ -1388,7 +1420,7 @@ dependencies = [ "ic-asset", "ic-cdk", "ic-identity-hsm", - "ic-utils 0.29.0", + "ic-utils 0.30.2", "ic-wasm", "icrc-ledger-types", "indicatif", @@ -1458,7 +1490,7 @@ dependencies = [ "humantime-serde", "ic-agent", "ic-identity-hsm", - "ic-utils 0.29.0", + "ic-utils 0.30.2", "k256 0.11.6", "keyring", "lazy_static", @@ -1629,6 +1661,21 @@ dependencies = [ "spki 0.7.2", ] +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core", + "serde", + "sha2 0.9.9", + "thiserror", + "zeroize", +] + [[package]] name = "either" version = "1.9.0" @@ -2201,6 +2248,10 @@ name = "hashbrown" version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +dependencies = [ + "ahash 0.8.6", + "allocator-api2", +] [[package]] name = "heck" @@ -2408,11 +2459,13 @@ dependencies = [ [[package]] name = "ic-agent" -version = "0.29.0" -source = "git+https://github.com/dfinity/agent-rs.git?rev=b91b85b7b6ba6bfaf9dfd616b7c7c8f966bf8f68#b91b85b7b6ba6bfaf9dfd616b7c7c8f966bf8f68" +version = "0.30.2" +source = "git+https://github.com/dfinity/agent-rs.git?rev=ed0862a45d5973ff123cbabc4ac40a89821b18c6#ed0862a45d5973ff123cbabc4ac40a89821b18c6" dependencies = [ "backoff", + "cached 0.46.1", "candid 0.9.11", + "ed25519-consensus", "futures-util", "hex", "http", @@ -2425,6 +2478,7 @@ dependencies = [ "pem 2.0.1", "pkcs8 0.10.2", "rand", + "rangemap", "reqwest", "ring 0.16.20", "rustls-webpki", @@ -2455,7 +2509,7 @@ dependencies = [ "globset", "hex", "ic-agent", - "ic-utils 0.29.0", + "ic-utils 0.30.2", "itertools 0.10.5", "json5", "mime", @@ -2657,7 +2711,7 @@ source = "git+https://github.com/dfinity/ic.git?rev=a533346f63f4091eb64692891de0 dependencies = [ "arrayvec 0.5.2", "base64 0.11.0", - "cached", + "cached 0.41.0", "hex", "ic-crypto-internal-bls12-381-type", "ic-crypto-internal-seed", @@ -2774,8 +2828,8 @@ dependencies = [ [[package]] name = "ic-identity-hsm" -version = "0.29.0" -source = "git+https://github.com/dfinity/agent-rs.git?rev=b91b85b7b6ba6bfaf9dfd616b7c7c8f966bf8f68#b91b85b7b6ba6bfaf9dfd616b7c7c8f966bf8f68" +version = "0.30.2" +source = "git+https://github.com/dfinity/agent-rs.git?rev=ed0862a45d5973ff123cbabc4ac40a89821b18c6#ed0862a45d5973ff123cbabc4ac40a89821b18c6" dependencies = [ "hex", "ic-agent", @@ -2870,8 +2924,8 @@ dependencies = [ [[package]] name = "ic-transport-types" -version = "0.29.0" -source = "git+https://github.com/dfinity/agent-rs.git?rev=b91b85b7b6ba6bfaf9dfd616b7c7c8f966bf8f68#b91b85b7b6ba6bfaf9dfd616b7c7c8f966bf8f68" +version = "0.30.2" +source = "git+https://github.com/dfinity/agent-rs.git?rev=ed0862a45d5973ff123cbabc4ac40a89821b18c6#ed0862a45d5973ff123cbabc4ac40a89821b18c6" dependencies = [ "candid 0.9.11", "hex", @@ -2945,8 +2999,8 @@ dependencies = [ [[package]] name = "ic-utils" -version = "0.29.0" -source = "git+https://github.com/dfinity/agent-rs.git?rev=b91b85b7b6ba6bfaf9dfd616b7c7c8f966bf8f68#b91b85b7b6ba6bfaf9dfd616b7c7c8f966bf8f68" +version = "0.30.2" +source = "git+https://github.com/dfinity/agent-rs.git?rev=ed0862a45d5973ff123cbabc4ac40a89821b18c6#ed0862a45d5973ff123cbabc4ac40a89821b18c6" dependencies = [ "async-trait", "candid 0.9.11", @@ -3039,7 +3093,7 @@ dependencies = [ "humantime", "ic-agent", "ic-asset", - "ic-utils 0.29.0", + "ic-utils 0.30.2", "libflate", "num-traits", "pem 1.1.1", @@ -4484,6 +4538,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "rangemap" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "977b1e897f9d764566891689e642653e5ed90c6895106acd005eb4c1d0203991" + [[package]] name = "rayon" version = "1.8.0" @@ -5454,6 +5514,12 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + [[package]] name = "supports-color" version = "1.3.1" diff --git a/Cargo.toml b/Cargo.toml index 869e4773e3..8a42a64df0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,18 +18,18 @@ rust-version = "1.71.1" license = "Apache-2.0" [workspace.dependencies] -candid = { version = "0.9.0", features = [ "parser" ] } -ic-agent = "0.29.0" +candid = { version = "0.9.0", features = ["parser"] } +ic-agent = "0.30.2" ic-asset = { path = "src/canisters/frontend/ic-asset" } ic-cdk = "0.10.0" -ic-identity-hsm = "0.29.0" -ic-utils = "0.29.0" +ic-identity-hsm = "0.30.2" +ic-utils = "0.30.2" aes-gcm = "0.9.4" anyhow = "1.0.56" anstyle = "1.0.0" argon2 = "0.4.0" -backoff = { version = "0.4.0", features = [ "futures", "tokio" ] } +backoff = { version = "0.4.0", features = ["futures", "tokio"] } base64 = "0.13.0" byte-unit = "4.0.14" bytes = "1.2.1" @@ -69,19 +69,19 @@ url = "2.1.0" walkdir = "2.3.2" [patch.crates-io.ic-agent] -version = "0.29.0" +version = "0.30.2" git = "https://github.com/dfinity/agent-rs.git" -rev = "b91b85b7b6ba6bfaf9dfd616b7c7c8f966bf8f68" +rev = "ed0862a45d5973ff123cbabc4ac40a89821b18c6" [patch.crates-io.ic-identity-hsm] -version = "0.29.0" +version = "0.30.2" git = "https://github.com/dfinity/agent-rs.git" -rev = "b91b85b7b6ba6bfaf9dfd616b7c7c8f966bf8f68" +rev = "ed0862a45d5973ff123cbabc4ac40a89821b18c6" [patch.crates-io.ic-utils] -version = "0.29.0" +version = "0.30.2" git = "https://github.com/dfinity/agent-rs.git" -rev = "b91b85b7b6ba6bfaf9dfd616b7c7c8f966bf8f68" +rev = "ed0862a45d5973ff123cbabc4ac40a89821b18c6" [profile.release] panic = 'abort' diff --git a/docs/cli-reference/dfx-canister.md b/docs/cli-reference/dfx-canister.md index 555b83df78..ffc06eed56 100644 --- a/docs/cli-reference/dfx-canister.md +++ b/docs/cli-reference/dfx-canister.md @@ -438,6 +438,7 @@ You can use the following optional flags with the `dfx canister install` command | Flag | Description | |-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `--argument-file` | Specifies the file from which to read the argument to pass to the init method. Stdin may be referred to as `-`. | | `--async-call` | Enables you to continue without waiting for the result of the installation to be returned by polling the Internet Computer or the local canister execution environment. | | `--upgrade-unchanged` | Upgrade the canister even if the .wasm did not change. | diff --git a/e2e/tests-dfx/certificate.bash b/e2e/tests-dfx/certificate.bash index 1fe5d66269..a86a2baeeb 100644 --- a/e2e/tests-dfx/certificate.bash +++ b/e2e/tests-dfx/certificate.bash @@ -73,6 +73,7 @@ teardown() { # The wallet does not have a query call forward method (currently calls forward from wallet's update method) # So call with users Identity as sender here # There may need to be a query version of wallet_call + declare -x DFX_DISABLE_QUERY_VERIFICATION=1 assert_command dfx canister call certificate_backend hello_query '("Buckaroo")' assert_eq '("Hullo, Buckaroo!")' } diff --git a/e2e/tests-dfx/delete.bash b/e2e/tests-dfx/delete.bash index d87e08bcfd..5aa7b3e610 100755 --- a/e2e/tests-dfx/delete.bash +++ b/e2e/tests-dfx/delete.bash @@ -14,6 +14,19 @@ teardown() { standard_teardown } +@test "delete by canister id cleans up canister id store" { + dfx_start + dfx deploy e2e_project_backend + id=$(dfx canister id e2e_project_backend) + dfx canister stop e2e_project_backend + assert_command dfx canister delete "$id" + assert_command_fail dfx canister info e2e_project_backend + assert_contains "Cannot find canister id. Please issue 'dfx canister create e2e_project_backend'." + assert_command_fail dfx canister status "$id" + assert_contains "Canister $id not found" + assert_command dfx deploy +} + @test "delete can be used to delete a canister" { dfx_start dfx deploy e2e_project_backend diff --git a/e2e/tests-dfx/dotenv.bash b/e2e/tests-dfx/dotenv.bash index 1f6f2ab755..2f92e07d0e 100644 --- a/e2e/tests-dfx/dotenv.bash +++ b/e2e/tests-dfx/dotenv.bash @@ -14,6 +14,43 @@ teardown() { standard_teardown } + +@test "puts .env in project root" { + dfx_start + jq '.canisters["e2e_project_backend"].post_install="echo post install backend"' dfx.json | sponge dfx.json + jq '.canisters["e2e_project_frontend"].post_install="echo post install frontend"' dfx.json | sponge dfx.json + + mkdir subdir + mkdir subdir/canister-install-all subdir/canister-install-single + mkdir subdir/build-all subdir/build-single + mkdir subdir/deploy-single subdir/deploy-all + dfx canister create --all + ( cd subdir/build-single && dfx build e2e_project_frontend ) + ( cd subdir/build-all && dfx build --all ) + ( cd subdir/canister-install-single && dfx canister install e2e_project_backend ) + dfx canister uninstall-code e2e_project_backend + ( cd subdir/canister-install-all && dfx canister install --all ) + rm -rf .dfx + ( cd subdir/deploy-single && dfx deploy e2e_project_backend) + ( cd subdir/deploy-all && dfx deploy ) + + assert_command find . -name .env + assert_eq "./.env" +} + +@test "the output_env_file must be contained within project" { + dfx_start + mkdir ../outside + + assert_command_fail dfx deploy --output-env-file nonexistent/.env + assert_contains "failed to canonicalize output_env_file" + assert_contains "working-dir/e2e_project/nonexistent: No such file or directory" + assert_command_fail dfx deploy --output-env-file /etc/passwd + assert_contains "The output_env_file must be a relative path, but is /etc/passwd" + assert_command_fail dfx deploy --output-env-file ../outside/.env + assert_match "The output_env_file must be within the project root, but is .*/working-dir/e2e_project/../outside/.env" +} + @test "writes environment variables to .env" { dfx_start dfx canister create --all diff --git a/e2e/tests-dfx/extension.bash b/e2e/tests-dfx/extension.bash index f5688d51ef..bf2c627940 100644 --- a/e2e/tests-dfx/extension.bash +++ b/e2e/tests-dfx/extension.bash @@ -13,6 +13,12 @@ teardown() { standard_teardown } +@test "extension install with an empty cache does not create a corrupt cache" { + dfx cache delete + dfx extension install nns --version 0.2.1 + dfx_start +} + @test "install extension from official registry" { assert_command_fail dfx snsx diff --git a/e2e/tests-dfx/install.bash b/e2e/tests-dfx/install.bash index 04fcb84fa9..5511205a07 100644 --- a/e2e/tests-dfx/install.bash +++ b/e2e/tests-dfx/install.bash @@ -182,7 +182,32 @@ teardown() { assert_contains db07e7e24f6f8ddf53c33a610713259a7c1eb71c270b819ebd311e2d223267f0 } +@test "installing one canister with an argument succeeds" { + dfx_start + assert_command dfx canister create e2e_project_backend + assert_command dfx build e2e_project_backend + assert_command dfx canister install e2e_project_backend --argument '()' +} + +@test "installing with an argument in a file succeeds" { + dfx_start + assert_command dfx canister create e2e_project_backend + assert_command dfx build e2e_project_backend + TMPFILE="$(mktemp)" + echo '()' >"$TMPFILE" + assert_command dfx canister install e2e_project_backend --argument-file "$TMPFILE" +} + +@test "installing with an argument on stdin succeeds" { + dfx_start + assert_command dfx canister create e2e_project_backend + assert_command dfx build e2e_project_backend + TMPFILE="$(mktemp)" + echo '()' >"$TMPFILE" + assert_command dfx canister install e2e_project_backend --argument-file - <"$TMPFILE" +} + @test "installing multiple canisters with arguments fails" { - assert_command_fail dfx canister install --all --argument hello + assert_command_fail dfx canister install --all --argument '()' assert_contains "error: the argument '--all' cannot be used with '--argument '" } diff --git a/nix/sources.json b/nix/sources.json index 72e8ea5b82..e73f22befb 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -6,10 +6,10 @@ "homepage": "https://rustsec.org", "owner": "RustSec", "repo": "advisory-db", - "rev": "0c251c3c9a1b08e08ef5946d4c2d133fe1bc213e", - "sha256": "1nqzy1ky570zdkkdc9q7cpi5ys9cxnkyjhzvic1fzfcrrlz92kzd", + "rev": "3338fcfb59cea5fcd7d2a4e7fe24cbc7cb778003", + "sha256": "0fw5xrzafv061jj3lzrnqarbjcm1irzvl338yhkzw1k8firmki7d", "type": "tarball", - "url": "https://github.com/RustSec/advisory-db/archive/0c251c3c9a1b08e08ef5946d4c2d133fe1bc213e.tar.gz", + "url": "https://github.com/RustSec/advisory-db/archive/3338fcfb59cea5fcd7d2a4e7fe24cbc7cb778003.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, "canister_sandbox-x86_64-darwin": { @@ -66,11 +66,11 @@ }, "ic-btc-canister": { "owner": "dfinity", - "sha256": "0izvazr0cpdwjga12zim2cwp3rgm5n3w7ag5yplfl8rxrhwk65f4", + "sha256": "1b34jpxkk72h07ls0fspwrgmndmj7xhlivdhn82msvgz8mx69x89", "type": "file", - "url": "https://github.com/dfinity/bitcoin-canister/releases/download/release%2F2023-03-31/ic-btc-canister.wasm.gz", + "url": "https://github.com/dfinity/bitcoin-canister/releases/download/release%2F2023-10-13/ic-btc-canister.wasm.gz", "url_template": "https://github.com/dfinity/bitcoin-canister/releases/download//ic-btc-canister.wasm.gz", - "version": "release%2F2023-03-31" + "version": "release%2F2023-10-13" }, "ic-https-outcalls-adapter-x86_64-darwin": { "builtin": false, @@ -160,27 +160,27 @@ "builtin": false, "description": "The Motoko base library", "owner": "dfinity", - "sha256": "0b8lsxb3j7qj6kzb32fbkf0a018jkisapcb8szwl8ad023lv3xv3", + "sha256": "12z4mr3r63nnncjqxrsxjhr1z2p8adg7zp48wbacb42jhs0mkfvl", "type": "tarball", - "url": "https://github.com/dfinity/motoko/releases/download/0.10.1/motoko-base-library.tar.gz", + "url": "https://github.com/dfinity/motoko/releases/download/0.10.2/motoko-base-library.tar.gz", "url_template": "https://github.com/dfinity/motoko/releases/download//motoko-base-library.tar.gz", - "version": "0.10.1" + "version": "0.10.2" }, "motoko-x86_64-darwin": { "builtin": false, - "sha256": "1inc2x9misqazgswfz7irvsjp4dkvab87j66yklnvy51w6pi3r7b", + "sha256": "1x49qwzrxc6dj5gik2hpi8l3xdnggqj2v9yvb6sfb7ff6gx3avc6", "type": "file", - "url": "https://github.com/dfinity/motoko/releases/download/0.10.1/motoko-Darwin-x86_64-0.10.1.tar.gz", + "url": "https://github.com/dfinity/motoko/releases/download/0.10.2/motoko-Darwin-x86_64-0.10.2.tar.gz", "url_template": "https://github.com/dfinity/motoko/releases/download//motoko-Darwin-x86_64-.tar.gz", - "version": "0.10.1" + "version": "0.10.2" }, "motoko-x86_64-linux": { "builtin": false, - "sha256": "11jx3r0lw41x7xqajqqc7s9wvkr9kfpg5h38vr9bcvwfndg49flc", + "sha256": "1a1yv2awrd053qk3h9a34y887j2vfhb0ckrk25kjjx4ifdygp8ys", "type": "file", - "url": "https://github.com/dfinity/motoko/releases/download/0.10.1/motoko-Linux-x86_64-0.10.1.tar.gz", + "url": "https://github.com/dfinity/motoko/releases/download/0.10.2/motoko-Linux-x86_64-0.10.2.tar.gz", "url_template": "https://github.com/dfinity/motoko/releases/download//motoko-Linux-x86_64-.tar.gz", - "version": "0.10.1" + "version": "0.10.2" }, "replica-x86_64-darwin": { "builtin": false, diff --git a/public/manifest.json b/public/manifest.json index d6fc9f5a0d..9e0bf6b9ae 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -60,6 +60,7 @@ "0.14.4", "0.15.0", "0.15.1", - "0.15.2-beta.1" + "0.15.2-beta.1", + "0.15.2-beta.2" ] } diff --git a/scripts/workflows/provision-darwin.sh b/scripts/workflows/provision-darwin.sh index 38fb86c9ab..73df981f86 100755 --- a/scripts/workflows/provision-darwin.sh +++ b/scripts/workflows/provision-darwin.sh @@ -27,7 +27,8 @@ if [ "$E2E_TEST" = "tests-dfx/certificate.bash" ]; then brew install mitmproxy fi if [ "$E2E_TEST" = "tests-dfx/deps.bash" ]; then - cargo install ic-wasm + cargo install cargo-binstall + cargo binstall -y ic-wasm fi # Exit temporary directory. diff --git a/scripts/workflows/provision-linux.sh b/scripts/workflows/provision-linux.sh index 9e2b26f111..f00de0f386 100755 --- a/scripts/workflows/provision-linux.sh +++ b/scripts/workflows/provision-linux.sh @@ -36,7 +36,8 @@ if [ "$E2E_TEST" = "tests-dfx/identity_encryption.bash" ] || [ "$E2E_TEST" = "te sudo apt-get install --yes expect fi if [ "$E2E_TEST" = "tests-dfx/deps.bash" ]; then - cargo install ic-wasm + cargo install cargo-binstall + cargo binstall -y ic-wasm fi # Set environment variables. diff --git a/src/canisters/frontend/ic-asset/src/lib.rs b/src/canisters/frontend/ic-asset/src/lib.rs index 8059916760..9e9fa6f454 100644 --- a/src/canisters/frontend/ic-asset/src/lib.rs +++ b/src/canisters/frontend/ic-asset/src/lib.rs @@ -3,7 +3,7 @@ //! # Example //! //! ```rust,no_run -//! use ic_agent::agent::{Agent, http_transport::ReqwestHttpReplicaV2Transport}; +//! use ic_agent::agent::{Agent, http_transport::ReqwestTransport}; //! use ic_agent::identity::BasicIdentity; //! use ic_utils::Canister; //! use std::time::Duration; @@ -12,7 +12,7 @@ //! # let pemfile = ""; //! # let canister_id = ""; //! let agent = Agent::builder() -//! .with_transport(ReqwestHttpReplicaV2Transport::create(replica_url)?) +//! .with_transport(ReqwestTransport::create(replica_url)?) //! .with_identity(BasicIdentity::from_pem_file(pemfile)?) //! .build()?; //! let canister = Canister::builder() diff --git a/src/canisters/frontend/icx-asset/src/main.rs b/src/canisters/frontend/icx-asset/src/main.rs index 490ed4f36c..818180c6dd 100644 --- a/src/canisters/frontend/icx-asset/src/main.rs +++ b/src/canisters/frontend/icx-asset/src/main.rs @@ -110,9 +110,9 @@ async fn main() -> anyhow::Result<()> { let logger = support::new_logger(); let agent = Agent::builder() - .with_transport( - agent::http_transport::ReqwestHttpReplicaV2Transport::create(opts.replica.clone())?, - ) + .with_transport(agent::http_transport::ReqwestTransport::create( + opts.replica.clone(), + )?) .with_boxed_identity(create_identity(opts.pem)) .build()?; diff --git a/src/dfx-core/src/config/model/canister_id_store.rs b/src/dfx-core/src/config/model/canister_id_store.rs index 150c7906eb..76485bef5a 100644 --- a/src/dfx-core/src/config/model/canister_id_store.rs +++ b/src/dfx-core/src/config/model/canister_id_store.rs @@ -188,10 +188,14 @@ impl CanisterIdStore { self.remote_ids .as_ref() .and_then(|remote_ids| self.get_name_in(canister_id, remote_ids)) - .or_else(|| self.get_name_in(canister_id, &self.ids)) + .or_else(|| self.get_name_in_project(canister_id)) .or_else(|| self.get_name_in_pull_ids(canister_id)) } + pub fn get_name_in_project(&self, canister_id: &str) -> Option<&String> { + self.get_name_in(canister_id, &self.ids) + } + pub fn get_name_in<'a>( &'a self, canister_id: &str, diff --git a/src/dfx-core/src/config/model/dfinity.rs b/src/dfx-core/src/config/model/dfinity.rs index e67d9a7c38..17c8b1d8a7 100644 --- a/src/dfx-core/src/config/model/dfinity.rs +++ b/src/dfx-core/src/config/model/dfinity.rs @@ -3,6 +3,7 @@ use crate::config::directories::get_user_dfx_config_dir; use crate::config::model::bitcoin_adapter::BitcoinAdapterLogLevel; use crate::config::model::canister_http_adapter::HttpAdapterLogLevel; +use crate::error::config::GetOutputEnvFileError; use crate::error::dfx_config::AddDependenciesError::CanisterCircularDependency; use crate::error::dfx_config::GetCanisterNamesWithDependenciesError::AddDependenciesFailed; use crate::error::dfx_config::GetComputeAllocationError::GetComputeAllocationFailed; @@ -1013,6 +1014,35 @@ impl Config { ) } + // returns the path to the output env file if any, guaranteed to be + // a child relative to the project root + pub fn get_output_env_file( + &self, + from_cmdline: Option, + ) -> Result, GetOutputEnvFileError> { + from_cmdline + .or(self.config.output_env_file.clone()) + .map(|p| { + if p.is_relative() { + let p = self.get_project_root().join(p); + + // cannot canonicalize a path that doesn't exist, but the parent should exist + let env_parent = + crate::fs::parent(&p).map_err(GetOutputEnvFileError::Parent)?; + let env_parent = crate::fs::canonicalize(&env_parent) + .map_err(GetOutputEnvFileError::Canonicalize)?; + if !env_parent.starts_with(self.get_project_root()) { + Err(GetOutputEnvFileError::OutputEnvFileMustBeInProjectRoot(p)) + } else { + Ok(self.get_project_root().join(p)) + } + } else { + Err(GetOutputEnvFileError::OutputEnvFileMustBeRelative(p)) + } + }) + .transpose() + } + pub fn save(&self) -> Result<(), StructuredFileError> { save_json_file(&self.path, &self.json) } diff --git a/src/dfx-core/src/error/config.rs b/src/dfx-core/src/error/config.rs index 1121332e42..1658ba575e 100644 --- a/src/dfx-core/src/error/config.rs +++ b/src/dfx-core/src/error/config.rs @@ -1,5 +1,6 @@ use crate::error::fs::FsError; use crate::error::get_user_home::GetUserHomeError; +use std::path::PathBuf; use thiserror::Error; #[derive(Error, Debug)] @@ -13,3 +14,18 @@ pub enum ConfigError { #[error("Failed to determine shared network data directory: {0}")] DetermineSharedNetworkDirectoryFailed(GetUserHomeError), } + +#[derive(Error, Debug)] +pub enum GetOutputEnvFileError { + #[error("failed to canonicalize output_env_file")] + Canonicalize(#[source] FsError), + + #[error("The output_env_file must be within the project root, but is {}", .0.display())] + OutputEnvFileMustBeInProjectRoot(PathBuf), + + #[error("The output_env_file must be a relative path, but is {}", .0.display())] + OutputEnvFileMustBeRelative(PathBuf), + + #[error(transparent)] + Parent(FsError), +} diff --git a/src/dfx-core/src/util/mod.rs b/src/dfx-core/src/util/mod.rs index 64a9d30f9f..efb41ba088 100644 --- a/src/dfx-core/src/util/mod.rs +++ b/src/dfx-core/src/util/mod.rs @@ -6,5 +6,6 @@ pub fn network_to_pathcompat(network_name: &str) -> String { pub fn expiry_duration() -> Duration { // 5 minutes is max ingress timeout - Duration::from_secs(60 * 5) + // 4 minutes accounts for possible replica drift + Duration::from_secs(60 * 4) } diff --git a/src/dfx/Cargo.toml b/src/dfx/Cargo.toml index 535aa84ba8..049cadf038 100644 --- a/src/dfx/Cargo.toml +++ b/src/dfx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dfx" -version = "0.15.2-beta.1" +version = "0.15.2-beta.2" authors.workspace = true edition.workspace = true repository.workspace = true @@ -77,7 +77,7 @@ mime.workspace = true mime_guess.workspace = true net2 = "0.2.34" num-traits.workspace = true -os_str_bytes = "6.3.0" +os_str_bytes = { version = "6.3.0", features = ["conversions"] } patch = "0.7.0" pem.workspace = true petgraph = "0.6.0" diff --git a/src/dfx/assets/dfx-asset-sources.toml b/src/dfx/assets/dfx-asset-sources.toml index a44888a10e..5cd20632b0 100644 --- a/src/dfx/assets/dfx-asset-sources.toml +++ b/src/dfx/assets/dfx-asset-sources.toml @@ -30,8 +30,8 @@ url = 'https://download.dfinity.systems/ic/80a6745673a28ee53d257b3fe19dcd6b7efa9 sha256 = 'd42213aea42f1ae55623e7e437ef683e99c0a3a98c1bae7dc24db7c1577005e9' [x86_64-darwin.motoko] -url = 'https://github.com/dfinity/motoko/releases/download/0.10.1/motoko-Darwin-x86_64-0.10.1.tar.gz' -sha256 = 'ebe411afe1a1f86de9f4c6c88396dab3912bf5cef17cc7f5fb0aeb585317ccc6' +url = 'https://github.com/dfinity/motoko/releases/download/0.10.2/motoko-Darwin-x86_64-0.10.2.tar.gz' +sha256 = '866d35fa33ce9de5b459dba72d247ecfb63e288a178a195f91cdb09e3fc789f4' # The replica and canister_sandbox binaries must have the same revision. [x86_64-darwin.replica] @@ -52,12 +52,12 @@ url = 'https://download.dfinity.systems/ic/80a6745673a28ee53d257b3fe19dcd6b7efa9 sha256 = '73a6d72d82025abb58c28d6ada411ac40ed5b482017f409133f7ac5562899990' [x86_64-darwin.motoko-base] -url = 'https://github.com/dfinity/motoko/releases/download/0.10.1/motoko-base-library.tar.gz' -sha256 = '27563ee89ad2b6c24642ccd9b569836cef2a0316d33bc3d2b4cc61ed7ec1017e' +url = 'https://github.com/dfinity/motoko/releases/download/0.10.2/motoko-base-library.tar.gz' +sha256 = 'cfa7950a3f452b0d8f42320061be09176a7aecee5a7851d913a1517a8116fd46' [x86_64-darwin.ic-btc-canister] -url = 'https://github.com/dfinity/bitcoin-canister/releases/download/release%2F2023-03-31/ic-btc-canister.wasm.gz' -sha256 = 'c4153339cc3d23eae8f5e5a9c3872df5e5713913357e11d493bc5d06f257fb47' +url = 'https://github.com/dfinity/bitcoin-canister/releases/download/release%2F2023-10-13/ic-btc-canister.wasm.gz' +sha256 = '09f5647a45ff6d5d05b2b0ed48613fb2365b5fe6573ba0e901509c39fb9564ac' [x86_64-linux.ic-ref] url = 'https://download.dfinity.systems/ic-ref/ic-ref-0.0.1-a9f73dba-x86_64-linux.tar.gz' @@ -88,8 +88,8 @@ url = 'https://download.dfinity.systems/ic/80a6745673a28ee53d257b3fe19dcd6b7efa9 sha256 = 'eb5ea6cd768fda12d00f370665db132d66c262b35f1a513c2807f78881c1cb7a' [x86_64-linux.motoko] -url = 'https://github.com/dfinity/motoko/releases/download/0.10.1/motoko-Linux-x86_64-0.10.1.tar.gz' -sha256 = '8cba445eb38e6fb652de68c0f2ae9b29cfcd933e0c63a9703f3d104e411e5d86' +url = 'https://github.com/dfinity/motoko/releases/download/0.10.2/motoko-Linux-x86_64-0.10.2.tar.gz' +sha256 = 'daa3fb7c739174296711334f0616745bc8839027432538261e05b4cc95d83ea8' # The replica and canister_sandbox binaries must have the same revision. [x86_64-linux.replica] @@ -110,9 +110,9 @@ url = 'https://download.dfinity.systems/ic/80a6745673a28ee53d257b3fe19dcd6b7efa9 sha256 = 'a9e30c500fb108ab5247db0827868fb74914939a04519d08943440f12b020db8' [x86_64-linux.motoko-base] -url = 'https://github.com/dfinity/motoko/releases/download/0.10.1/motoko-base-library.tar.gz' -sha256 = '27563ee89ad2b6c24642ccd9b569836cef2a0316d33bc3d2b4cc61ed7ec1017e' +url = 'https://github.com/dfinity/motoko/releases/download/0.10.2/motoko-base-library.tar.gz' +sha256 = 'cfa7950a3f452b0d8f42320061be09176a7aecee5a7851d913a1517a8116fd46' [x86_64-linux.ic-btc-canister] -url = 'https://github.com/dfinity/bitcoin-canister/releases/download/release%2F2023-03-31/ic-btc-canister.wasm.gz' -sha256 = 'c4153339cc3d23eae8f5e5a9c3872df5e5713913357e11d493bc5d06f257fb47' +url = 'https://github.com/dfinity/bitcoin-canister/releases/download/release%2F2023-10-13/ic-btc-canister.wasm.gz' +sha256 = '09f5647a45ff6d5d05b2b0ed48613fb2365b5fe6573ba0e901509c39fb9564ac' diff --git a/src/dfx/src/commands/build.rs b/src/dfx/src/commands/build.rs index d9abf3412b..22d58f3dcf 100644 --- a/src/dfx/src/commands/build.rs +++ b/src/dfx/src/commands/build.rs @@ -40,9 +40,7 @@ pub fn exec(env: &dyn Environment, opts: CanisterBuildOpts) -> DfxResult { // Read the config. let config = env.get_config_or_anyhow()?; - let env_file = opts - .output_env_file - .or_else(|| config.get_config().output_env_file.clone()); + let env_file = config.get_output_env_file(opts.output_env_file)?; // Check the cache. This will only install the cache if there isn't one installed // already. diff --git a/src/dfx/src/commands/canister/delete.rs b/src/dfx/src/commands/canister/delete.rs index 09f906c96b..db20159dab 100644 --- a/src/dfx/src/commands/canister/delete.rs +++ b/src/dfx/src/commands/canister/delete.rs @@ -91,10 +91,15 @@ async fn delete_canister( ) -> DfxResult { let log = env.get_logger(); let mut canister_id_store = env.get_canister_id_store()?; + let (canister_id, canister_name_to_delete) = match Principal::from_text(canister) { + Ok(canister_id) => ( + canister_id, + canister_id_store.get_name_in_project(canister).cloned(), + ), + Err(_) => (canister_id_store.get(canister)?, Some(canister.to_string())), + }; if !env.get_network_descriptor().is_playground() { - let canister_id = - Principal::from_text(canister).or_else(|_| canister_id_store.get(canister))?; let mut call_sender = call_sender; let to_dank = withdraw_cycles_to_dank || withdraw_cycles_to_dank_principal.is_some(); @@ -268,7 +273,10 @@ async fn delete_canister( canister::delete_canister(env, canister_id, call_sender).await?; } - canister_id_store.remove(canister)?; + + if let Some(canister_name) = canister_name_to_delete { + canister_id_store.remove(&canister_name)?; + } Ok(()) } diff --git a/src/dfx/src/commands/canister/deposit_cycles.rs b/src/dfx/src/commands/canister/deposit_cycles.rs index d68d975b01..1db9ed67f2 100644 --- a/src/dfx/src/commands/canister/deposit_cycles.rs +++ b/src/dfx/src/commands/canister/deposit_cycles.rs @@ -60,6 +60,8 @@ pub async fn exec( opts: DepositCyclesOpts, mut call_sender: &CallSender, ) -> DfxResult { + fetch_root_key_if_needed(env).await?; + let proxy_sender; // choose default wallet if no wallet is specified @@ -79,8 +81,6 @@ pub async fn exec( let config = env.get_config_or_anyhow()?; - fetch_root_key_if_needed(env).await?; - if let Some(canister) = opts.canister.as_deref() { deposit_cycles(env, canister, call_sender, cycles).await } else if opts.all { diff --git a/src/dfx/src/commands/canister/install.rs b/src/dfx/src/commands/canister/install.rs index 2985cbb347..0b01dd243d 100644 --- a/src/dfx/src/commands/canister/install.rs +++ b/src/dfx/src/commands/canister/install.rs @@ -3,8 +3,12 @@ use crate::lib::environment::Environment; use crate::lib::error::DfxResult; use crate::lib::operations::canister::install_canister::install_canister; use crate::lib::root_key::fetch_root_key_if_needed; +use crate::util::clap::parsers::file_or_stdin_parser; use crate::util::get_candid_init_type; -use crate::{lib::canister_info::CanisterInfo, util::blob_from_arguments}; +use crate::{ + lib::canister_info::CanisterInfo, + util::{arguments_from_file, blob_from_arguments}, +}; use dfx_core::identity::CallSender; use anyhow::{anyhow, bail, Context}; @@ -40,9 +44,17 @@ pub struct CanisterInstallOpts { upgrade_unchanged: bool, /// Specifies the argument to pass to the method. - #[arg(long)] + #[arg(long, conflicts_with("argument_file"))] argument: Option, + /// Specifies the file from which to read the argument to pass to the method. + #[arg( + long, + value_parser = file_or_stdin_parser, + conflicts_with("argument") + )] + argument_file: Option, + /// Specifies the data type for the argument when making the call using an argument. #[arg(long, requires("argument"), value_parser = ["idl", "raw"])] argument_type: Option, @@ -107,7 +119,14 @@ pub async fn exec( let canister_id = Principal::from_text(canister).or_else(|_| canister_id_store.get(canister))?; + + let arguments_from_file = opts + .argument_file + .map(|v| arguments_from_file(&v)) + .transpose()?; let arguments = opts.argument.as_deref(); + let arguments = arguments_from_file.as_deref().or(arguments); + let arg_type = opts.argument_type.as_deref(); let canister_info = config.as_ref() .ok_or_else(|| anyhow!("Cannot find dfx configuration file in the current working directory. Did you forget to create one?")) @@ -136,9 +155,7 @@ pub async fn exec( } else { let canister_info = canister_info?; let config = config.unwrap(); - let env_file = opts - .output_env_file - .or_else(|| config.get_config().output_env_file.clone()); + let env_file = config.get_output_env_file(opts.output_env_file)?; let idl_path = canister_info.get_constructor_idl_path(); let init_type = get_candid_init_type(&idl_path); let install_args = || blob_from_arguments(arguments, None, arg_type, &init_type); @@ -163,9 +180,7 @@ pub async fn exec( } else if opts.all { // Install all canisters. let config = env.get_config_or_anyhow()?; - let env_file = opts - .output_env_file - .or_else(|| config.get_config().output_env_file.clone()); + let env_file = config.get_output_env_file(opts.output_env_file)?; if let Some(canisters) = &config.get_config().canisters { for canister in canisters.keys() { if pull_canisters_in_config.contains_key(canister) { diff --git a/src/dfx/src/commands/canister/send.rs b/src/dfx/src/commands/canister/send.rs index 2aced0088b..17e14789dc 100644 --- a/src/dfx/src/commands/canister/send.rs +++ b/src/dfx/src/commands/canister/send.rs @@ -6,7 +6,7 @@ use candid::Principal; use clap::Parser; use dfx_core::identity::CallSender; use ic_agent::agent::Transport; -use ic_agent::{agent::http_transport::ReqwestHttpReplicaV2Transport, RequestId}; +use ic_agent::{agent::http_transport::ReqwestTransport, RequestId}; use std::{fs::File, path::Path}; use std::{io::Read, str::FromStr}; @@ -40,8 +40,8 @@ pub async fn exec( message.validate()?; let network = message.network.clone(); - let transport = ReqwestHttpReplicaV2Transport::create(network) - .context("Failed to create transport object.")?; + let transport = + ReqwestTransport::create(network).context("Failed to create transport object.")?; let content = hex::decode(&message.content).context("Failed to decode message content.")?; let canister_id = Principal::from_text(message.canister_id.clone()) .with_context(|| format!("Failed to parse canister id {:?}.", message.canister_id))?; diff --git a/src/dfx/src/commands/cycles/balance.rs b/src/dfx/src/commands/cycles/balance.rs index 1cdbe78e1b..bfddfd64b7 100644 --- a/src/dfx/src/commands/cycles/balance.rs +++ b/src/dfx/src/commands/cycles/balance.rs @@ -2,6 +2,7 @@ use crate::lib::environment::Environment; use crate::lib::error::DfxResult; use crate::lib::nns_types::account_identifier::Subaccount; use crate::lib::operations::cycles_ledger; +use crate::lib::root_key::fetch_root_key_if_needed; use crate::util::{format_as_trillions, pretty_thousand_separators}; use candid::Principal; use clap::Parser; @@ -29,6 +30,8 @@ pub struct CyclesBalanceOpts { } pub async fn exec(env: &dyn Environment, opts: CyclesBalanceOpts) -> DfxResult { + fetch_root_key_if_needed(env).await?; + let agent = env.get_agent(); let owner = opts.owner.unwrap_or_else(|| { diff --git a/src/dfx/src/commands/deploy.rs b/src/dfx/src/commands/deploy.rs index 7a429dcd85..5058ecb88f 100644 --- a/src/dfx/src/commands/deploy.rs +++ b/src/dfx/src/commands/deploy.rs @@ -115,9 +115,7 @@ pub fn exec(env: &dyn Environment, opts: DeployOpts) -> DfxResult { .map_err(|err| anyhow!(err)) .context("Failed to parse InstallMode.")?; let config = env.get_config_or_anyhow()?; - let env_file = opts - .output_env_file - .or_else(|| config.get_config().output_env_file.clone()); + let env_file = config.get_output_env_file(opts.output_env_file)?; let with_cycles = opts.with_cycles; diff --git a/src/dfx/src/commands/extension/install.rs b/src/dfx/src/commands/extension/install.rs index 6435915951..58e6b472d7 100644 --- a/src/dfx/src/commands/extension/install.rs +++ b/src/dfx/src/commands/extension/install.rs @@ -1,4 +1,5 @@ use crate::commands::DfxCommand; +use crate::config::cache::DiskBasedCache; use crate::lib::environment::Environment; use crate::lib::error::DfxResult; use clap::Parser; @@ -19,6 +20,9 @@ pub struct InstallOpts { } pub fn exec(env: &dyn Environment, opts: InstallOpts) -> DfxResult<()> { + // creating an `extensions` directory in an otherwise empty cache directory would + // cause the cache to be considered "installed" and later commands would fail + DiskBasedCache::install(&env.get_cache().version_str())?; let spinner = env.new_spinner(format!("Installing extension: {}", opts.name).into()); let mgr = env.new_extension_manager()?; let effective_extension_name = opts.install_as.clone().unwrap_or_else(|| opts.name.clone()); diff --git a/src/dfx/src/commands/ledger/balance.rs b/src/dfx/src/commands/ledger/balance.rs index f02fd0657c..6d397ea02d 100644 --- a/src/dfx/src/commands/ledger/balance.rs +++ b/src/dfx/src/commands/ledger/balance.rs @@ -2,6 +2,7 @@ use crate::lib::environment::Environment; use crate::lib::error::DfxResult; use crate::lib::nns_types::account_identifier::{AccountIdentifier, Subaccount}; use crate::lib::operations::ledger; +use crate::lib::root_key::fetch_root_key_if_needed; use anyhow::anyhow; use candid::Principal; use clap::Parser; @@ -23,6 +24,7 @@ pub struct BalanceOpts { } pub async fn exec(env: &dyn Environment, opts: BalanceOpts) -> DfxResult { + fetch_root_key_if_needed(env).await?; let sender = env .get_selected_identity_principal() .expect("Selected identity not instantiated."); diff --git a/src/dfx/src/lib/builders/mod.rs b/src/dfx/src/lib/builders/mod.rs index cfa2934da2..0a553ef1ff 100644 --- a/src/dfx/src/lib/builders/mod.rs +++ b/src/dfx/src/lib/builders/mod.rs @@ -448,7 +448,7 @@ fn write_environment_variables(vars: &[Env<'_>], write_path: &Path) -> DfxResult // the section is correctly formed let end_pos = end_pos + END_TAG.len() + start_pos + START_TAG.len(); existing_file.replace_range(start_pos..end_pos, &write_string); - fs::write(write_path, existing_file)?; + dfx_core::fs::write(write_path, existing_file)?; return Ok(()); } else { // the file has been edited, so we don't know how much to delete, so we append instead @@ -456,10 +456,10 @@ fn write_environment_variables(vars: &[Env<'_>], write_path: &Path) -> DfxResult } // append to the existing file existing_file.push_str(&write_string); - fs::write(write_path, existing_file)?; + dfx_core::fs::write(write_path, existing_file)?; } else { // no existing file, okay to clobber - fs::write(write_path, write_string)?; + dfx_core::fs::write(write_path, write_string)?; } Ok(()) } @@ -501,7 +501,7 @@ impl BuildConfig { idl_root: canister_root.join("idl/"), // TODO: possibly move to `network_root.join("idl/")` lsp_root: network_root.join("lsp/"), canisters_to_build: None, - env_file: config_intf.output_env_file.clone(), + env_file: config.get_output_env_file(None)?, }) } diff --git a/src/dfx/src/lib/environment.rs b/src/dfx/src/lib/environment.rs index f1056a72ee..e77b2ab090 100644 --- a/src/dfx/src/lib/environment.rs +++ b/src/dfx/src/lib/environment.rs @@ -383,11 +383,14 @@ pub fn create_agent( identity: Box, timeout: Duration, ) -> DfxResult { + let disable_query_verification = + std::env::var("DFX_DISABLE_QUERY_VERIFICATION").is_ok_and(|x| !x.trim().is_empty()); let agent = Agent::builder() .with_transport(ic_agent::agent::http_transport::ReqwestTransport::create( url, )?) .with_boxed_identity(identity) + .with_verify_query_signatures(!disable_query_verification) .with_ingress_expiry(Some(timeout)) .build()?; Ok(agent) diff --git a/src/dfx/src/lib/replica/status.rs b/src/dfx/src/lib/replica/status.rs index 8851ff78bf..3efc7ee84f 100644 --- a/src/dfx/src/lib/replica/status.rs +++ b/src/dfx/src/lib/replica/status.rs @@ -1,13 +1,13 @@ use crate::lib::error::DfxResult; use anyhow::{bail, Context}; -use ic_agent::agent::http_transport::ReqwestHttpReplicaV2Transport; +use ic_agent::agent::http_transport::ReqwestTransport; use ic_agent::Agent; use std::time::Duration; pub async fn ping_and_wait(url: &str) -> DfxResult { let agent = Agent::builder() .with_transport( - ReqwestHttpReplicaV2Transport::create(url) + ReqwestTransport::create(url) .with_context(|| format!("Failed to create replica transport from url {url}.",))?, ) .build() diff --git a/src/dfx/src/lib/sign/sign_transport.rs b/src/dfx/src/lib/sign/sign_transport.rs index 217b9ab9a6..768af94107 100644 --- a/src/dfx/src/lib/sign/sign_transport.rs +++ b/src/dfx/src/lib/sign/sign_transport.rs @@ -65,6 +65,19 @@ impl Transport for SignTransport { Box::pin(run(self, envelope)) } + fn read_subnet_state( + &self, + _: Principal, + _: Vec, + ) -> Pin, AgentError>> + Send + '_>> { + async fn run() -> Result, AgentError> { + Err(AgentError::MessageError( + "read_subnet_state calls not supported".to_string(), + )) + } + Box::pin(run()) + } + fn call<'a>( &'a self, _effective_canister_id: Principal, diff --git a/src/dfx/src/util/currency_conversion.rs b/src/dfx/src/util/currency_conversion.rs index 1980e091b1..ad312582f9 100644 --- a/src/dfx/src/util/currency_conversion.rs +++ b/src/dfx/src/util/currency_conversion.rs @@ -4,7 +4,7 @@ use crate::lib::{ use anyhow::Context; use dfx_core::config::model::dfinity::DEFAULT_IC_GATEWAY; use fn_error_context::context; -use ic_agent::{agent::http_transport::ReqwestHttpReplicaV2Transport, Agent}; +use ic_agent::{agent::http_transport::ReqwestTransport, Agent}; use rust_decimal::Decimal; /// How many cycles you get per XDR when converting ICP to cycles @@ -16,7 +16,7 @@ const CYCLES_PER_XDR: u128 = 1_000_000_000_000; pub async fn as_cycles_with_current_exchange_rate(icpts: &ICPTs) -> DfxResult { let agent = Agent::builder() .with_transport( - ReqwestHttpReplicaV2Transport::create(DEFAULT_IC_GATEWAY) + ReqwestTransport::create(DEFAULT_IC_GATEWAY) .context("Failed to create transport object to default ic gateway.")?, ) .build()