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(node): Add node_reward_type field to AddNodePayload and node config #3116

Merged
merged 19 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
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
22 changes: 20 additions & 2 deletions ic-os/components/ic/generate-ic-config/generate-ic-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
function usage() {
cat <<EOF
Usage:
generate-ic-config [-n network.conf] [-c nns.conf] [-b backup.conf] [-m malicious_behavior.conf] [-q query_stats.conf] -i ic.json5.template -o ic.json5
generate-ic-config [-n network.conf] [-c nns.conf] [-b backup.conf] [-m malicious_behavior.conf] [-q query_stats.conf] [ -r reward.conf ] -i ic.json5.template -o ic.json5

Generate replica config from template file.

Expand All @@ -15,6 +15,7 @@ Usage:
-b backup.conf: Optional, parameters of the artifact backup
-m malicious_behavior.conf: Optional, malicious behavior parameters
-q query_stats.conf: Optional, query statistics epoch length configuration
-r reward.conf: Optional, node reward type configuration
-t jaeger_addr.conf: Optional, Jaeger address
-i infile: input ic.json5.template file
-o outfile: output ic.json5 file
Expand Down Expand Up @@ -139,6 +140,15 @@ function read_query_stats_variables() {
done <"$1"
}

# Read node reward type config variables from file. The file contains a single value which is the node reward type.
function read_node_reward_type_variable() {
while IFS="=" read -r key value; do
case "$key" in
"node_reward_type") node_reward_type="${value}" ;;
esac
done <"$1"
}

# Read Jaeger address variable from file. The file contains a single value Jaeger node address used in system tests.
function read_jaeger_addr_variable() {
while IFS="=" read -r key value; do
Expand All @@ -148,7 +158,7 @@ function read_jaeger_addr_variable() {
done <"$1"
}

while getopts "l:m:q:n:c:t:i:o:b:" OPT; do
while getopts "l:m:q:r:n:c:t:i:o:b:" OPT; do
case "${OPT}" in
n)
NETWORK_CONFIG_FILE="${OPTARG}"
Expand All @@ -165,6 +175,9 @@ while getopts "l:m:q:n:c:t:i:o:b:" OPT; do
q)
QUERY_STATS_CONFIG_FILE="${OPTARG}"
;;
r)
NODE_REWARD_TYPE="${OPTARG}"
;;
t)
JAEGER_ADDR_FILE="${OPTARG}"
;;
Expand Down Expand Up @@ -206,6 +219,10 @@ if [ "${QUERY_STATS_CONFIG_FILE}" != "" -a -e "${QUERY_STATS_CONFIG_FILE}" ]; th
read_query_stats_variables "${QUERY_STATS_CONFIG_FILE}"
fi

if [ "${NODE_REWARD_TYPE}" != "" -a -e "${NODE_REWARD_TYPE}" ]; then
read_node_reward_type_variable "${NODE_REWARD_TYPE}"
fi

if [ "${JAEGER_ADDR_FILE}" != "" -a -e "${JAEGER_ADDR_FILE}" ]; then
read_jaeger_addr_variable "${JAEGER_ADDR_FILE}"
fi
Expand Down Expand Up @@ -249,6 +266,7 @@ sed -e "s@{{ ipv6_address }}@${IPV6_ADDRESS}@" \
-e "s@{{ backup_purging_interval_secs }}@${BACKUP_PURGING_INTERVAL_SECS}@" \
-e "s@{{ malicious_behavior }}@${MALICIOUS_BEHAVIOR}@" \
-e "s@{{ query_stats_epoch_length }}@${QUERY_STATS_EPOCH_LENGTH}@" \
-e "s@{{ node_reward_type }}@${NODE_REWARD_TYPE}@" \
-e "s@{{ jaeger_addr }}@${JAEGER_ADDR}@" \
"${IN_FILE}" >"${OUT_FILE}"

Expand Down
1 change: 1 addition & 0 deletions ic-os/components/ic/generate-ic-config/ic.json5.template
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ table ip6 filter {\n\
},

