Skip to content

Commit

Permalink
[tools] vfn configs (0LNetworkCommunity#109)
Browse files Browse the repository at this point in the history
Co-authored-by: 0o-de-lally <[email protected]>
Co-authored-by: Yotam Katznelson <[email protected]>
Co-authored-by: sirouk <[email protected]>
  • Loading branch information
4 people committed Aug 17, 2024
1 parent b681518 commit 14993b5
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 45 deletions.
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

0 comments on commit 14993b5

Please sign in to comment.