Skip to content

Commit

Permalink
feat: configure PocketIC SNS and PocketIC default subnet in NNS canis…
Browse files Browse the repository at this point in the history
…ters (#160)

* feat: configure PocketIC SNS and default subnet in NNS canisters

* changelog

* fix

* fix
  • Loading branch information
mraszyk authored Nov 18, 2024
1 parent bc34481 commit 1d3cc48
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
- name: Install IC SDK (dfx)
uses: dfinity/setup-dfx@main
with:
dfx-version: "0.24.1"
dfx-version: "0.24.2"
- name: Set prebuilt extensions directory
run: echo "PREBUILT_EXTENSIONS_DIR=$HOME/prebuilt-extensions" >> $GITHUB_ENV
- name: Build extension manually
Expand Down
32 changes: 31 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ fn-error-context = "0.2.1"
futures-util = "0.3.28"
ic-agent = "=0.38.0"
ic-utils = "=0.38.0"
pocket-ic = "6.0.0"
reqwest = { version = "^0.11.22", default-features = false, features = [
"blocking",
"json",
Expand Down
1 change: 1 addition & 0 deletions extensions/nns/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## [Unreleased] - ReleaseDate
- Fixed a bug where `dfx nns install` and `dfx nns import` would fail if a canister type in dfx.json was defined by an extension.
- Added support for application subnets for `dfx start --pocketic`.
- Configure the PocketIC SNS subnet in the SNS-W canister and the default subnet in the CMC canister.

## [0.4.7] - 2024-11-08
- Added support for `dfx start --pocketic`.
Expand Down
1 change: 1 addition & 0 deletions extensions/nns/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ ic-icrc1-index-ng.workspace = true
ic-icrc1-ledger.workspace = true
ic-http-utils.workspace = true
hex = "0.4.3"
pocket-ic.workspace = true
reqwest.workspace = true
rust_decimal = "1.29.1"
serde.workspace = true
Expand Down
31 changes: 25 additions & 6 deletions extensions/nns/e2e/tests/nns.bash
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,30 @@ assert_nns_canister_id_matches() {
if [[ "$USE_POCKET_IC" ]]
then
assert_success

SNS_SUBNET_ID=$(curl http://localhost:8080/_/topology | jq -r '.subnet_configs | map_values(select(.subnet_kind=="SNS")) | keys[]')
if [[ "${SNS_SUBNET_ID}" == "" ]]
then
echo "No SNS subnet found in the PocketIC instance topology."
exit 1
fi
run dfx canister call qaa6y-5yaaa-aaaaa-aaafa-cai get_sns_subnet_ids '(record {})' --query
assert_success
assert_output --partial "${SNS_SUBNET_ID}"

APP_SUBNET_ID=$(curl http://localhost:8080/_/topology | jq -r '.subnet_configs | map_values(select(.subnet_kind=="Application")) | keys[]')
if [[ "${APP_SUBNET_ID}" == "" ]]
then
echo "No application subnet found in the PocketIC instance topology."
exit 1
fi
while [[ "$(dfx canister call rkp4c-7iaaa-aaaaa-aaaca-cai get_default_subnets '()' --query | grep "${APP_SUBNET_ID}")" == "" ]]
do
sleep 1
done
run dfx canister call rkp4c-7iaaa-aaaaa-aaaca-cai get_default_subnets '()' --query
assert_success
assert_output --partial "${APP_SUBNET_ID}"
else
assert_failure
assert_output --partial "The replica subnet_type needs to be 'system' to run NNS canisters."
Expand Down Expand Up @@ -181,12 +205,7 @@ assert_nns_canister_id_matches() {
run dfx --identity ident-1 canister call rkp4c-7iaaa-aaaaa-aaaca-cai notify_mint_cycles '(record { block_index = 5 : nat64; })'
# If cycles ledger is configured correctly, then notify_mint_cycles will try to call the cycles ledger (and fail because the canister is not even created).
# If it is not configured correctly, then this will complain about the cycles ledger canister id not being configured.
if [ "$USE_POCKET_IC" ]
then
assert_output --partial "No route to canister um5iw-rqaaa-aaaaq-qaaba-cai"
else
assert_output --partial "Canister um5iw-rqaaa-aaaaq-qaaba-cai not found"
fi
assert_output --partial "Canister um5iw-rqaaa-aaaaq-qaaba-cai not found"
}

@test "dfx nns install with a canister type defined by another extension" {
Expand Down
38 changes: 28 additions & 10 deletions extensions/nns/src/install_nns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use ic_icrc1_index_ng::{IndexArg, InitArg as IndexInitArg};
use ic_icrc1_ledger::{InitArgsBuilder, LedgerArgument};
use ic_utils::interfaces::management_canister::builders::InstallMode;
use ic_utils::interfaces::ManagementCanister;
use pocket_ic::common::rest::Topology;
use reqwest::Url;
use serde::Serialize;
use sha2::{Digest, Sha256};
Expand Down Expand Up @@ -89,23 +90,40 @@ pub async fn install_nns(
logger: &Logger,
) -> anyhow::Result<()> {
eprintln!("Checking out the environment...");
// check if we're talking to PocketIC defaulting to false if we aren't sure
let is_pocketic = if let Some(descriptor) = &network.local_server_descriptor {
// PocketIC server has `/_/topology` endpoint while the replica does not
// Retrieve the PocketIC instance topology.
let topology = if let Some(descriptor) = &network.local_server_descriptor {
let endpoint = format!("http://{}/_/topology", descriptor.bind_address);
let status = reqwest::get(endpoint).await?.status();
status.is_success()
let resp = reqwest::get(endpoint).await?;
if resp.status().is_success() {
Some(resp.json::<Topology>().await?)
} else {
None
}
} else {
false
None
};
// PocketIC has multiple subnets and thus supports default application subnet type.
if !is_pocketic {
if topology.is_none() {
verify_local_replica_type_is_system(network, networks_config)?;
}
verify_nns_canister_ids_are_available(agent).await?;
let provider_url = get_and_check_provider(network)?;
let nns_url = provider_url.clone();
let subnet_id = get_subnet_id(agent).await?.to_text();
let root_subnet_id = get_subnet_id(agent).await?;
let sns_subnet_id = topology
.as_ref()
.and_then(|topology| topology.get_sns())
.unwrap_or(root_subnet_id);
let default_subnet_id = topology
.as_ref()
.and_then(|topology| {
topology
.get_app_subnets()
.first()
.cloned()
.or_else(|| topology.get_system_subnets().first().cloned())
})
.unwrap_or(root_subnet_id);

eprintln!("Installing the core backend wasm canisters...");
download_nns_wasms(dfx_cache_path).await?;
Expand All @@ -118,7 +136,7 @@ pub async fn install_nns(
wasm_dir: nns_wasm_dir(dfx_cache_path),
nns_url: nns_url.to_string(),
test_accounts,
sns_subnets: Some(subnet_id.to_string()),
sns_subnets: Some(sns_subnet_id.to_string()),
local_registry_file: network.local_server_descriptor.as_ref().map(|desc| {
desc.data_dir_by_settings_digest()
.join("state/replicated_state/registry.proto")
Expand Down Expand Up @@ -240,7 +258,7 @@ pub async fn install_nns(
// ... and configure the backend NNS canisters:
eprintln!("Configuring the NNS...");
set_xdr_rate(1234567, &nns_url, dfx_cache_path)?;
set_cmc_authorized_subnets(&nns_url, &subnet_id, dfx_cache_path)?;
set_cmc_authorized_subnets(&nns_url, &default_subnet_id.to_string(), dfx_cache_path)?;
set_cycles_ledger_canister_id_in_cmc(&nns_url, dfx_cache_path)?;

print_nns_details(provider_url)?;
Expand Down

0 comments on commit 1d3cc48

Please sign in to comment.