registration: {
node_reward_type: "{{ node_reward_type }}",
nns_url: "{{ nns_urls }}",
nns_pub_key_pem: "/var/lib/ic/data/nns_public_key.pem",
node_operator_pem: "/var/lib/ic/data/node_operator_private_key.pem"
Expand Down
2 changes: 1 addition & 1 deletion ic-os/docs/Configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ In production, configuration is propagated from a partition on the USB installer
=== SetupOS -> HostOS

SetupOS validates, sanitizes, and copies all of its configuration files to the HostOS config partition:
config.ini # Data center-specific network settings
config.ini # Data center and node-specific network settings
ssh_authorized_keys # SSH private keys
node_operator_private_key.pem # Node Operator private key created in the Node Provider onboarding
deployment.json # Deployment-specific configurations
Expand Down
4 changes: 2 additions & 2 deletions ic-os/setupos/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ The sequence of the scripts is defined in the main installation script, `setupos
== Node Providers, Node Technicians, and Node Operators

* *Node Provider*: An entity that purchases and owns the node hardware. Node Providers are rewarded for their node's useful work.
* *Node Technician*: These are the 'hired hands' or 'remote hands' employed by the Node Providers to maintain and manage the node. They do not necessarily own the hardware, but are responsible for its operation. Note that a single node will often have more than one Node Technicianthe Node Technician can be thought of as the individual currently operating the node, so this role can cycle among several parties.
** Note: While it is possible, it is uncommon for a Node Provider to also act as their own Node Technician.
* *Node Technician*: Node Technicians are responsible for the physical installation, maintenance, and repair of the node. These are typically 'hired hands' or 'remote hands' employed by the Node Providers to maintain and manage the node. A single node may have more than one Node Technicianthe Node Technician can be thought of as the individual currently operating the node, so this role can cycle among several parties. The information about the Node Technician is currently not stored in the NNS.
** Note: It is possible that a Node Provider and Node Technician are the same entity.
* *Node Operator*:
** The term "Node Operator" refers not to a specific individual or group, but to:
*** A specific record within the NNS registry—the *Node Operator record*, and to:
Expand Down
31 changes: 21 additions & 10 deletions ic-os/setupos/config/config.ini
sasa-tomic marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,6 @@
#
# Update these settings according to your specific network and node requirements.

# ------------------------------
# Node Reward Settings (required)
# ------------------------------
# Update node_reward_type as per your node configuration.
# Node rewards setting should be of the form:
# node_reward_type=typeX or node_reward_type=typeX.Y
# Example:
# node_reward_type=type3.1
node_reward_type=

# ------------------------------
# IPv6 Settings (required)
# ------------------------------
Expand All @@ -23,6 +13,27 @@ ipv6_prefix=2a00:fb01:400:44
# Define the gateway address for your IPv6 network. Ensure it's within your network range:
ipv6_gateway=2a00:fb01:400:44::1

# ------------------------------
# Node Reward Settings (required for some node operators)
# ------------------------------
# Specifies the type of node rewards that the node operator expects to receive.
# The value must match a community-approved value in the NNS.
#
# Example command to get node operator details:
# ic-admin --nns-url https://ic0.app get-node-operator ut325-qbq5v-fli2f-e2a5h-qapdd-fsuyv-xej2j-ogvux-i3fc2-5nj3a-2ae
# Example output:
# NodeOperator { node_operator_principal_id: ut325-qbq5v-fli2f-e2a5h-qapdd-fsuyv-xej2j-ogvux-i3fc2-5nj3a-2ae, node_allowance: 0, node_provider_principal_id: lq5ra-f4ibl-t7wpy-hennc-m4eb7-tnfxe-eorgd-onpsl-wervo-7chjj-6qe, dc_id: "bo1", rewardable_nodes: {"type1": 28}, ipv6: None }
# ==> The community-approved value of node_reward_type for this operator is "type1"
#
# If not provided, the NNS will attempt to automatically assign a value based on the operator's reward configuration.
sasa-tomic marked this conversation as resolved.
Show resolved Hide resolved
# If the reward configuration in unique, the NNS will automatically assign the correct node_reward_type.
sasa-tomic marked this conversation as resolved.
Show resolved Hide resolved
# If the reward configuration is ambiguous (e.g., the operator has both "type3" and "type3.1" rewards), node
# registration with a node_reward_type set to empty value below will fail.
# Expected value format:
# node_reward_type=typeX or node_reward_type=typeX.Y
# Examples include "type3.1", "type1", etc.:
# node_reward_type=type3.1
sasa-tomic marked this conversation as resolved.
Show resolved Hide resolved
node_reward_type=

# ------------------------------
# IPv4 Settings (Optional)
Expand Down
10 changes: 10 additions & 0 deletions rs/config/src/registration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ pub struct Config {

/// If this Sec256k1 PEM is available, use it instead of the HSM.
pub node_operator_pem: Option<PathBuf>,

/// Specifies the type of node rewards that the node operator expects to receive.
/// Examples include "type3.1" or "type1", corresponding to entries in the node reward table in the NNS.
/// The value must match a community-approved value in the NNS.
/// If not provided, the NNS will attempt to assign a value based on the operator's reward configuration.
/// If the reward configuration in the NNS is ambiguous (has more than 1 value), node registration
/// is expected to fail since it's unclear which rewards should be assigned to the node.
/// If there is no reward table configured in the NNS, the value of this field is ignored during registration.
pub node_reward_type: Option<String>,
}

// We allow for the operator to only specify some of the fields while the others
Expand Down Expand Up @@ -57,6 +66,7 @@ impl Default for Config {
nns_url: None,
nns_pub_key_pem: None,
node_operator_pem: None,
node_reward_type: None,
}
}
}
1 change: 1 addition & 0 deletions rs/ic_os/dev_test_tools/launch-single-vm/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ fn main() {
node_operator_principal_id: None,
secret_key_store: None,
domain: None,
node_reward_type: None,
},
)]);

Expand Down
10 changes: 6 additions & 4 deletions rs/orchestrator/src/registration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ pub(crate) struct NodeRegistration {
key_handler: Arc<dyn NodeRegistrationCrypto>,
local_store: Arc<dyn LocalStore>,
signer: Box<dyn Signer>,
node_reward_type: Option<String>,
sasa-tomic marked this conversation as resolved.
Show resolved Hide resolved
}

impl NodeRegistration {
Expand All @@ -91,6 +92,7 @@ impl NodeRegistration {
Some(signer) => Box::new(signer),
None => Box::new(Hsm),
};
let node_reward_type = node_config.registration.node_reward_type.clone();
Self {
log,
node_config,
Expand All @@ -100,6 +102,7 @@ impl NodeRegistration {
key_handler,
local_store,
signer,
node_reward_type,
}
}

Expand Down Expand Up @@ -219,10 +222,9 @@ impl NodeRegistration {
.expect("Invalid IPv4 configuration"),
domain: process_domain_name(&self.log, &self.node_config.domain)
.expect("Domain name is invalid"),
// Unused section follows
p2p_flow_endpoints: Default::default(),
prometheus_metrics_endpoint: Default::default(),
node_reward_type: None,
node_reward_type: self.node_config.registration.node_reward_type.clone(),
p2p_flow_endpoints: Default::default(), // unused section
prometheus_metrics_endpoint: Default::default(), // unused section
}
}

Expand Down
1 change: 1 addition & 0 deletions rs/prep/src/bin/prep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ mod test_flag_node_parser {
node_operator_principal_id: None,
secret_key_store: None,
domain: None,
node_reward_type: None,
},
};

Expand Down
13 changes: 12 additions & 1 deletion rs/prep/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ use ic_crypto_node_key_validation::ValidNodePublicKeys;
use ic_interfaces_state_manager::{CertificationScope, StateHashError, StateManager};
use ic_protobuf::registry::{
crypto::v1::{PublicKey, X509PublicKeyCert},
node::v1::{ConnectionEndpoint as pbConnectionEndpoint, NodeRecord as pbNodeRecord},
node::v1::{
ConnectionEndpoint as pbConnectionEndpoint, NodeRecord as pbNodeRecord, NodeRewardType,
},
};
use ic_registry_keys::{make_crypto_node_key, make_crypto_tls_cert_key, make_node_record_key};
use ic_registry_proto_data_provider::ProtoRegistryDataProvider;
Expand Down Expand Up @@ -306,6 +308,10 @@ pub struct NodeConfiguration {
/// The domain name of the node
#[serde(skip_serializing, skip_deserializing)]
pub domain: Option<String>,

/// The type of rewards that the node operator wants to receive for the node.
/// E.g. "type3.1" or "type1" or similar from the node reward table in the NNS.
pub node_reward_type: Option<String>,
}

impl From<NodeConfiguration> for pbNodeRecord {
Expand All @@ -324,6 +330,10 @@ impl From<NodeConfiguration> for pbNodeRecord {
.map(|id| id.to_vec())
.unwrap_or_default(),
domain: node_configuration.domain,
node_reward_type: node_configuration
.node_reward_type
.map(NodeRewardType::from)
.map(|t| t as i32),
..Default::default()
}
}
Expand Down Expand Up @@ -440,6 +450,7 @@ mod node_configuration {
node_operator_principal_id: None,
secret_key_store: None,
domain: None,
node_reward_type: None,
};

let got = pbNodeRecord::from(node_configuration);
Expand Down
1 change: 1 addition & 0 deletions rs/prep/src/prep_state_directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ mod tests {
node_operator_principal_id: None,
secret_key_store: None,
domain: None,
node_reward_type: None,
},
);

Expand Down
16 changes: 15 additions & 1 deletion rs/protobuf/src/registry/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,24 @@ impl From<NodeRewardType> for String {
}
NodeRewardType::Type0 => "type0".to_string(),
NodeRewardType::Type1 => "type1".to_string(),
NodeRewardType::Type1dot1 => "type1.1".to_string(),
NodeRewardType::Type2 => "type2".to_string(),
NodeRewardType::Type3 => "type3".to_string(),
NodeRewardType::Type3dot1 => "type3.1".to_string(),
NodeRewardType::Type1dot1 => "type1.1".to_string(),
}
}
}

impl From<String> for NodeRewardType {
fn from(value: String) -> Self {
match value.as_str() {
"type0" => NodeRewardType::Type0,
"type1" => NodeRewardType::Type1,
"type1.1" => NodeRewardType::Type1dot1,
"type2" => NodeRewardType::Type2,
"type3" => NodeRewardType::Type3,
"type3.1" => NodeRewardType::Type3dot1,
_ => NodeRewardType::Unspecified,
}
}
}
1 change: 1 addition & 0 deletions rs/registry/regedit/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ pub fn run_ic_prep() -> (TempDir, IcPrepStateDir) {
node_operator_principal_id: None,
secret_key_store: None,
domain: None,
node_reward_type: None,
},
);

Expand Down
1 change: 1 addition & 0 deletions rs/replica_tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ pub fn get_ic_config() -> IcConfig {
node_operator_principal_id: None,
secret_key_store: Some(node_sks),
domain: None,
node_reward_type: None,
},
);

Expand Down
1 change: 1 addition & 0 deletions rs/starter/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ fn main() -> Result<()> {
node_operator_principal_id: None,
secret_key_store: None,
domain: None,
node_reward_type: None,
},
);

Expand Down
1 change: 1 addition & 0 deletions rs/tests/driver/src/driver/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ fn node_to_config(node: &Node) -> NodeConfiguration {
node_operator_principal_id: None,
secret_key_store: node.secret_key_store.clone(),
domain: node.domain.clone(),
node_reward_type: None,
}
}

Expand Down
Loading