Skip to content

Commit

Permalink
genesis: check contents of onchain validator set after building genesis
Browse files Browse the repository at this point in the history
  • Loading branch information
bmwill committed Jul 15, 2022
1 parent a3c75b8 commit 8a2cb1c
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 14 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.

1 change: 1 addition & 0 deletions crates/sui-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ edition = "2021"
[dependencies]
bcs = "0.1.3"
arc-swap = "1.5.0"
camino = "1.0.9"
anyhow = { version = "1.0.58", features = ["backtrace"] }
serde = { version = "1.0.139", features = ["derive"] }
serde_yaml = "0.8.25"
Expand Down
45 changes: 41 additions & 4 deletions crates/sui-config/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use crate::ValidatorInfo;
use anyhow::{bail, Context, Result};
use camino::Utf8Path;
use move_binary_format::CompiledModule;
use move_core_types::ident_str;
use move_core_types::language_storage::ModuleId;
Expand Down Expand Up @@ -242,24 +243,56 @@ impl Builder {
let objects =
create_genesis_objects(&mut genesis_ctx, &modules, &objects, &self.validators);

Genesis {
let genesis = Genesis {
objects,
validator_set: self.validators,
};

// Verify that all the validators were properly created onchain
let system_object = genesis.sui_system_object();
assert_eq!(system_object.epoch, 0);

for (validator, onchain_validator) in genesis
.validator_set()
.iter()
.zip(system_object.validators.active_validators.iter())
{
assert_eq!(validator.stake(), onchain_validator.stake_amount);
assert_eq!(
validator.sui_address().to_vec(),
onchain_validator.metadata.sui_address.to_vec(),
);
assert_eq!(
validator.public_key().to_vec(),
onchain_validator.metadata.pubkey_bytes,
);
assert_eq!(validator.name().as_bytes(), onchain_validator.metadata.name);
assert_eq!(
validator.network_address().to_vec(),
onchain_validator.metadata.net_address
);
}

genesis
}

pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, anyhow::Error> {
let path = path.as_ref();
trace!("Reading Genesis Builder from {}", path.display());
let path: &Utf8Path = path.try_into()?;
trace!("Reading Genesis Builder from {}", path);

if !path.is_dir() {
bail!("path must be a directory");
}

// Load Objects
let mut objects = Vec::new();
for entry in std::fs::read_dir(path.join(GENESIS_BUILDER_OBJECT_DIR))? {
for entry in path.join(GENESIS_BUILDER_OBJECT_DIR).read_dir_utf8()? {
let entry = entry?;
if entry.file_name().starts_with('.') {
continue;
}

let path = entry.path();
let object_bytes = fs::read(path)?;
let object: Object = serde_yaml::from_slice(&object_bytes)?;
Expand All @@ -268,8 +301,12 @@ impl Builder {

// Load validator infos
let mut committee = Vec::new();
for entry in std::fs::read_dir(path.join(GENESIS_BUILDER_COMMITTEE_DIR))? {
for entry in path.join(GENESIS_BUILDER_COMMITTEE_DIR).read_dir_utf8()? {
let entry = entry?;
if entry.file_name().starts_with('.') {
continue;
}

let path = entry.path();
let validator_info_bytes = fs::read(path)?;
let validator_info: ValidatorInfo = serde_yaml::from_slice(&validator_info_bytes)?;
Expand Down
44 changes: 34 additions & 10 deletions crates/sui/src/genesis_ceremony.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use anyhow::Result;
use clap::Parser;
use multiaddr::Multiaddr;
use std::path::PathBuf;
use sui_config::{genesis::Builder, SUI_GENESIS_FILENAME};
use sui_config::{
genesis::{Builder, Genesis},
SUI_GENESIS_FILENAME,
};
use sui_types::{
base_types::{ObjectID, SuiAddress},
crypto::PublicKeyBytes,
Expand All @@ -15,7 +18,7 @@ use sui_types::{
#[derive(Parser)]
pub struct Ceremony {
#[clap(long)]
path: PathBuf,
path: Option<PathBuf>,

#[clap(subcommand)]
command: CeremonyCommand,
Expand Down Expand Up @@ -43,16 +46,23 @@ pub enum CeremonyCommand {
},

Finalize,

Verify,
}

pub fn run(cmd: Ceremony) -> Result<()> {
let dir = if let Some(path) = cmd.path {
path
} else {
std::env::current_dir()?
};

match cmd.command {
CeremonyCommand::Init => {
let builder = Builder::new();
builder.save(cmd.path)?;
builder.save(dir)?;
}

//TODO this will need to include Narwhal network information
CeremonyCommand::AddValidator {
name,
public_key,
Expand All @@ -63,7 +73,7 @@ pub fn run(cmd: Ceremony) -> Result<()> {
narwhal_worker_to_worker,
narwhal_consensus_address,
} => {
let mut builder = Builder::load(&cmd.path)?;
let mut builder = Builder::load(&dir)?;
builder = builder.add_validator(sui_config::ValidatorInfo {
name,
public_key,
Expand All @@ -76,29 +86,43 @@ pub fn run(cmd: Ceremony) -> Result<()> {
narwhal_worker_to_worker,
narwhal_consensus_address,
});
builder.save(cmd.path)?;
builder.save(dir)?;
}

CeremonyCommand::AddGasObject {
address,
object_id,
value,
} => {
let mut builder = Builder::load(&cmd.path)?;
let mut builder = Builder::load(&dir)?;

let object_id = object_id.unwrap_or_else(ObjectID::random);
let object = Object::with_id_owner_gas_for_testing(object_id, address, value);
builder = builder.add_object(object);

builder.save(cmd.path)?;
builder.save(dir)?;
}

CeremonyCommand::Finalize => {
let builder = Builder::load(&cmd.path)?;
let builder = Builder::load(&dir)?;

let genesis = builder.build();

genesis.save(cmd.path.join(SUI_GENESIS_FILENAME))?;
genesis.save(dir.join(SUI_GENESIS_FILENAME))?;
}

CeremonyCommand::Verify => {
let loaded_genesis = Genesis::load(dir.join(SUI_GENESIS_FILENAME))?;

let builder = Builder::load(&dir)?;

let built_genesis = builder.build();

if built_genesis != loaded_genesis {
return Err(anyhow::anyhow!(
"loaded genesis does not match built genesis"
));
}
}
}

Expand Down

0 comments on commit 8a2cb1c

Please sign in to comment.