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

[tools] vfn configs #109

Merged
merged 15 commits into from
Nov 21, 2023
Merged
30 changes: 13 additions & 17 deletions tools/config/src/config_cli.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::make_yaml_public_fullnode::{download_genesis, init_fullnode_yaml};
use crate::validator_config::initialize_validator_configs;
use crate::validator_config::{validator_dialogue, vfn_dialogue};
use crate::{legacy_config, make_profile};
use anyhow::{Context, Result};
use clap::Parser;
Expand Down Expand Up @@ -90,16 +90,16 @@ enum ConfigSub {
/// check the files generated
#[clap(short, long)]
check: bool,
// just make the VFN file
#[clap(short, long)]
vfn: bool,
},

/// Generate a fullnode dir and add fullnode.yaml from template
FullnodeInit {
/// path to libra config and data files defaults to $HOME/.libra
#[clap(long)]
home_path: Option<PathBuf>,
/// private VFN (only for validators)
#[clap(short, long)]
vfn: bool,
},
}

Expand Down Expand Up @@ -185,10 +185,13 @@ impl ConfigCli {

Ok(())
}
Some(ConfigSub::ValidatorInit { check }) => {
Some(ConfigSub::ValidatorInit { check, vfn }) => {
let home_dir = self.path.clone().unwrap_or_else(global_config_dir);
if *vfn {
vfn_dialogue(&home_dir, None, None).await?;
return Ok(());
}
if *check {
let home_dir = self.path.clone().unwrap_or_else(global_config_dir);

let public_keys_file = home_dir.join(OPERATOR_FILE);

let public_identity = read_operator_file(public_keys_file.as_path())?;
Expand Down Expand Up @@ -237,22 +240,15 @@ impl ConfigCli {
);
std::fs::create_dir_all(&data_path)?;
}
initialize_validator_configs(&data_path, None).await?;
validator_dialogue(&data_path, None).await?;
println!("Validators' config initialized.");
Ok(())
}
Some(ConfigSub::FullnodeInit { home_path, vfn }) => {
Some(ConfigSub::FullnodeInit { home_path }) => {
download_genesis(home_path.to_owned()).await?;
println!("downloaded genesis block");

let p = if *vfn {
// no need for seed peers, will be identified
// to validator node
init_fullnode_yaml(home_path.to_owned(), true, true).await?
} else {
// we want seed peers, and will not have an identity
init_fullnode_yaml(home_path.to_owned(), true, false).await?
};
let p = init_fullnode_yaml(home_path.to_owned(), true).await?;

println!("config created at {}", p.display());

Expand Down
42 changes: 26 additions & 16 deletions tools/config/src/make_yaml_public_fullnode.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
use diem_config::config::NodeConfig;
use diem_types::{network_address::NetworkAddress, waypoint::Waypoint, PeerId};
use diem_crypto::x25519;
use diem_types::{
network_address::{DnsName, NetworkAddress},
waypoint::Waypoint,
PeerId,
};
use libra_types::global_config_dir;
use std::{
collections::HashMap,
path::{Path, PathBuf},
};

const FN_FILENAME: &str = "fullnode.yaml";
const VFN_FILENAME: &str = "vfn.yaml";
/// fetch seed peers and make a yaml file from template
pub async fn init_fullnode_yaml(
home_dir: Option<PathBuf>,
overwrite_peers: bool,
vfn: bool,
) -> anyhow::Result<PathBuf> {
let waypoint = get_genesis_waypoint(home_dir.clone()).await?;

let yaml = if vfn {
make_private_vfn_yaml(home_dir.clone(), waypoint)?
} else {
make_fullnode_yaml(home_dir.clone(), waypoint)?
};

let filename = if vfn { "vfn.yaml" } else { "fullnode.yaml" };
let yaml = make_fullnode_yaml(home_dir.clone(), waypoint)?;

let home = home_dir.unwrap_or_else(global_config_dir);
let p = home.join(filename);
let p = home.join(FN_FILENAME);
std::fs::write(&p, yaml)?;

if overwrite_peers {
Expand Down Expand Up @@ -102,19 +102,21 @@ api:

/// Create a VFN file to for validators to seed the public network
pub fn make_private_vfn_yaml(
home_dir: Option<PathBuf>,
waypoint: Waypoint,
home_dir: &Path,
val_net_pubkey: x25519::PublicKey,
val_host_addr: DnsName,
) -> anyhow::Result<String> {
let home_dir = home_dir.unwrap_or_else(global_config_dir);
let path = home_dir.display().to_string();
let val_net_pubkey = val_net_pubkey.to_string();
let val_host_addr = val_host_addr.to_string();

let template = format!(
"
base:
role: 'full_node'
data_dir: '{path}/data'
waypoint:
from_config: '{waypoint}'
from_file: '{path}/genesis/waypoint.txt'
execution:
genesis_file_location: '{path}/genesis/genesis.blob'
Expand All @@ -133,17 +135,25 @@ full_node_networks:
- network_id:
private: 'vfn'
# mutual_authentication: true
listen_address: '/ip4/0.0.0.0/tcp/6181'
identity:
type: 'from_file'
path: {path}/validator-full-node-identity.yaml
seeds:
{val_net_pubkey}:
addresses:
- '/ip4/{val_host_addr}/tcp/6181/noise-ik/0x{val_net_pubkey}/handshake/0'
role: 'Validator'
api:
enabled: false
enabled: true
address: '0.0.0.0:8080'
"
);

let p = home_dir.join(VFN_FILENAME);
std::fs::write(p, &template)?;

Ok(template)
}

Expand Down
2 changes: 1 addition & 1 deletion tools/config/src/make_yaml_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ full_node_networks:
listen_address: '/ip4/0.0.0.0/tcp/6181'
identity:
type: 'from_file'
path: {path}/validator-full-node-identity.yaml
path: {path}/validator-identity.yaml
api:
enabled: true
Expand Down
70 changes: 62 additions & 8 deletions tools/config/src/validator_config.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
use crate::make_yaml_public_fullnode::make_private_vfn_yaml;
use crate::make_yaml_validator;
use anyhow::{bail, Context};
use anyhow::{anyhow, bail, Context};
use dialoguer::{Confirm, Input};
use diem_crypto::x25519;
use diem_genesis::config::HostAndPort;
use diem_genesis::keys::PublicIdentity;
use diem_types::chain_id::NamedChain;
use diem_types::network_address::DnsName;
use libra_types::legacy_types::app_cfg::AppCfg;
use libra_types::legacy_types::network_playlist::NetworkPlaylist;
use libra_types::ol_progress::OLProgress;
use libra_wallet::utils::read_public_identity_file;
use libra_wallet::validator_files::SetValidatorConfiguration;
use std::path::{Path, PathBuf};
use std::str::FromStr;
Expand All @@ -17,8 +22,8 @@ pub fn initialize_validator(
mnem: Option<String>,
keep_legacy_address: bool,
chain_name: Option<NamedChain>,
) -> anyhow::Result<()> {
let (.., keys) =
) -> anyhow::Result<PublicIdentity> {
let (.., pub_id, keys) =
libra_wallet::keys::refresh_validator_files(mnem, home_path.clone(), keep_legacy_address)?;
OLProgress::complete("initialized validator key files");

Expand Down Expand Up @@ -48,7 +53,7 @@ pub fn initialize_validator(
))?;
OLProgress::complete("saved a user libra.yaml file locally");

Ok(())
Ok(pub_id)
}

async fn get_ip() -> anyhow::Result<HostAndPort> {
Expand All @@ -72,7 +77,7 @@ pub async fn what_host() -> Result<HostAndPort, anyhow::Error> {
};

let input: String = Input::new()
.with_prompt("Enter the DNS or IP address, with port 6180")
.with_prompt("Enter the DNS or IP address, with port. Use validator: 6180, VFN: 6181, fullnode: 6182")
.interact_text()
.unwrap();
let ip = input
Expand All @@ -82,7 +87,7 @@ pub async fn what_host() -> Result<HostAndPort, anyhow::Error> {
Ok(ip)
}

pub async fn initialize_validator_configs(
pub async fn validator_dialogue(
data_path: &Path,
github_username: Option<&str>,
) -> Result<(), anyhow::Error> {
Expand All @@ -99,19 +104,68 @@ pub async fn initialize_validator_configs(
.with_prompt("Is this a legacy V5 address you wish to keep?")
.interact()?;

initialize_validator(
let pub_id = initialize_validator(
Some(data_path.to_path_buf()),
github_username,
host,
host.clone(),
None,
keep_legacy_address,
None,
)?;

// now set up the vfn.yaml on the same host for convenience
vfn_dialogue(
data_path,
Some(host.host),
pub_id.validator_network_public_key,
)
.await?;
}

Ok(())
}

fn get_local_vfn_id(home: &Path) -> anyhow::Result<x25519::PublicKey> {
let id = read_public_identity_file(&home.join("public-keys.yaml"))?;

id.validator_network_public_key
.context("no validator public key found in public-keys.yaml")
}

pub async fn vfn_dialogue(
home: &Path,
host: Option<DnsName>,
net_pubkey: Option<x25519::PublicKey>,
) -> anyhow::Result<()> {
let dns = match host {
Some(d) => d,
None => {
println!("Let's get the network address of your VALIDATOR host");

what_host().await?.host
}
};

let pk = match net_pubkey {
Some(r) => r,
// maybe they already have the public-keys.yamlhere
None => get_local_vfn_id(home).map_err(|e| {
anyhow!("ERROR: cannot make vfn.yaml, make sure you have the public-keys.yaml on this host before starting, message: {}", e)
})?,
};

make_private_vfn_yaml(
home,
// NOTE: the VFN needs to identify the validator node, which uses the
// same validator_network public ID
pk, dns,
)?;

println!("SUCCESS: on your VFN you should have vfn.yaml, validator-full-node.yaml files before starting node.");

Ok(())
}

#[test]
fn test_validator_files_config() {
use libra_types::global_config_dir;
Expand Down
4 changes: 2 additions & 2 deletions tools/genesis/src/wizard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use diem_github_client::Client;
use libra_types::legacy_types::app_cfg::AppCfg;
use libra_wallet::keys::VALIDATOR_FILE;

use libra_config::validator_config::initialize_validator_configs;
use libra_config::validator_config::validator_dialogue;

pub const DEFAULT_GIT_BRANCH: &str = "main";
pub const GITHUB_TOKEN_FILENAME: &str = "github_token.txt";
Expand Down Expand Up @@ -92,7 +92,7 @@ impl GenesisWizard {
// check the git token is as expected, and set it.
self.git_token_check()?;

match initialize_validator_configs(&self.data_path, Some(&self.github_username)).await {
match validator_dialogue(&self.data_path, Some(&self.github_username)).await {
Ok(_) => {
println!("Validators' config initialized!");
}
Expand Down
5 changes: 4 additions & 1 deletion tools/wallet/src/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,10 @@ pub fn generate_key_objects_from_legacy(
network_private_key: validator_network_key.private_key(),
};
let vfn_blob = IdentityBlob {
account_address: Some(account_address),
// the VFN needs a different address than the validator
// otherwise it will think it is dialing itself, and
// will show a "self dial" error on the validator logs
account_address: Some(full_node_network_key.public_key().to_string().parse()?),
account_private_key: None,
consensus_private_key: None,
network_private_key: full_node_network_key.private_key(),
Expand Down
Loading