Skip to content

Commit

Permalink
feat(epoch config): dump epoch configs in neard init for tests (#12343)
Browse files Browse the repository at this point in the history
Added a new parameter to `init`. 
Dump all the epoch configs between the given version and the latest
known protocol version.
  • Loading branch information
VanBarbascu authored Nov 5, 2024
1 parent de5edbc commit 39fab27
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 2 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 chain/indexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,5 +173,6 @@ pub fn indexer_init_configs(
params.download_config_url.as_deref(),
params.boot_nodes.as_deref(),
params.max_gas_burnt_view,
None,
)
}
1 change: 1 addition & 0 deletions core/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ bolero.workspace = true
insta.workspace = true
expect-test.workspace = true
regex.workspace = true
tempfile.workspace = true


[[bench]]
Expand Down
53 changes: 53 additions & 0 deletions core/primitives/src/epoch_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,34 @@ impl EpochConfigStore {
})
.1
}

fn dump_epoch_config(directory: &str, version: &ProtocolVersion, config: &Arc<EpochConfig>) {
let content = serde_json::to_string_pretty(config.as_ref()).unwrap();
let path = PathBuf::from(directory).join(format!("{}.json", version));
fs::write(path, content).unwrap();
}

/// Dumps all the configs between the beginning and end protocol versions to the given directory.
/// If the beginning version doesn't exist, the closest config to it will be dumped.
pub fn dump_epoch_configs_between(
&self,
first_version: &ProtocolVersion,
last_version: &ProtocolVersion,
directory: &str,
) {
// Dump all the configs between the beginning and end versions, inclusive.
self.store
.iter()
.filter(|(version, _)| *version >= first_version && *version <= last_version)
.for_each(|(version, config)| {
Self::dump_epoch_config(directory, version, config);
});
// Dump the closest config to the beginning version if it doesn't exist.
if !self.store.contains_key(&first_version) {
let config = self.get_config(*first_version);
Self::dump_epoch_config(directory, first_version, config);
}
}
}

#[cfg(test)]
Expand Down Expand Up @@ -628,6 +656,31 @@ mod tests {
}
}

#[test]
fn test_dump_epoch_configs_mainnet() {
let tmp_dir = tempfile::tempdir().unwrap();
EpochConfigStore::for_chain_id("mainnet", None).unwrap().dump_epoch_configs_between(
&55,
&68,
tmp_dir.path().to_str().unwrap(),
);

// Check if tmp dir contains the dumped files. 55, 64, 65.
let dumped_files = fs::read_dir(tmp_dir.path()).unwrap();
let dumped_files: Vec<_> =
dumped_files.map(|entry| entry.unwrap().file_name().into_string().unwrap()).collect();

assert!(dumped_files.contains(&String::from("55.json")));
assert!(dumped_files.contains(&String::from("64.json")));
assert!(dumped_files.contains(&String::from("65.json")));

// Check if 55.json is equal to 48.json from res/epcoh_configs/mainnet.
let contents_55 = fs::read_to_string(tmp_dir.path().join("55.json")).unwrap();
let epoch_config_55: EpochConfig = serde_json::from_str(&contents_55).unwrap();
let epoch_config_48 = parse_config_file("mainnet", 48).unwrap();
assert_eq!(epoch_config_55, epoch_config_48);
}

