Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(beta): enable cycles ledger support #3669

Merged
merged 4 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

# UNRELEASED

### feat(beta): enable cycles ledger support

If the environment variable `DFX_CYCLES_LEDGER_SUPPORT_ENABLE` is set and no cycles wallet is configured, then dfx will try to use the cycles ledger to perform any operation that the cycles wallet usually is used for.

The following commands/options have been unhidden:
- `dfx cycles`
- `--from-subaccount` for `dfx deploy`, `dfx canister create`, `dfx canister deposit-cycles` to determine which cycles ledger subaccount the used cycles should be used from
- `--created-at-time` for `dfx deploy`, `dfx create canister`, `dfx canister deposit-cycles` to control transaction deduplication on the cycles ledger
- `--to-subaccount` for `dfx canister delete` to control into which subaccount cycles are withdrawn before the canister is deleted

The cycles ledger will not be supported by default until the cycles ledger canister is under NNS control.

### feat: dfx canister call ... --output json

This is the same as `dfx canister call ... | idl2json`, for convenience.
Expand Down
13 changes: 13 additions & 0 deletions docs/cli-reference/dfx-canister.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ You can use the following options with the `dfx canister create` command.
|-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `-c`, `--compute-allocation <allocation>` | Specifies the canister's compute allocation. This should be a percent in the range [0..100]. |
| `--controller <principal>` | Specifies the identity name or the principal of the new controller. |
| `--created-at-time <timestamp>` | Transaction timestamp, in nanoseconds, for use in controlling transaction deduplication, default is system time. https://internetcomputer.org/docs/current/developer-docs/integrations/icrc-1/#transaction-deduplication- |
| `--from-subaccount <subaccount>` | Subaccount of the selected identity to spend cycles from. |
| `--memory-allocation <memory>` | Specifies how much memory the canister is allowed to use in total. This should be a value in the range [0..12 GiB]. A setting of 0 means the canister will have access to memory on a “best-effort” basis: It will only be charged for the memory it uses, but at any point in time may stop running if it tries to allocate more memory when there isn’t space available on the subnet. |
| `--reserved-cycles-limit <limit>` | Specifies the upper limit for the canister's reserved cycles. |
| `--no-wallet` | Performs the call with the user Identity as the Sender of messages. Bypasses the Wallet canister. Enabled by default. |
Expand Down Expand Up @@ -326,6 +328,7 @@ You can use the following options with the `dfx canister delete` command.
| Option | Description |
|---------------------------------------------------|------------------------------------------------------------------------------------|
| `--no-withdrawal` | Do not withdrawal cycles, just delete the canister. |
| `--to-subaccount` | Subaccount of the selected identity to deposit cycles to. |
| `--withdraw-cycles-to-dank` | Withdraw cycles to dank with the current principal. |
| `--withdraw-cycles-to-canister <principal>` | Withdraw cycles from canister(s) to the specified canister/wallet before deleting. |
| `--withdraw-cycles-to-dank-principal <principal>` | Withdraw cycles to dank with the given principal. |
Expand Down Expand Up @@ -378,6 +381,16 @@ You can use the following arguments with the `dfx canister deposit-cycles` comma
| `--all` | Deposits the specified amount of cycles into all canisters configured in `dfx.json`. Note that you must specify `--all` or an individual canister name. |
| `canister_name` | Specifies the name of the canister you want to deposit cycles into. Note that you must specify either a canister name or the `--all` option. |

### Options

You can use the following options with the `dfx canister deposit-cycles` command.

| Option | Description |
|-------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `--created-at-time <timestamp>` | Transaction timestamp, in nanoseconds, for use in controlling transaction deduplication, default is system time. https://internetcomputer.org/docs/current/developer-docs/integrations/icrc-1/#transaction-deduplication- |
| `--from-subaccount <subaccount>` | Subaccount of the selected identity to spend cycles from. |


### Examples

