Skip to content

Commit

Permalink
feat: support replace node provider id (#118)
Browse files Browse the repository at this point in the history
* feat: support replace node provider id

* test

* doc
  • Loading branch information
lwshang authored Jun 22, 2022
1 parent 4641e7a commit e0caa66
Show file tree
Hide file tree
Showing 6 changed files with 373 additions and 3 deletions.
279 changes: 279 additions & 0 deletions candid/registry.did
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
type AddFirewallRulesPayload = record {
expected_hash : text;
scope : FirewallRulesScope;
positions : vec int32;
rules : vec FirewallRule;
};
type AddNodeOperatorPayload = record {
ipv6 : opt text;
node_operator_principal_id : opt principal;
node_allowance : nat64;
rewardable_nodes : vec record { text; nat32 };
node_provider_principal_id : opt principal;
dc_id : text;
};
type AddNodePayload = record {
prometheus_metrics_endpoint : text;
http_endpoint : text;
idkg_dealing_encryption_pk : opt vec nat8;
xnet_endpoint : text;
committee_signing_pk : vec nat8;
node_signing_pk : vec nat8;
transport_tls_cert : vec nat8;
ni_dkg_dealing_encryption_pk : vec nat8;
p2p_flow_endpoints : vec text;
};
type AddNodesToSubnetPayload = record {
subnet_id : principal;
node_ids : vec principal;
};
type AddOrRemoveDataCentersProposalPayload = record {
data_centers_to_add : vec DataCenterRecord;
data_centers_to_remove : vec text;
};
type BitcoinFeature = record {
status : BitcoinFeatureStatus;
network : Network;
};
type BitcoinFeatureStatus = variant { Paused; Enabled; Disabled; Syncing };
type BlessReplicaVersionPayload = record {
node_manager_sha256_hex : text;
release_package_url : text;
sha256_hex : text;
replica_version_id : text;
release_package_sha256_hex : text;
node_manager_binary_url : text;
binary_url : text;
};
type CanisterIdRange = record { end : principal; start : principal };
type CompleteCanisterMigrationPayload = record {
canister_id_ranges : vec CanisterIdRange;
migration_trace : vec principal;
};
type CreateSubnetPayload = record {
unit_delay_millis : nat64;
max_instructions_per_round : nat64;
features : SubnetFeatures;
max_instructions_per_message : nat64;
gossip_registry_poll_period_ms : nat32;
max_ingress_bytes_per_message : nat64;
dkg_dealings_per_block : nat64;
max_block_payload_size : nat64;
max_instructions_per_install_code : nat64;
start_as_nns : bool;
is_halted : bool;
gossip_pfn_evaluation_period_ms : nat32;
max_ingress_messages_per_block : nat64;
max_number_of_canisters : nat64;
ecdsa_config : opt EcdsaInitialConfig;
gossip_max_artifact_streams_per_peer : nat32;
advert_best_effort_percentage : opt nat32;
replica_version_id : text;
gossip_max_duplicity : nat32;
gossip_max_chunk_wait_ms : nat32;
dkg_interval_length : nat64;
subnet_id_override : opt principal;
ssh_backup_access : vec text;
ingress_bytes_per_block_soft_cap : nat64;
initial_notary_delay_millis : nat64;
gossip_max_chunk_size : nat32;
subnet_type : SubnetType;
ssh_readonly_access : vec text;
gossip_retransmission_request_ms : nat32;
gossip_receive_check_cache_size : nat32;
node_ids : vec principal;
};
type DataCenterRecord = record {
id : text;
gps : opt Gps;
region : text;
owner : text;
};
type DeleteSubnetPayload = record { subnet_id : opt principal };
type EcdsaConfig = record {
quadruples_to_create_in_advance : nat32;
max_queue_size : opt nat32;
key_ids : vec EcdsaKeyId;
};
type EcdsaCurve = variant { secp256k1 };
type EcdsaInitialConfig = record {
quadruples_to_create_in_advance : nat32;
max_queue_size : opt nat32;
keys : vec EcdsaKeyRequest;
};
type EcdsaKeyId = record { name : text; curve : EcdsaCurve };
type EcdsaKeyRequest = record {
key_id : EcdsaKeyId;
subnet_id : opt principal;
};
type FirewallRule = record {
ipv4_prefixes : vec text;
action : int32;
comment : text;
ipv6_prefixes : vec text;
ports : vec nat32;
};
type FirewallRulesScope = variant {
Node : principal;
ReplicaNodes;
Subnet : principal;
Global;
};
type Gps = record { latitude : float32; longitude : float32 };
type Network = variant { Mainnet; Regtest; Testnet };
type NodeOperatorRecord = record {
ipv6 : opt text;
node_operator_principal_id : vec nat8;
node_allowance : nat64;
rewardable_nodes : vec record { text; nat32 };
node_provider_principal_id : vec nat8;
dc_id : text;
};
type NodeProvidersMonthlyXdrRewards = record {
rewards : vec record { text; nat64 };
};
type NodeRewardRate = record { xdr_permyriad_per_node_per_month : nat64 };
type NodeRewardRates = record { rates : vec record { text; NodeRewardRate } };
type PrepareCanisterMigrationPayload = record {
canister_id_ranges : vec CanisterIdRange;
source_subnet : principal;
destination_subnet : principal;
};
type RecoverSubnetPayload = record {
height : nat64;
replacement_nodes : opt vec principal;
subnet_id : principal;
registry_store_uri : opt record { text; text; nat64 };
ecdsa_config : opt EcdsaInitialConfig;
state_hash : vec nat8;
time_ns : nat64;
};
type RemoveFirewallRulesPayload = record {
expected_hash : text;
scope : FirewallRulesScope;
positions : vec int32;
};
type RemoveNodeDirectlyPayload = record { node_id : principal };
type RemoveNodeOperatorsPayload = record {
node_operators_to_remove : vec vec nat8;
};
type RemoveNodesPayload = record { node_ids : vec principal };
type RerouteCanisterRangesPayload = record {
source_subnet : principal;
reassigned_canister_ranges : vec CanisterIdRange;
destination_subnet : principal;
};
type Result = variant { Ok : principal; Err : text };
type Result_1 = variant { Ok; Err : text };
type Result_2 = variant {
Ok : vec record { DataCenterRecord; NodeOperatorRecord };
Err : text;
};
type Result_3 = variant { Ok : NodeProvidersMonthlyXdrRewards; Err : text };
type SetFirewallConfigPayload = record {
ipv4_prefixes : vec text;
firewall_config : text;
ipv6_prefixes : vec text;
};
type SubnetFeatures = record {
canister_sandboxing : bool;
http_requests : bool;
bitcoin : opt BitcoinFeature;
};
type SubnetType = variant { application; verified_application; system };
type UpdateNodeDirectlyPayload = record {
idkg_dealing_encryption_pk : opt vec nat8;
};
type UpdateNodeOperatorConfigDirectlyPayload = record {
node_operator_id : opt principal;
node_provider_id : opt principal;
};
type UpdateNodeOperatorConfigPayload = record {
node_operator_id : opt principal;
set_ipv6_to_none : opt bool;
ipv6 : opt text;
node_provider_id : opt principal;
node_allowance : opt nat64;
rewardable_nodes : vec record { text; nat32 };
dc_id : opt text;
};
type UpdateNodeRewardsTableProposalPayload = record {
new_entries : vec record { text; NodeRewardRates };
};
type UpdateSubnetPayload = record {
unit_delay_millis : opt nat64;
max_duplicity : opt nat32;
max_instructions_per_round : opt nat64;
features : opt SubnetFeatures;
set_gossip_config_to_default : bool;
max_instructions_per_message : opt nat64;
pfn_evaluation_period_ms : opt nat32;
subnet_id : principal;
max_ingress_bytes_per_message : opt nat64;
dkg_dealings_per_block : opt nat64;
ecdsa_key_signing_disable : opt vec EcdsaKeyId;
max_block_payload_size : opt nat64;
max_instructions_per_install_code : opt nat64;
start_as_nns : opt bool;
is_halted : opt bool;
max_ingress_messages_per_block : opt nat64;
max_number_of_canisters : opt nat64;
ecdsa_config : opt EcdsaConfig;
advert_best_effort_percentage : opt nat32;
retransmission_request_ms : opt nat32;
dkg_interval_length : opt nat64;
registry_poll_period_ms : opt nat32;
max_chunk_wait_ms : opt nat32;
receive_check_cache_size : opt nat32;
ecdsa_key_signing_enable : opt vec EcdsaKeyId;
ssh_backup_access : opt vec text;
max_chunk_size : opt nat32;
initial_notary_delay_millis : opt nat64;
max_artifact_streams_per_peer : opt nat32;
subnet_type : opt SubnetType;
ssh_readonly_access : opt vec text;
};
type UpdateSubnetReplicaVersionPayload = record {
subnet_id : principal;
replica_version_id : text;
};
type UpdateUnassignedNodesConfigPayload = record {
replica_version : opt text;
ssh_readonly_access : opt vec text;
};
service : {
add_firewall_rules : (AddFirewallRulesPayload) -> ();
add_node : (AddNodePayload) -> (Result);
add_node_operator : (AddNodeOperatorPayload) -> ();
add_nodes_to_subnet : (AddNodesToSubnetPayload) -> ();
add_or_remove_data_centers : (AddOrRemoveDataCentersProposalPayload) -> ();
bless_replica_version : (BlessReplicaVersionPayload) -> ();
clear_provisional_whitelist : () -> ();
complete_canister_migration : (CompleteCanisterMigrationPayload) -> (
Result_1,
);
create_subnet : (CreateSubnetPayload) -> ();
delete_subnet : (DeleteSubnetPayload) -> ();
get_build_metadata : () -> (text) query;
get_node_operators_and_dcs_of_node_provider : (principal) -> (Result_2) query;
get_node_providers_monthly_xdr_rewards : () -> (Result_3) query;
prepare_canister_migration : (PrepareCanisterMigrationPayload) -> (Result_1);
recover_subnet : (RecoverSubnetPayload) -> ();
remove_firewall_rules : (RemoveFirewallRulesPayload) -> ();
remove_node_directly : (RemoveNodeDirectlyPayload) -> ();
remove_node_operators : (RemoveNodeOperatorsPayload) -> ();
remove_nodes : (RemoveNodesPayload) -> ();
remove_nodes_from_subnet : (RemoveNodesPayload) -> ();
reroute_canister_ranges : (RerouteCanisterRangesPayload) -> (Result_1);
set_firewall_config : (SetFirewallConfigPayload) -> ();
update_firewall_rules : (AddFirewallRulesPayload) -> ();
update_node_directly : (UpdateNodeDirectlyPayload) -> (Result_1);
update_node_operator_config : (UpdateNodeOperatorConfigPayload) -> ();
update_node_operator_config_directly : (
UpdateNodeOperatorConfigDirectlyPayload,
) -> ();
update_node_rewards_table : (UpdateNodeRewardsTableProposalPayload) -> ();
update_subnet : (UpdateSubnetPayload) -> ();
update_subnet_replica_version : (UpdateSubnetReplicaVersionPayload) -> ();
update_unassigned_nodes_config : (UpdateUnassignedNodesConfigPayload) -> ();
}
5 changes: 5 additions & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mod neuron_manage;
mod neuron_stake;
mod public;
mod qrcode;
mod replace_node_provide_id;
mod request_status;
mod send;
mod transfer;
Expand All @@ -43,6 +44,7 @@ pub enum Command {
AccountBalance(account_balance::AccountBalanceOpts),
/// Update node provider details
UpdateNodeProvider(update_node_provider::UpdateNodeProviderOpts),
ReplaceNodeProviderId(replace_node_provide_id::ReplaceNodeProviderIdOpts),
/// Generate a mnemonic seed phrase and generate or recover PEM.
Generate(generate::GenerateOpts),
/// Print QR Scanner dapp QR code: scan to start dapp to submit QR results.
Expand Down Expand Up @@ -81,6 +83,9 @@ pub fn exec(auth: &AuthInfo, qr: bool, fetch_root_key: bool, cmd: Command) -> An
Command::UpdateNodeProvider(opts) => {
update_node_provider::exec(auth, opts).and_then(|out| print(&out))
}
Command::ReplaceNodeProviderId(opts) => {
replace_node_provide_id::exec(auth, opts).and_then(|out| print(&out))
}
Command::Send(opts) => runtime.block_on(async { send::exec(opts, fetch_root_key).await }),
Command::Generate(opts) => generate::exec(opts),
// QR code for URL: https://p5deo-6aaaa-aaaab-aaaxq-cai.raw.ic0.app/
Expand Down
62 changes: 62 additions & 0 deletions src/commands/replace_node_provide_id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use std::str::FromStr;

use crate::{
lib::signing::{sign_ingress_with_request_status_query, IngressWithRequestId},
lib::{registry_canister_id, AnyhowResult, AuthInfo},
};
use anyhow::{anyhow, Context};
use candid::{CandidType, Encode};
use clap::Parser;
use ic_base_types::PrincipalId;

/// Signs a message to replace Node Provide ID in targeted Node Operator Record
#[derive(Parser)]
pub struct ReplaceNodeProviderIdOpts {
/// The Principal id of the node operator. This principal is the entity that
/// is able to add and remove nodes.
#[clap(long)]
node_operator_id: String,

/// The new Principal id of the node provider.
#[clap(long)]
node_provider_id: String,
}

/// The payload to update an existing Node Operator (without going through the proposal process)
#[derive(CandidType)]
pub struct UpdateNodeOperatorConfigDirectlyPayload {
pub node_operator_id: Option<PrincipalId>,
pub node_provider_id: Option<PrincipalId>,
}

pub fn exec(
auth: &AuthInfo,
opts: ReplaceNodeProviderIdOpts,
) -> AnyhowResult<Vec<IngressWithRequestId>> {
let node_operator_id = PrincipalId::from_str(&opts.node_operator_id)
.map_err(|e| anyhow!(e))
.with_context(|| {
format!(
"node_operator_id {} is not valid Principal",
&opts.node_operator_id
)
})?;
let node_provider_id = PrincipalId::from_str(&opts.node_provider_id)
.map_err(|e| anyhow!(e))
.with_context(|| {
format!(
"node_provider_id {} is not valid Principal",
&opts.node_provider_id
)
})?;
let args = Encode!(&UpdateNodeOperatorConfigDirectlyPayload {
node_operator_id: Some(node_operator_id),
node_provider_id: Some(node_provider_id),
})?;
Ok(vec![sign_ingress_with_request_status_query(
auth,
registry_canister_id(),
"update_node_operator_config_directly",
args,
)?])
}
Loading

0 comments on commit e0caa66

Please sign in to comment.