#[test]
#[ignore]
fn generate_epoch_configs_mainnet() {
Expand Down
23 changes: 22 additions & 1 deletion nearcore/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ use near_jsonrpc::RpcConfig;
use near_network::config::NetworkConfig;
use near_network::tcp;
use near_o11y::log_config::LogConfig;
use near_primitives::chains::MAINNET;
use near_primitives::epoch_manager::EpochConfigStore;
use near_primitives::hash::CryptoHash;
use near_primitives::shard_layout::ShardLayout;
use near_primitives::test_utils::create_test_signer;
Expand All @@ -45,7 +47,7 @@ use near_primitives::types::{
};
use near_primitives::utils::{from_timestamp, get_num_seats_per_shard};
use near_primitives::validator_signer::{InMemoryValidatorSigner, ValidatorSigner};
use near_primitives::version::PROTOCOL_VERSION;
use near_primitives::version::{ProtocolVersion, PROTOCOL_VERSION};
#[cfg(feature = "rosetta_rpc")]
use near_rosetta_rpc::RosettaRpcConfig;
use near_store::config::StateSnapshotType;
Expand Down Expand Up @@ -814,6 +816,7 @@ pub fn init_configs(
download_config_url: Option<&str>,
boot_nodes: Option<&str>,
max_gas_burnt_view: Option<Gas>,
dump_epoch_config: Option<ProtocolVersion>,
) -> anyhow::Result<()> {
fs::create_dir_all(dir).with_context(|| anyhow!("Failed to create directory {:?}", dir))?;

Expand Down Expand Up @@ -1007,6 +1010,21 @@ pub fn init_configs(
info!(target: "near", "Generated node key, validator key, genesis file in {}", dir.display());
}
}

if let Some(first_version) = dump_epoch_config {
let epoch_config_dir = dir.join("epoch_configs");
fs::create_dir_all(epoch_config_dir.clone())
.with_context(|| anyhow!("Failed to create directory {:?}", epoch_config_dir))?;
EpochConfigStore::for_chain_id(MAINNET, None)
.expect("Could not load the EpochConfigStore for mainnet.")
.dump_epoch_configs_between(
&first_version,
&PROTOCOL_VERSION,
epoch_config_dir.to_str().unwrap(),
);
info!(target: "near", "Generated epoch configs files in {}", epoch_config_dir.display());
}

Ok(())
}

Expand Down Expand Up @@ -1535,6 +1553,7 @@ mod tests {
None,
None,
None,
None,
)
.unwrap();
let genesis = Genesis::from_file(
Expand Down Expand Up @@ -1600,6 +1619,7 @@ mod tests {
None,
None,
None,
None,
)
.unwrap();

Expand Down Expand Up @@ -1633,6 +1653,7 @@ mod tests {
None,
None,
None,
None,
)
.unwrap();

Expand Down
32 changes: 31 additions & 1 deletion neard/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use near_o11y::{
use near_ping::PingCommand;
use near_primitives::hash::CryptoHash;
use near_primitives::merkle::compute_root_from_path;
use near_primitives::types::{Gas, NumSeats, NumShards, ShardId};
use near_primitives::types::{Gas, NumSeats, NumShards, ProtocolVersion, ShardId};
use near_replay_archive_tool::ReplayArchiveCommand;
use near_state_parts::cli::StatePartsCommand;
use near_state_parts_dump_check::cli::StatePartsDumpCheckCommand;
Expand Down Expand Up @@ -255,6 +255,26 @@ pub(super) enum NeardSubCommand {
ReplayArchive(ReplayArchiveCommand),
}

#[derive(Debug, Clone)]
enum FirstProtocolVersion {
Since(ProtocolVersion),
Latest,
}

impl FromStr for FirstProtocolVersion {
type Err = String;

fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"latest" => Ok(FirstProtocolVersion::Latest),
_ => input
.parse::<ProtocolVersion>()
.map(FirstProtocolVersion::Since)
.map_err(|_| format!("Invalid value for FirstProtocolVersion: {}", input)),
}
}
}

#[derive(clap::Parser)]
pub(super) struct InitCmd {
/// Download the verified NEAR genesis file automatically.
Expand Down Expand Up @@ -300,6 +320,10 @@ pub(super) struct InitCmd {
/// from genesis configuration will be taken.
#[clap(long)]
max_gas_burnt_view: Option<Gas>,
/// Dump epoch config from the given protocol version onwards.
/// Can be a number or the word "latest".
#[clap(long)]
dump_epoch_config: Option<FirstProtocolVersion>,
}

/// Warns if unsupported build of the executable is used on mainnet or testnet.
Expand Down Expand Up @@ -357,6 +381,11 @@ impl InitCmd {
None
};

let dump_epoch_config = self.dump_epoch_config.map(|first| match first {
FirstProtocolVersion::Since(version) => version,
FirstProtocolVersion::Latest => near_primitives::version::PROTOCOL_VERSION,
});

nearcore::init_configs(
home_dir,
self.chain_id,
Expand All @@ -372,6 +401,7 @@ impl InitCmd {
self.download_config_url.as_deref(),
self.boot_nodes.as_deref(),
self.max_gas_burnt_view,
dump_epoch_config,
)
.context("Failed to initialize configs")
}
Expand Down
1 change: 1 addition & 0 deletions runtime/runtime-params-estimator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ fn run_estimation(cli_args: CliArgs) -> anyhow::Result<Option<CostTable>> {
None,
None,
None,
None,
)
.expect("failed to init config");

Expand Down

0 comments on commit 39fab27

Please sign in to comment.