Skip to content

Commit

Permalink
[tools] Transaction to update Val configs on chain (0LNetworkCommunit…
Browse files Browse the repository at this point in the history
…y#938)

* create txs subcommand to update val configs based on onboarding configuration objects

* remove unwraps which cause panic on wizard and init

* scaffold whoami command

* cleanup whoami

* patch tests. Fix issue with discovery info using old port.

* remove deprecated code

* get external IP from external source

* make the VFN have a fixed identity on the public network.

* display current network id from node.yaml

* val-config can check onchain configs and print

* Relocate the query of onchain configs to `ol query`. 

* Added documentation
  • Loading branch information
0o-de-lally authored Jan 11, 2022
1 parent 441dab5 commit 5f61e5e
Show file tree
Hide file tree
Showing 32 changed files with 774 additions and 628 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 30 additions & 33 deletions config/management/genesis/src/ol_node_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use diem_config::{
use diem_crypto::x25519::PublicKey;
use diem_global_constants::{
DEFAULT_PUB_PORT, DEFAULT_VFN_PORT, OWNER_ACCOUNT,
VALIDATOR_NETWORK_KEY,
VALIDATOR_NETWORK_KEY, FULLNODE_NETWORK_KEY,
};
use diem_management::{config::ConfigPath, error::Error, secure_backend::ValidatorBackend};
use diem_secure_storage::{CryptoStorage, KVStorage};
Expand Down Expand Up @@ -404,29 +404,18 @@ pub fn make_vfn_cfg(

// Private Fullnode Network named "vfn" - but could be any name the validator and vfn agreed on
let mut vfn_network = NetworkConfig::network_with_id(NetworkId::Private("vfn".to_string()));
//////////////// IDENTITY OF NODE ////////////////
//////////////// IDENTITY OF THE VFN FOR PUBLIC NETWORK ////////////////
// the VFN announces itself as the owner address, but uses FULLNODE private key to authenticate.
// make the fullnode discoverable by the account address of the validator owner.
let owner_address_as_fn_id = storage.get(OWNER_ACCOUNT)?.value;

// TODO: determine if we want deterministic identity. Seems to not work with VFN, for now allowing the network configs to generate random ID for VFN.

// NOTE: WE ARE CHOSING TO HAVE THE FULLNODE NETWORK PRIVATE KEY UNECRPYTED IN THE CONFIG FILE
// this is preferable to the VFN also storing the key_store.json on the host
// which is equally insecure, and contains many more keys.


// let fullnode_private_key = storage.export_private_key(FULLNODE_NETWORK_KEY)?;

// let p = PrivateKey::from_ed25519_private_bytes(&fullnode_private_key.to_bytes())?;
// let id_of_vfn_node = Identity::from_config(p, owner_address_as_fn_id);
// TODO: determine if we want deterministic identity for the PRIVATE NETWORK.

// A VFN has two fullnode networks it participates in.
// 1. A private network with the Validator.
// 2. the fullnode network. The fullnode network cannot exist unless the VFN briges the validators to the public.

// vfn_network.identity = id_of_vfn_node.clone();

// vfn_network.identity = // KEYS ARE RANDOMLY SET IF UNDEFINED

// set the Validator as the Seed peer for the VFN network
// need to get their ID and IP address
Expand All @@ -435,7 +424,11 @@ pub fn make_vfn_cfg(

let p = PrivateKey::from_ed25519_private_bytes(&val_net_private_key.to_bytes())?;

let seeds = make_vfn_peer_set(owner_address_as_fn_id, p.public_key(), val_ip_address)?;
let seeds = encode_validator_seed_for_vfn_discovery(
owner_address_as_fn_id,
p.public_key(),
val_ip_address
)?;

// The seed for the VFN is the validator's ID on the private network.
vfn_network.seeds = seeds;
Expand All @@ -448,9 +441,17 @@ pub fn make_vfn_cfg(
// Public fullnode network template
let mut pub_network = NetworkConfig::network_with_id(NetworkId::Public);

// TODO: decide if we want deterministic addresses for public network.
// using the same ID on both private vfn network as well as public network.
// pub_network.identity = id_of_vfn_node;
////////////////// IDENTITY OF NODE FOR THE PUBLIC FULLNODE NETWORK /////////////////////////
// NOTE: WE ARE CHOSING TO HAVE THE FULLNODE NETWORK PRIVATE KEY UNECRPYTED IN THE CONFIG FILE
// this is preferable to the VFN also storing the key_store.json on the host
// which is equally insecure, and contains many more keys.

let fullnode_private_key = storage.export_private_key(FULLNODE_NETWORK_KEY)?;

let p = PrivateKey::from_ed25519_private_bytes(&fullnode_private_key.to_bytes())?;
let id_of_vfn_node = Identity::from_config(p, owner_address_as_fn_id);

pub_network.identity = id_of_vfn_node;

// this port accepts connections from unknown peers.
pub_network.listen_address = format!("/ip4/0.0.0.0/tcp/{}", DEFAULT_PUB_PORT).parse()?;
Expand All @@ -465,29 +466,25 @@ pub fn make_vfn_cfg(
Ok(c)
}

fn make_vfn_peer_set(
// Create the seed discovery information, so that the VFN can find the Validator.
// The validator announces itsef with the validator's VALIDATOR_NETWORK_KEY, so we need to construct the noise protocol with it. (NOT the VFN identity)
fn encode_validator_seed_for_vfn_discovery(
validator_account: AccountAddress,
val_vfn_net_pubkey: PublicKey,
val_net_pubkey: PublicKey,
ip_address: Ipv4Addr,
) -> Result<PeerSet, Error> {
// create the vfn network info.
let val_peer_data = make_validator_network_protocol(ip_address, val_vfn_net_pubkey)?;
// construct seed peer info, using the validator's ID it uses on the private network VALIDATOR_NETWORK_KEY

let role = PeerRole::Validator;
let val_addr = ValConfigs::make_unencrypted_addr(&ip_address, val_net_pubkey, NetworkId::Private("vfn".to_owned()));
let val_peer_data = Peer::from_addrs(role, vec![val_addr]);

// The seed address for the VFN can only be the Validator's address.
let mut seeds = PeerSet::default();
seeds.insert(validator_account, val_peer_data);
Ok(seeds)
}

pub fn make_validator_network_protocol(
ip_address: Ipv4Addr,
pubkey: PublicKey,
) -> Result<Peer, Error> {
let role = PeerRole::Validator;
let val_addr = ValConfigs::make_vfn_addr(&ip_address.to_string(), pubkey);
let p = Peer::from_addrs(role, vec![val_addr]);
Ok(p)
}


pub fn default_for_public_fullnode() -> Result<NodeConfig, anyhow::Error> {
let path_str = env!("CARGO_MANIFEST_DIR");
Expand Down
32 changes: 0 additions & 32 deletions json-rpc/types/src/views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1474,38 +1474,6 @@ impl TowerStateResourceView {
}
}

// impl TryFrom<AccountState> for TowerStateResourceView {
// type Error = Error;

// fn try_from(state: AccountState) -> Result<TowerStateResourceView, Error> {
// let this_epoch = match state.get_configuration_resource()?{
// Some(cr) => cr.epoch(),
// None => bail!("cannot get epoch data from account state"),
// };

// let mut actual_count_proofs_in_epoch = 0;
// if let Some(m) = state.get_miner_state()? {
// if m.latest_epoch_mining == this_epoch {
// actual_count_proofs_in_epoch = m.count_proofs_in_epoch;
// }

// Ok(TowerStateResourceView {
// previous_proof_hash: BytesView::from( m.previous_proof_hash),
// verified_tower_height: m.verified_tower_height, // user's latest verified_tower_height
// latest_epoch_mining: m.latest_epoch_mining,
// count_proofs_in_epoch: m.count_proofs_in_epoch,
// epochs_validating_and_mining: m.epochs_validating_and_mining,
// contiguous_epochs_validating_and_mining: m.contiguous_epochs_validating_and_mining,
// epochs_since_last_account_creation: m.epochs_since_last_account_creation,
// // the proof count adjusted for lazy computation
// actual_count_proofs_in_epoch,
// })
// } else {
// bail!("could not get tower state")
// }
// }
// }

//////// 0L ////////
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct OracleUpgradeStateView {
Expand Down
1 change: 1 addition & 0 deletions ol/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ bcs = "0.1.2"
move-vm-types = { path = "../../language/move-vm/types" } # 0L todo: which move-vm/ path?
move-binary-format = { path = "../../language/move-binary-format" }
dialoguer = "0.8.0"
diem-crypto = { path = "../../crypto/crypto" }


# Parity with Storage create
Expand Down
14 changes: 7 additions & 7 deletions ol/cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,23 @@ mod version;
mod mgmt_cmd;
mod serve_cmd;
mod restore_cmd;
mod onboard_cmd;
mod query_cmd;
mod health_cmd;
mod pilot_cmd;
mod start_cmd;
mod whoami_cmd;

use self::{
init_cmd::InitCmd,
version::VersionCmd,
mgmt_cmd::MgmtCmd,
serve_cmd::ServeCmd,
restore_cmd::RestoreCmd,
onboard_cmd::OnboardCmd,
query_cmd::QueryCmd,
health_cmd::HealthCmd,
pilot_cmd::PilotCmd,
start_cmd::StartCmd,
whoami_cmd::WhoamiCmd,
};

use crate::entrypoint;
Expand Down Expand Up @@ -70,11 +70,7 @@ pub enum OlCliCmd {
/// The `restore` subcommand
#[options(help = "restore the database from the epoch-archive repository")]
Restore(RestoreCmd),

/// The `onboard` subcommand
#[options(help = "onboarding validator actions")]
Onboard(OnboardCmd),


/// The `query` subcommand
#[options(help = "run simple queries through subcommands, prints the value to stdout")]
Query(QueryCmd),
Expand All @@ -90,6 +86,10 @@ pub enum OlCliCmd {
/// The `start` subcommand
#[options(help = "start 0L services")]
Start(StartCmd),

/// The `whoami` subcommand
#[options(help = "show public keys and network protocols")]
Whoami(WhoamiCmd),
}

/// This trait allows you to define how application configuration is loaded.
Expand Down
55 changes: 37 additions & 18 deletions ol/cli/src/commands/init_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ pub struct InitCmd {
/// home path for app config
#[options(help = "home path for app config")]
path: Option<PathBuf>,

/// An upstream peer to use in 0L.toml
#[options(help = "An upstream peer to use in 0L.toml")]
// TODO: rename to json_rpc_peer
rpc_peer: Option<Url>,

/// Create the 0L.toml file for 0L apps
#[options(help = "Create the 0L.toml file for 0L apps")]
app: bool,
Expand All @@ -55,9 +56,11 @@ pub struct InitCmd {
/// Init key store file for validator
#[options(help = "Init key store file for validator")]
key_store: bool,

/// run checkup on config file
#[options(help = "Check config file and give hints if something seems wrong")]
checkup: bool,

/// fix the config file
#[options(help = "Fix config file, and migrate any missing fields")]
fix: bool,
Expand All @@ -69,6 +72,7 @@ pub struct InitCmd {
/// Set a waypoint in config files
#[options(help = "Manually set a waypoint. ")]
waypoint: Option<Waypoint>,

/// Path to source code, for devs
#[options(help = "Path to source code, for devs")]
source_path: Option<PathBuf>,
Expand Down Expand Up @@ -239,7 +243,10 @@ impl Runnable for InitCmd {
entry_args.swarm_persona,
&self.source_path,
)
.expect("could not initialize host with swarm configs");
.unwrap_or_else(|e| {
println!("could not initialize host with swarm configs, exiting. Message: {:?}", &e);
exit(1);
});
return;
}

Expand All @@ -253,21 +260,25 @@ impl Runnable for InitCmd {
match Confirm::new()
.with_prompt("This will overwrite an 0L.toml file if it exists. Proceed?")
.interact()
.unwrap()
{
true => {
initialize_app_cfg(
authkey,
account,
&self.rpc_peer,
&self.path,
&None, // TODO: probably need an epoch option here.
&self.waypoint,
&self.source_path,
)
.unwrap()
}
_ => panic!("Creating 0L.toml aborted"),
Ok(t) => {
if t {
initialize_app_cfg(
authkey,
account,
&self.rpc_peer,
&self.path,
&None, // TODO: probably need an epoch option here.
&self.waypoint,
&self.source_path,
)
.unwrap_or_else(|e| {
println!("could not initialize app configs 0L.toml, exiting. Message: {:?}", &e);
exit(1);
});
}
},
Err(_) => {},
};
return;
};
Expand Down Expand Up @@ -300,7 +311,11 @@ pub fn initialize_app_cfg(
source_path,
None,
None,
);
)
.unwrap_or_else(|e| {
println!("could not create app configs, exiting. Message: {:?}", &e);
exit(1);
});
Ok(cfg)
}

Expand All @@ -324,7 +339,11 @@ pub fn initialize_host_swarm(
if !&blocks_dir.exists() {
// first run, create the directory if there is none, or if the user changed the configs.
// note: user may have blocks but they are in a different directory than what miner.toml says.
fs::create_dir_all(&blocks_dir).unwrap();
fs::create_dir_all(&blocks_dir)
.unwrap_or_else(|e| {
println!("could not create directory for vdf proofs, exiting. Message: {:?}", &e);
exit(1);
})
};

match copy(&source, target_file, &CopyOptions::new()) {
Expand Down
51 changes: 0 additions & 51 deletions ol/cli/src/commands/onboard_cmd.rs

This file was deleted.

Loading

0 comments on commit 5f61e5e

Please sign in to comment.