diff --git a/rs/nervous_system/integration_tests/BUILD.bazel b/rs/nervous_system/integration_tests/BUILD.bazel index e85d10c5e75..bc1a77c66d3 100644 --- a/rs/nervous_system/integration_tests/BUILD.bazel +++ b/rs/nervous_system/integration_tests/BUILD.bazel @@ -176,6 +176,8 @@ rust_test_suite_with_extra_srcs( "tests/advance_target_version_upgrades_all_canisters_test.rs", "tests/upgrade_existing_sns_test.rs", "tests/deploy_fresh_sns_test.rs", + "tests/sns_release_qualification_legacy.rs", + "tests/sns_upgrade_test_utils_legacy.rs", ], ), aliases = ALIASES, @@ -259,3 +261,21 @@ rust_test( ], deps = [":nervous_system_integration_tests"] + DEPENDENCIES_WITH_TEST_FEATURES + DEV_DEPENDENCIES, ) + +rust_test( + name = "sns_release_qualification_legacy", + timeout = "long", + srcs = [ + "tests/sns_release_qualification_legacy.rs", + "tests/sns_upgrade_test_utils_legacy.rs", + ], + aliases = ALIASES, + data = DEV_DATA, + env = DEV_ENV | {"RUST_TEST_NOCAPTURE": "1"}, + flaky = True, + proc_macro_deps = MACRO_DEPENDENCIES + MACRO_DEV_DEPENDENCIES, + tags = [ + "cpu:4", + ], + deps = [":nervous_system_integration_tests"] + DEPENDENCIES_WITH_TEST_FEATURES + DEV_DEPENDENCIES, +) diff --git a/rs/nervous_system/integration_tests/src/pocket_ic_helpers.rs b/rs/nervous_system/integration_tests/src/pocket_ic_helpers.rs index d8e57c3e7f6..3da089a125f 100644 --- a/rs/nervous_system/integration_tests/src/pocket_ic_helpers.rs +++ b/rs/nervous_system/integration_tests/src/pocket_ic_helpers.rs @@ -97,7 +97,7 @@ pub fn extract_sns_canister_version( } /// Creates a new PocketIc instance with NNS and SNS and application subnet -pub async fn pocket_ic_for_sns_tests_with_mainnet_versions() -> PocketIc { +pub async fn pocket_ic_for_sns_tests_with_mainnet_versions() -> (PocketIc, SnsWasms) { let pocket_ic = PocketIcBuilder::new() .with_nns_subnet() .with_sns_subnet() @@ -105,16 +105,25 @@ pub async fn pocket_ic_for_sns_tests_with_mainnet_versions() -> PocketIc { .await; // Install the (mainnet) NNS canisters. - let with_mainnet_nns_canisters = true; - install_nns_canisters(&pocket_ic, vec![], with_mainnet_nns_canisters, None, vec![]).await; + { + let with_mainnet_nns_canisters = true; + install_nns_canisters(&pocket_ic, vec![], with_mainnet_nns_canisters, None, vec![]).await; + } // Publish (mainnet) SNS Wasms to SNS-W. - let with_mainnet_sns_wasms = true; - add_wasms_to_sns_wasm(&pocket_ic, with_mainnet_sns_wasms) - .await - .unwrap(); + let initial_sns_version = { + let with_mainnet_sns_canisters = true; + let deployed_sns_starting_info = + add_wasms_to_sns_wasm(&pocket_ic, with_mainnet_sns_canisters) + .await + .unwrap(); + deployed_sns_starting_info + .into_iter() + .map(|(canister_type, (_, wasm))| (canister_type, wasm)) + .collect::>() + }; - pocket_ic + (pocket_ic, initial_sns_version) } pub async fn install_canister( diff --git a/rs/nervous_system/integration_tests/tests/deploy_fresh_sns_test.rs b/rs/nervous_system/integration_tests/tests/deploy_fresh_sns_test.rs index 5dedba2dd25..67da040bc05 100644 --- a/rs/nervous_system/integration_tests/tests/deploy_fresh_sns_test.rs +++ b/rs/nervous_system/integration_tests/tests/deploy_fresh_sns_test.rs @@ -34,7 +34,8 @@ async fn test_deploy_fresh_sns() { .collect(); eprintln!("1. Prepare the world (use mainnet WASMs for all NNS and SNS canisters) ..."); - let pocket_ic = pocket_ic_helpers::pocket_ic_for_sns_tests_with_mainnet_versions().await; + let (pocket_ic, _initial_sns_version) = + pocket_ic_helpers::pocket_ic_for_sns_tests_with_mainnet_versions().await; eprintln!("Install the test dapp ..."); for dapp_canister_id in dapp_canister_ids.clone() { diff --git a/rs/nervous_system/integration_tests/tests/sns_release_qualification.rs b/rs/nervous_system/integration_tests/tests/sns_release_qualification.rs index 07c69334801..e6acae37821 100644 --- a/rs/nervous_system/integration_tests/tests/sns_release_qualification.rs +++ b/rs/nervous_system/integration_tests/tests/sns_release_qualification.rs @@ -85,8 +85,6 @@ async fn test_deployment_swap_upgrade() { /// Upgrade Tests -// TODO[NNS1-3433]: Enable this test after the SNS Governance canister published to SNS-W on mainnet -// TODO[NNS1-3433]: starts upgrading its Swap. #[ignore] #[tokio::test] async fn test_upgrade_swap() { @@ -110,7 +108,8 @@ pub async fn test_sns_deployment( nns_canisters_to_upgrade: Vec, // should use constants from nns/constants to make this easy to track sns_canisters_to_upgrade: Vec, ) { - let pocket_ic = pocket_ic_helpers::pocket_ic_for_sns_tests_with_mainnet_versions().await; + let (pocket_ic, _initial_sns_version) = + pocket_ic_helpers::pocket_ic_for_sns_tests_with_mainnet_versions().await; let create_service_nervous_system = CreateServiceNervousSystemBuilder::default() .with_governance_parameters_neuron_minimum_dissolve_delay_to_vote(ONE_MONTH_SECONDS * 6) diff --git a/rs/nervous_system/integration_tests/tests/sns_release_qualification_legacy.rs b/rs/nervous_system/integration_tests/tests/sns_release_qualification_legacy.rs new file mode 100644 index 00000000000..2445eae7617 --- /dev/null +++ b/rs/nervous_system/integration_tests/tests/sns_release_qualification_legacy.rs @@ -0,0 +1,21 @@ +use ic_sns_wasm::pb::v1::SnsCanisterType; + +mod sns_upgrade_test_utils_legacy; +use sns_upgrade_test_utils_legacy::test_sns_upgrade_legacy; + +/// Legacy upgrade Tests +/// +#[tokio::test] +async fn test_upgrade_swap() { + test_sns_upgrade_legacy(vec![SnsCanisterType::Swap]).await; +} + +#[tokio::test] +async fn test_upgrade_sns_gov_root() { + test_sns_upgrade_legacy(vec![SnsCanisterType::Root, SnsCanisterType::Governance]).await; +} + +#[tokio::test] +async fn test_upgrade_upgrade_sns_gov_root() { + test_sns_upgrade_legacy(vec![SnsCanisterType::Governance, SnsCanisterType::Root]).await; +} diff --git a/rs/nervous_system/integration_tests/tests/sns_upgrade_test_utils.rs b/rs/nervous_system/integration_tests/tests/sns_upgrade_test_utils.rs index d7f831d8678..a39fc395e2b 100644 --- a/rs/nervous_system/integration_tests/tests/sns_upgrade_test_utils.rs +++ b/rs/nervous_system/integration_tests/tests/sns_upgrade_test_utils.rs @@ -3,18 +3,20 @@ use ic_nervous_system_common::ONE_MONTH_SECONDS; use ic_nervous_system_integration_tests::{ create_service_nervous_system_builder::CreateServiceNervousSystemBuilder, pocket_ic_helpers, - pocket_ic_helpers::{add_wasm_via_nns_proposal, nns, sns}, -}; -use ic_nns_test_utils::sns_wasm::{ - build_archive_sns_wasm, build_governance_sns_wasm, build_index_ng_sns_wasm, - build_ledger_sns_wasm, build_root_sns_wasm, build_swap_sns_wasm, create_modified_sns_wasm, - ensure_sns_wasm_gzipped, + pocket_ic_helpers::{ + await_with_timeout, hash_sns_wasms, nns, sns, + sns::governance::{ + EXPECTED_UPGRADE_DURATION_MAX_SECONDS, EXPECTED_UPGRADE_STEPS_REFRESH_MAX_SECONDS, + }, + }, }; +use ic_sns_governance::governance::UPGRADE_STEPS_INTERVAL_REFRESH_BACKOFF_SECONDS; use ic_sns_swap::pb::v1::Lifecycle; use ic_sns_wasm::pb::v1::SnsCanisterType; pub async fn test_sns_upgrade(sns_canisters_to_upgrade: Vec) { - let pocket_ic = pocket_ic_helpers::pocket_ic_for_sns_tests_with_mainnet_versions().await; + let (pocket_ic, initial_sns_version) = + pocket_ic_helpers::pocket_ic_for_sns_tests_with_mainnet_versions().await; eprintln!("Creating SNS ..."); let create_service_nervous_system = CreateServiceNervousSystemBuilder::default() @@ -40,51 +42,6 @@ pub async fn test_sns_upgrade(sns_canisters_to_upgrade: Vec) { ) .await; - eprintln!("Adding all WASMs ..."); - for canister_type in &sns_canisters_to_upgrade { - let wasm = match canister_type { - SnsCanisterType::Root => build_root_sns_wasm(), - SnsCanisterType::Governance => build_governance_sns_wasm(), - SnsCanisterType::Ledger => build_ledger_sns_wasm(), - SnsCanisterType::Swap => build_swap_sns_wasm(), - SnsCanisterType::Index => build_index_ng_sns_wasm(), - SnsCanisterType::Unspecified => { - panic!("Where did you get this canister type from?") - } - SnsCanisterType::Archive => build_archive_sns_wasm(), - }; - - let wasm = ensure_sns_wasm_gzipped(wasm); - let proposal_info = add_wasm_via_nns_proposal(&pocket_ic, wasm).await.unwrap(); - assert_eq!(proposal_info.failure_reason, None); - } - - eprintln!("Adding all WASMs with custom metadata ..."); - for canister_type in &sns_canisters_to_upgrade { - let wasm = match canister_type { - // Second upgrade with modified wasms - SnsCanisterType::Root => create_modified_sns_wasm(&build_root_sns_wasm(), Some(42)), - SnsCanisterType::Governance => { - create_modified_sns_wasm(&build_governance_sns_wasm(), Some(42)) - } - SnsCanisterType::Ledger => create_modified_sns_wasm(&build_ledger_sns_wasm(), Some(42)), - SnsCanisterType::Swap => create_modified_sns_wasm(&build_swap_sns_wasm(), Some(42)), - SnsCanisterType::Index => { - create_modified_sns_wasm(&build_index_ng_sns_wasm(), Some(42)) - } - SnsCanisterType::Unspecified => { - panic!("Where did you get this canister type from?") - } - SnsCanisterType::Archive => { - create_modified_sns_wasm(&build_archive_sns_wasm(), Some(42)) - } - }; - - let wasm = ensure_sns_wasm_gzipped(wasm); - let proposal_info = add_wasm_via_nns_proposal(&pocket_ic, wasm).await.unwrap(); - assert_eq!(proposal_info.failure_reason, None); - } - // Only spawn an archive if we're testing it if sns_canisters_to_upgrade.contains(&SnsCanisterType::Archive) { eprintln!("Testing if the Archive canister is spawned ..."); @@ -109,19 +66,62 @@ pub async fn test_sns_upgrade(sns_canisters_to_upgrade: Vec) { ) .await; - // Every canister we are testing has two upgrades. We are just making sure the counts match - for canister_type in &sns_canisters_to_upgrade { - eprintln!( - "1st upgrade_sns_to_next_version_and_assert_change {:?} ...", - canister_type - ); - sns::upgrade_sns_to_next_version_and_assert_change(&pocket_ic, &sns, *canister_type).await; - } - for canister_type in sns_canisters_to_upgrade { - eprintln!( - "2nd upgrade_sns_to_next_version_and_assert_change {:?} ...", - canister_type - ); - sns::upgrade_sns_to_next_version_and_assert_change(&pocket_ic, &sns, canister_type).await; + let mut latest_sns_version = initial_sns_version; + + for upgrade_pass in 0..2 { + eprintln!("Upgrade pass {}", upgrade_pass); + + eprintln!("Adding all WASMs ..."); + for canister_type in &sns_canisters_to_upgrade { + eprintln!("modify_and_add_wasm for {:?} ...", canister_type); + latest_sns_version = nns::sns_wasm::modify_and_add_wasm( + &pocket_ic, + latest_sns_version, + *canister_type, + upgrade_pass, + ) + .await; + } + + eprintln!("wait for the upgrade steps to be refreshed ..."); + let latest_sns_version_hash = hash_sns_wasms(&latest_sns_version); + await_with_timeout( + &pocket_ic, + UPGRADE_STEPS_INTERVAL_REFRESH_BACKOFF_SECONDS + ..EXPECTED_UPGRADE_STEPS_REFRESH_MAX_SECONDS, + |pocket_ic| async { + sns::governance::try_get_upgrade_journal(pocket_ic, sns.governance.canister_id) + .await + .ok() + .and_then(|journal| journal.upgrade_steps) + .and_then(|upgrade_steps| upgrade_steps.versions.last().cloned()) + }, + &Some(latest_sns_version_hash.clone()), + ) + .await + .unwrap(); + + eprintln!("advance the target version to the latest version. ..."); + sns::governance::propose_to_advance_sns_target_version( + &pocket_ic, + sns.governance.canister_id, + ) + .await + .unwrap(); + + eprintln!("wait for the upgrade to happen ..."); + await_with_timeout( + &pocket_ic, + 0..EXPECTED_UPGRADE_DURATION_MAX_SECONDS, + |pocket_ic| async { + let journal = + sns::governance::try_get_upgrade_journal(pocket_ic, sns.governance.canister_id) + .await; + journal.ok().and_then(|journal| journal.deployed_version) + }, + &Some(latest_sns_version_hash.clone()), + ) + .await + .unwrap(); } } diff --git a/rs/nervous_system/integration_tests/tests/sns_upgrade_test_utils_legacy.rs b/rs/nervous_system/integration_tests/tests/sns_upgrade_test_utils_legacy.rs new file mode 100644 index 00000000000..8feb2a9b320 --- /dev/null +++ b/rs/nervous_system/integration_tests/tests/sns_upgrade_test_utils_legacy.rs @@ -0,0 +1,129 @@ +use ic_base_types::PrincipalId; +use ic_nervous_system_common::ONE_MONTH_SECONDS; +use ic_nervous_system_integration_tests::{ + create_service_nervous_system_builder::CreateServiceNervousSystemBuilder, + pocket_ic_helpers, + pocket_ic_helpers::{add_wasm_via_nns_proposal, nns, sns}, +}; +use ic_nns_test_utils::sns_wasm::{ + build_archive_sns_wasm, build_governance_sns_wasm, build_index_ng_sns_wasm, + build_ledger_sns_wasm, build_root_sns_wasm, build_swap_sns_wasm, create_modified_sns_wasm, + ensure_sns_wasm_gzipped, +}; +use ic_sns_swap::pb::v1::Lifecycle; +use ic_sns_wasm::pb::v1::SnsCanisterType; + +/// Tests upgrading SNS canisters to the master version, using the legacy UpgradeSnsToNextVersion proposals +pub async fn test_sns_upgrade_legacy(sns_canisters_to_upgrade: Vec) { + let (pocket_ic, _initial_sns_version) = + pocket_ic_helpers::pocket_ic_for_sns_tests_with_mainnet_versions().await; + + eprintln!("Creating SNS ..."); + let create_service_nervous_system = CreateServiceNervousSystemBuilder::default() + .with_governance_parameters_neuron_minimum_dissolve_delay_to_vote(ONE_MONTH_SECONDS * 6) + .with_one_developer_neuron( + PrincipalId::new_user_test_id(830947), + ONE_MONTH_SECONDS * 6, + 756575, + 0, + ) + .build(); + let swap_parameters = create_service_nervous_system + .swap_parameters + .clone() + .unwrap(); + + eprintln!("Deploying an SNS instance via proposal ..."); + let sns_instance_label = "1"; + let (sns, _) = nns::governance::propose_to_deploy_sns_and_wait( + &pocket_ic, + create_service_nervous_system, + sns_instance_label, + ) + .await; + + eprintln!("Adding all WASMs ..."); + for canister_type in &sns_canisters_to_upgrade { + let wasm = match canister_type { + SnsCanisterType::Root => build_root_sns_wasm(), + SnsCanisterType::Governance => build_governance_sns_wasm(), + SnsCanisterType::Ledger => build_ledger_sns_wasm(), + SnsCanisterType::Swap => build_swap_sns_wasm(), + SnsCanisterType::Index => build_index_ng_sns_wasm(), + SnsCanisterType::Unspecified => { + panic!("Where did you get this canister type from?") + } + SnsCanisterType::Archive => build_archive_sns_wasm(), + }; + + let wasm = ensure_sns_wasm_gzipped(wasm); + let proposal_info = add_wasm_via_nns_proposal(&pocket_ic, wasm).await.unwrap(); + assert_eq!(proposal_info.failure_reason, None); + } + + eprintln!("Adding all WASMs with custom metadata ..."); + for canister_type in &sns_canisters_to_upgrade { + let wasm = match canister_type { + // Second upgrade with modified wasms + SnsCanisterType::Root => create_modified_sns_wasm(&build_root_sns_wasm(), Some(42)), + SnsCanisterType::Governance => { + create_modified_sns_wasm(&build_governance_sns_wasm(), Some(42)) + } + SnsCanisterType::Ledger => create_modified_sns_wasm(&build_ledger_sns_wasm(), Some(42)), + SnsCanisterType::Swap => create_modified_sns_wasm(&build_swap_sns_wasm(), Some(42)), + SnsCanisterType::Index => { + create_modified_sns_wasm(&build_index_ng_sns_wasm(), Some(42)) + } + SnsCanisterType::Unspecified => { + panic!("Where did you get this canister type from?") + } + SnsCanisterType::Archive => { + create_modified_sns_wasm(&build_archive_sns_wasm(), Some(42)) + } + }; + + let wasm = ensure_sns_wasm_gzipped(wasm); + let proposal_info = add_wasm_via_nns_proposal(&pocket_ic, wasm).await.unwrap(); + assert_eq!(proposal_info.failure_reason, None); + } + + // Only spawn an archive if we're testing it + if sns_canisters_to_upgrade.contains(&SnsCanisterType::Archive) { + eprintln!("Testing if the Archive canister is spawned ..."); + sns::ensure_archive_canister_is_spawned_or_panic( + &pocket_ic, + sns.governance.canister_id, + sns.ledger.canister_id, + ) + .await; + } + + eprintln!("Await the swap lifecycle ..."); + sns::swap::await_swap_lifecycle(&pocket_ic, sns.swap.canister_id, Lifecycle::Open) + .await + .unwrap(); + + eprintln!("smoke_test_participate_and_finalize ..."); + sns::swap::smoke_test_participate_and_finalize( + &pocket_ic, + sns.swap.canister_id, + swap_parameters, + ) + .await; + + // Every canister we are testing has two upgrades. We are just making sure the counts match + for canister_type in &sns_canisters_to_upgrade { + eprintln!( + "1st upgrade_sns_to_next_version_and_assert_change {:?} ...", + canister_type + ); + sns::upgrade_sns_to_next_version_and_assert_change(&pocket_ic, &sns, *canister_type).await; + } + for canister_type in sns_canisters_to_upgrade { + eprintln!( + "2nd upgrade_sns_to_next_version_and_assert_change {:?} ...", + canister_type + ); + sns::upgrade_sns_to_next_version_and_assert_change(&pocket_ic, &sns, canister_type).await; + } +}