diff --git a/candid/governance.did b/candid/governance.did index 7b3afa05..b80b3465 100644 --- a/candid/governance.did +++ b/candid/governance.did @@ -1,5 +1,6 @@ type AccountIdentifier = record { hash : vec nat8 }; type Action = variant { + RegisterKnownNeuron : KnownNeuron; ManageNeuron : ManageNeuron; ExecuteNnsFunction : ExecuteNnsFunction; RewardNodeProvider : RewardNodeProvider; @@ -57,8 +58,9 @@ type Command_1 = variant { Disburse : DisburseResponse; }; type Command_2 = variant { - Spawn : Spawn; + Spawn : NeuronId; Split : Split; + Configure : Configure; Merge : Merge; DisburseToNeuron : DisburseToNeuron; ClaimOrRefreshNeuron : ClaimOrRefresh; @@ -87,9 +89,14 @@ type Follow = record { topic : int32; followees : vec NeuronId }; type Followees = record { followees : vec NeuronId }; type Governance = record { default_followees : vec record { int32; Followees }; + most_recent_monthly_node_provider_rewards : opt MostRecentMonthlyNodeProviderRewards; + maturity_modulation_last_updated_at_timestamp_seconds : opt nat64; wait_for_quiet_threshold_seconds : nat64; + metrics : opt GovernanceCachedMetrics; node_providers : vec NodeProvider; + cached_daily_maturity_modulation_basis_points : opt int32; economics : opt NetworkEconomics; + spawning_neurons : opt bool; latest_reward_event : opt RewardEvent; to_claim_transfers : vec NeuronStakeTransfer; short_voting_period_seconds : nat64; @@ -98,11 +105,34 @@ type Governance = record { neurons : vec record { nat64; Neuron }; genesis_timestamp_seconds : nat64; }; +type GovernanceCachedMetrics = record { + not_dissolving_neurons_e8s_buckets : vec record { nat64; float64 }; + garbage_collectable_neurons_count : nat64; + neurons_with_invalid_stake_count : nat64; + not_dissolving_neurons_count_buckets : vec record { nat64; nat64 }; + total_supply_icp : nat64; + neurons_with_less_than_6_months_dissolve_delay_count : nat64; + dissolved_neurons_count : nat64; + total_staked_e8s : nat64; + not_dissolving_neurons_count : nat64; + dissolved_neurons_e8s : nat64; + neurons_with_less_than_6_months_dissolve_delay_e8s : nat64; + dissolving_neurons_count_buckets : vec record { nat64; nat64 }; + dissolving_neurons_count : nat64; + dissolving_neurons_e8s_buckets : vec record { nat64; float64 }; + community_fund_total_staked_e8s : nat64; + timestamp_seconds : nat64; +}; type GovernanceError = record { error_message : text; error_type : int32 }; type IncreaseDissolveDelay = record { additional_dissolve_delay_seconds : nat32; }; -type JoinCommunityFund = record {}; +type KnownNeuron = record { + id : opt NeuronId; + known_neuron_data : opt KnownNeuronData; +}; +type KnownNeuronData = record { name : text; description : opt text }; +type ListKnownNeuronsResponse = record { known_neurons : vec KnownNeuron }; type ListNeurons = record { neuron_ids : vec nat64; include_neurons_readable_by_caller : bool; @@ -111,6 +141,7 @@ type ListNeuronsResponse = record { neuron_infos : vec record { nat64; NeuronInfo }; full_neurons : vec Neuron; }; +type ListNodeProvidersResponse = record { node_providers : vec NodeProvider }; type ListProposalInfo = record { include_reward_status : vec int32; before_proposal : opt NeuronId; @@ -132,6 +163,10 @@ type MergeMaturityResponse = record { merged_maturity_e8s : nat64; new_stake_e8s : nat64; }; +type MostRecentMonthlyNodeProviderRewards = record { + timestamp : nat64; + rewards : vec RewardNodeProvider; +}; type Motion = record { motion_text : text }; type NetworkEconomics = record { neuron_minimum_stake_e8s : nat64; @@ -155,10 +190,13 @@ type Neuron = record { aging_since_timestamp_seconds : nat64; hot_keys : vec principal; account : vec nat8; + joined_community_fund_timestamp_seconds : opt nat64; dissolve_state : opt DissolveState; followees : vec record { int32; Followees }; neuron_fees_e8s : nat64; transfer : opt NeuronStakeTransfer; + known_neuron_data : opt KnownNeuronData; + spawn_at_timestamp_seconds : opt nat64; }; type NeuronId = record { id : nat64 }; type NeuronIdOrSubaccount = variant { @@ -175,7 +213,9 @@ type NeuronInfo = record { created_timestamp_seconds : nat64; state : int32; stake_e8s : nat64; + joined_community_fund_timestamp_seconds : opt nat64; retrieved_at_timestamp_seconds : nat64; + known_neuron_data : opt KnownNeuronData; voting_power : nat64; age_seconds : nat64; }; @@ -188,17 +228,26 @@ type NeuronStakeTransfer = record { transfer_timestamp : nat64; block_height : nat64; }; -type NodeProvider = record { id : opt principal }; +type NodeProvider = record { + id : opt principal; + reward_account : opt AccountIdentifier; +}; type Operation = variant { RemoveHotKey : RemoveHotKey; AddHotKey : AddHotKey; StopDissolving : record {}; StartDissolving : record {}; IncreaseDissolveDelay : IncreaseDissolveDelay; + JoinCommunityFund : record {}; + LeaveCommunityFund : record {}; SetDissolveTimestamp : SetDissolveTimestamp; - JoinCommunityFund: JoinCommunityFund; }; -type Proposal = record { url : text; action : opt Action; summary : text }; +type Proposal = record { + url : text; + title : opt text; + action : opt Action; + summary : text; +}; type ProposalData = record { id : opt NeuronId; failure_reason : opt GovernanceError; @@ -211,6 +260,7 @@ type ProposalData = record { decided_timestamp_seconds : nat64; proposal : opt Proposal; proposer : opt NeuronId; + wait_for_quiet_state : opt WaitForQuietState; executed_timestamp_seconds : nat64; }; type ProposalInfo = record { @@ -221,6 +271,7 @@ type ProposalInfo = record { ballots : vec record { nat64; Ballot }; proposal_timestamp_seconds : nat64; reward_event_round : nat64; + deadline_timestamp_seconds : opt nat64; failed_timestamp_seconds : nat64; reject_cost_e8s : nat64; latest_tally : opt Tally; @@ -235,7 +286,9 @@ type RemoveHotKey = record { hot_key_to_remove : opt principal }; type Result = variant { Ok; Err : GovernanceError }; type Result_1 = variant { Error : GovernanceError; NeuronId : NeuronId }; type Result_2 = variant { Ok : Neuron; Err : GovernanceError }; -type Result_3 = variant { Ok : NeuronInfo; Err : GovernanceError }; +type Result_3 = variant { Ok : RewardNodeProviders; Err : GovernanceError }; +type Result_4 = variant { Ok : NeuronInfo; Err : GovernanceError }; +type Result_5 = variant { Ok : NodeProvider; Err : GovernanceError }; type RewardEvent = record { day_after_genesis : nat64; actual_timestamp_seconds : nat64; @@ -251,14 +304,21 @@ type RewardNodeProvider = record { reward_mode : opt RewardMode; amount_e8s : nat64; }; -type RewardNodeProviders = record { rewards : vec RewardNodeProvider }; +type RewardNodeProviders = record { + use_registry_derived_rewards : opt bool; + rewards : vec RewardNodeProvider; +}; type RewardToAccount = record { to_account : opt AccountIdentifier }; type RewardToNeuron = record { dissolve_delay_seconds : nat64 }; type SetDefaultFollowees = record { default_followees : vec record { int32; Followees }; }; type SetDissolveTimestamp = record { dissolve_timestamp_seconds : nat64 }; -type Spawn = record { new_controller : opt principal }; +type Spawn = record { + percentage_to_spawn : opt nat32; + new_controller : opt principal; + nonce : opt nat64; +}; type SpawnResponse = record { created_neuron_id : opt NeuronId }; type Split = record { amount_e8s : nat64 }; type Tally = record { @@ -268,17 +328,33 @@ type Tally = record { timestamp_seconds : nat64; }; type UpdateNodeProvider = record { reward_account : opt AccountIdentifier }; +type WaitForQuietState = record { current_deadline_timestamp_seconds : nat64 }; service : (Governance) -> { claim_gtc_neurons : (principal, vec NeuronId) -> (Result); claim_or_refresh_neuron_from_account : (ClaimOrRefreshNeuronFromAccount) -> ( ClaimOrRefreshNeuronFromAccountResponse, ); + get_build_metadata : () -> (text) query; get_full_neuron : (nat64) -> (Result_2) query; + get_full_neuron_by_id_or_subaccount : (NeuronIdOrSubaccount) -> ( + Result_2, + ) query; + get_monthly_node_provider_rewards : () -> (Result_3); + get_most_recent_monthly_node_provider_rewards : () -> ( + opt MostRecentMonthlyNodeProviderRewards, + ) query; + get_network_economics_parameters : () -> (NetworkEconomics) query; get_neuron_ids : () -> (vec nat64) query; - get_neuron_info : (nat64) -> (Result_3) query; + get_neuron_info : (nat64) -> (Result_4) query; + get_neuron_info_by_id_or_subaccount : (NeuronIdOrSubaccount) -> ( + Result_4, + ) query; + get_node_provider_by_caller : (null) -> (Result_5) query; get_pending_proposals : () -> (vec ProposalInfo) query; get_proposal_info : (nat64) -> (opt ProposalInfo) query; + list_known_neurons : () -> (ListKnownNeuronsResponse) query; list_neurons : (ListNeurons) -> (ListNeuronsResponse) query; + list_node_providers : () -> (ListNodeProvidersResponse) query; list_proposals : (ListProposalInfo) -> (ListProposalInfoResponse) query; manage_neuron : (ManageNeuron) -> (ManageNeuronResponse); transfer_gtc_neuron : (NeuronId, NeuronId) -> (Result); diff --git a/e2e/tests-quill/create_neuron.bash b/e2e/tests-quill/create_neuron.bash index aeb42d87..766e43b3 100644 --- a/e2e/tests-quill/create_neuron.bash +++ b/e2e/tests-quill/create_neuron.bash @@ -11,7 +11,7 @@ teardown() { @test "basic create neuron" { #account is initialized with 10_000 tokens assert_command quill account-balance 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 --yes --insecure-local-dev-mode - assert_string_match '(record { e8s = 1_000_000_000_000 : nat64 })' + assert_string_match '(record { e8s = 100_000_000_000_000_000 : nat64 })' # stake 3 tokens assert_command bash -c "quill neuron-stake --amount 3 --name myneur --pem-file $PEM_LOCATION/identity.pem > stake.call" diff --git a/e2e/utils/setup_nns.bash b/e2e/utils/setup_nns.bash index 4f2cf80e..9b034f1f 100755 --- a/e2e/utils/setup_nns.bash +++ b/e2e/utils/setup_nns.bash @@ -1,6 +1,6 @@ #! /bin/bash -IC_COMMIT="b90edb9897718730f65e92eb4ff6057b1b25f766" +IC_COMMIT="999f7cc6bbe17abdb7b7a1eab73840a94597e363" if [[ -z "${DOWNLOAD_DIR}" ]]; then DOWNLOAD_DIR=$(mktemp -d -t dfx-e2e-XXXXXXXX) @@ -62,10 +62,13 @@ get_wasm lifeline.wasm get_wasm genesis-token-canister.wasm get_wasm identity-canister.wasm get_wasm nns-ui-canister.wasm +get_wasm sns-wasm-canister.wasm +get_wasm ic-icrc1-ledger.wasm NNS_URL="http://localhost:$(cat .dfx/replica-configuration/replica-1.port)" "${DOWNLOAD_DIR}/ic-nns-init" \ --url "$NNS_URL" \ --initialize-ledger-with-test-accounts 345f723e9e619934daac6ae0f4be13a7b0ba57d6a608e511a00fd0ded5866752 22ca7edac648b814e81d7946e8bacea99280e07c5f51a04ba7a38009d8ad8e89 76374de112443a5415f4bef978091a622b8f41035c99147abc1471fd99635661 \ - --wasm-dir "$DOWNLOAD_DIR" \ No newline at end of file + --wasm-dir "$DOWNLOAD_DIR" + \ No newline at end of file diff --git a/src/commands/neuron_manage.rs b/src/commands/neuron_manage.rs index 169f740b..8912505d 100644 --- a/src/commands/neuron_manage.rs +++ b/src/commands/neuron_manage.rs @@ -49,6 +49,9 @@ pub struct AddHotKey { #[derive(CandidType)] pub struct JoinCommunityFund {} +#[derive(CandidType)] +pub struct LeaveCommunityFund {} + #[derive(CandidType)] pub struct ProposalId { pub id: u64, @@ -68,6 +71,7 @@ pub enum Operation { AddHotKey(AddHotKey), IncreaseDissolveDelay(IncreaseDissolveDelay), JoinCommunityFund(JoinCommunityFund), + LeaveCommunityFund(LeaveCommunityFund), } #[derive(CandidType)] @@ -180,10 +184,14 @@ pub struct ManageOpts { #[clap(long)] merge_maturity: Option, - /// Join the Internet Computer's community fund with this neuron's entire stake. Caution: this operation is not reversible. + /// Join the Internet Computer's community fund with this neuron's entire stake. #[clap(long)] join_community_fund: bool, + /// Leave the Internet Computer's community fund. + #[clap(long, conflicts_with("join-community-fund"))] + leave_community_fund: bool, + /// Defines the topic of a follow rule. #[clap(long)] follow_topic: Option, @@ -386,6 +394,17 @@ pub fn exec(auth: &AuthInfo, opts: ManageOpts) -> AnyhowResult