You can use the `dfx canister deposit-cycles` command to add cycles to a specific canister or all canisters.
Expand Down
2 changes: 2 additions & 0 deletions docs/cli-reference/dfx-deploy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ You can use the following options with the `dfx deploy` command.
| `--argument <argument>` | Specifies an argument to pass to the canister during installation. |
| `--argument-type <argument-type>` | Specifies the data type for the argument when making the call using an argument [possible values: idl, raw] |
| `--argument-file <argument-file>` | Specifies the file from which to read the argument to pass to the init method. Stdin may be referred to as `-`. |
| `--created-at-time <timestamp>` | Transaction timestamp, in nanoseconds, for use in controlling transaction deduplication, default is system time. https://internetcomputer.org/docs/current/developer-docs/integrations/icrc-1/#transaction-deduplication- |
| `--from-subaccount <subaccount>` | Subaccount of the selected identity to spend cycles from. |
| `--with-cycles <number-of-cycles>` | Enables you to specify the initial number of cycles for a canister in a project. |
| `--specified-id <PRINCIPAL>` | Attempts to create the canister with this Canister ID |
| `--by-proposal` | Upload proposed changed assets, but do not commit them. Follow up by calling either commit_proposed_batch() or delete_batch(). |
Expand Down
4 changes: 2 additions & 2 deletions e2e/tests-dfx/certificate.bash
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ setup() {

teardown() {
# Kill child processes of mitmdump. Otherwise they hang around way too long
pkill -P $MITMDUMP_PID
kill $MITMDUMP_PID
pkill -P "$MITMDUMP_PID"
kill "$MITMDUMP_PID"
Copy link
Contributor Author

@sesi200 sesi200 Mar 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requested by latest shellcheck version


dfx_stop

Expand Down
20 changes: 15 additions & 5 deletions e2e/tests-dfx/cycles-ledger.bash
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,9 @@ current_time_nanoseconds() {
}

@test "top-up and deposit-cycles" {
skip "can't be properly tested with feature flag turned off (CYCLES_LEDGER_ENABLED). TODO(SDK-1331): re-enable this test"
# shellcheck disable=SC2030,SC2031
export DFX_CYCLES_LEDGER_SUPPORT_ENABLE=1

start_and_install_nns

dfx_new
Expand Down Expand Up @@ -559,9 +561,11 @@ current_time_nanoseconds() {
}

@test "canister creation" {
# shellcheck disable=SC2030,SC2031
export DFX_CYCLES_LEDGER_SUPPORT_ENABLE=1

start_and_install_nns

skip "can't be properly tested with feature flag turned off (CYCLES_LEDGER_ENABLED). TODO(SDK-1331): re-enable this test"
dfx_new temporary
add_cycles_ledger_canisters_to_project
install_cycles_ledger_canisters
Expand Down Expand Up @@ -648,7 +652,9 @@ current_time_nanoseconds() {
}

@test "canister deletion" {
skip "can't be properly tested with feature flag turned off (CYCLES_LEDGER_ENABLED). TODO(SDK-1331): re-enable this test"
# shellcheck disable=SC2030,SC2031
export DFX_CYCLES_LEDGER_SUPPORT_ENABLE=1

start_and_install_nns

dfx_new temporary
Expand Down Expand Up @@ -725,7 +731,9 @@ current_time_nanoseconds() {
}

@test "create canister on specific subnet" {
skip "can't be properly tested with feature flag turned off (CYCLES_LEDGER_ENABLED). TODO(SDK-1331): re-enable this test"
# shellcheck disable=SC2030,SC2031
export DFX_CYCLES_LEDGER_SUPPORT_ENABLE=1

start_and_install_nns

dfx_new temporary
Expand Down Expand Up @@ -764,7 +772,9 @@ current_time_nanoseconds() {
}

@test "automatically choose subnet" {
skip "can't be properly tested with feature flag turned off (CYCLES_LEDGER_ENABLED). TODO(SDK-1331): re-enable this test"
# shellcheck disable=SC2030,SC2031
export DFX_CYCLES_LEDGER_SUPPORT_ENABLE=1

dfx_start

REGISTRY="rwlgt-iiaaa-aaaaa-aaaaa-cai"
Expand Down
3 changes: 2 additions & 1 deletion e2e/tests-dfx/error_diagnosis.bash
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ teardown() {
}

@test "Instruct user to set a wallet" {
skip "TODO(SDK-1331): remove this test"
# only passes if DFX_CYCLES_LEDGER_SUPPORT_ENABLE is not set

dfx_new hello
install_asset greet
assert_command dfx identity new alice --storage-mode plaintext
Expand Down
6 changes: 2 additions & 4 deletions src/dfx/src/commands/canister/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,11 @@ pub struct CanisterCreateOpts {

/// Transaction timestamp, in nanoseconds, for use in controlling transaction deduplication, default is system time.
/// https://internetcomputer.org/docs/current/developer-docs/integrations/icrc-1/#transaction-deduplication-
//TODO(SDK-1331): unhide
#[arg(long, hide = true, conflicts_with = "all")]
#[arg(long, conflicts_with = "all")]
created_at_time: Option<u64>,

/// Subaccount of the selected identity to spend cycles from.
//TODO(SDK-1331): unhide
#[arg(long, value_parser = icrc_subaccount_parser, hide = true)]
#[arg(long, value_parser = icrc_subaccount_parser)]
from_subaccount: Option<Subaccount>,

#[command(flatten)]
Expand Down
7 changes: 3 additions & 4 deletions src/dfx/src/commands/canister/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::lib::operations::canister::{
deposit_cycles, start_canister, stop_canister, update_settings,
};
use crate::lib::operations::cycles_ledger::{
wallet_deposit_to_cycles_ledger, CYCLES_LEDGER_ENABLED,
cycles_ledger_enabled, wallet_deposit_to_cycles_ledger,
};
use crate::lib::root_key::fetch_root_key_if_needed;
use crate::util::assets::wallet_wasm;
Expand Down Expand Up @@ -77,8 +77,7 @@ pub struct CanisterDeleteOpts {
yes: bool,

/// Subaccount of the selected identity to deposit cycles to.
//TODO(SDK-1331): unhide
#[arg(long, value_parser = icrc_subaccount_parser, hide = true)]
#[arg(long, value_parser = icrc_subaccount_parser)]
to_subaccount: Option<Subaccount>,
}

Expand Down Expand Up @@ -135,7 +134,7 @@ async fn delete_canister(
// If there is no wallet, then do not attempt to withdraw the cycles.
match wallet_canister_id(network, &identity_name)? {
Some(canister_id) => WithdrawTarget::Canister { canister_id },
None if CYCLES_LEDGER_ENABLED => {
None if cycles_ledger_enabled() => {
let Some(my_principal) = env.get_selected_identity_principal()
else {
bail!("Identity has no principal attached")
Expand Down
12 changes: 5 additions & 7 deletions src/dfx/src/commands/canister/deposit_cycles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use crate::lib::error::DfxResult;
use crate::lib::identity::wallet::get_or_create_wallet_canister;
use crate::lib::operations::canister;
use crate::lib::operations::cycles_ledger::CYCLES_LEDGER_ENABLED;
use crate::lib::operations::cycles_ledger::cycles_ledger_enabled;
use crate::lib::root_key::fetch_root_key_if_needed;
use crate::lib::{environment::Environment, operations::cycles_ledger};
use crate::util::clap::parsers::{cycle_amount_parser, icrc_subaccount_parser};
Expand Down Expand Up @@ -31,14 +31,12 @@ pub struct DepositCyclesOpts {
all: bool,

/// Use cycles from this subaccount.
//TODO(SDK-1331): unhide
#[arg(long, value_parser = icrc_subaccount_parser, hide = true)]
#[arg(long, value_parser = icrc_subaccount_parser)]
from_subaccount: Option<Subaccount>,

/// Transaction timestamp, in nanoseconds, for use in controlling transaction deduplication, default is system time.
/// https://internetcomputer.org/docs/current/developer-docs/integrations/icrc-1/#transaction-deduplication-
//TODO(SDK-1331): unhide
#[arg(long, hide = true)]
#[arg(long)]
created_at_time: Option<u64>,
}

Expand All @@ -59,7 +57,7 @@ async fn deposit_cycles(

match call_sender {
CallSender::SelectedId => {
if !CYCLES_LEDGER_ENABLED {
if !cycles_ledger_enabled() {
// should be unreachable
bail!("No wallet configured");
}
Expand Down Expand Up @@ -113,7 +111,7 @@ pub async fn exec(
call_sender = &proxy_sender;
}
Err(err) => {
if CYCLES_LEDGER_ENABLED && matches!(err, crate::lib::identity::wallet::GetOrCreateWalletCanisterError::NoWalletConfigured { .. }) {
if cycles_ledger_enabled() && matches!(err, crate::lib::identity::wallet::GetOrCreateWalletCanisterError::NoWalletConfigured { .. }) {
debug!(env.get_logger(), "No wallet configured");
} else {
bail!(err)
Expand Down
6 changes: 2 additions & 4 deletions src/dfx/src/commands/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,11 @@ pub struct DeployOpts {

/// Transaction timestamp, in nanoseconds, for use in controlling transaction deduplication, default is system time.
/// https://internetcomputer.org/docs/current/developer-docs/integrations/icrc-1/#transaction-deduplication-
//TODO(SDK-1331): unhide
#[arg(long, hide = true, requires = "canister_name")]
#[arg(long, requires = "canister_name")]
created_at_time: Option<u64>,

/// Subaccount of the selected identity to spend cycles from.
//TODO(SDK-1331): unhide
#[arg(long, value_parser = icrc_subaccount_parser, hide = true)]
#[arg(long, value_parser = icrc_subaccount_parser)]
from_subaccount: Option<Subaccount>,

#[command(flatten)]
Expand Down
2 changes: 0 additions & 2 deletions src/dfx/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ pub enum DfxCommand {
Build(build::CanisterBuildOpts),
Cache(cache::CacheOpts),
Canister(canister::CanisterOpts),
//TODO(SDK-1331): unhide
#[command(hide = true)]
Cycles(cycles::CyclesOpts),
Deploy(deploy::DeployOpts),
Deps(deps::DepsOpts),
Expand Down
4 changes: 2 additions & 2 deletions src/dfx/src/commands/wallet/redeem_faucet_coupon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::lib::diagnosis::DiagnosedError;
use crate::lib::environment::Environment;
use crate::lib::error::DfxResult;
use crate::lib::identity::wallet::set_wallet_id;
use crate::lib::operations::cycles_ledger::CYCLES_LEDGER_ENABLED;
use crate::lib::operations::cycles_ledger::cycles_ledger_enabled;
use crate::lib::root_key::fetch_root_key_if_needed;
use crate::util::{format_as_trillions, pretty_thousand_separators};
use anyhow::{anyhow, bail, Context};
Expand Down Expand Up @@ -75,7 +75,7 @@ pub async fn exec(env: &dyn Environment, opts: RedeemFaucetCouponOpts) -> DfxRes
}
// identity has no wallet yet - faucet will provide one
_ => {
if CYCLES_LEDGER_ENABLED && !opts.yes {
if cycles_ledger_enabled() && !opts.yes {
ask_for_consent("`dfx cycles` is now recommended instead of `dfx wallet`. Are you sure you want to create a new cycles wallet anyway?")?;
}
let identity = env
Expand Down
6 changes: 3 additions & 3 deletions src/dfx/src/lib/operations/canister/create_canister.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::lib::ic_attributes::CanisterSettings as DfxCanisterSettings;
use crate::lib::identity::wallet::{get_or_create_wallet_canister, GetOrCreateWalletCanisterError};
use crate::lib::ledger_types::MAINNET_CYCLE_MINTER_CANISTER_ID;
use crate::lib::operations::canister::motoko_playground::reserve_canister_with_playground;
use crate::lib::operations::cycles_ledger::{create_with_cycles_ledger, CYCLES_LEDGER_ENABLED};
use crate::lib::operations::cycles_ledger::{create_with_cycles_ledger, cycles_ledger_enabled};
use crate::util::clap::subnet_selection_opt::SubnetSelectionType;
use anyhow::{anyhow, bail, Context};
use candid::Principal;
Expand Down Expand Up @@ -138,7 +138,7 @@ The command line value will be used.",
{
Ok(wallet) => CallSender::Wallet(*wallet.canister_id_()),
Err(err) => {
if CYCLES_LEDGER_ENABLED
if cycles_ledger_enabled()
&& matches!(
err,
GetOrCreateWalletCanisterError::NoWalletConfigured { .. }
Expand All @@ -158,7 +158,7 @@ The command line value will be used.",
CallSender::SelectedId => {
let auto_wallet_disabled = std::env::var("DFX_DISABLE_AUTO_WALLET").is_ok();
let ic_network = env.get_network_descriptor().is_ic;
if CYCLES_LEDGER_ENABLED && (ic_network || auto_wallet_disabled) {
if cycles_ledger_enabled() && (ic_network || auto_wallet_disabled) {
create_with_cycles_ledger(
env,
agent,
Expand Down
Loading
Loading