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

ledger: remove wasm downloader #3598

Merged
merged 2 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changelog/unreleased/improvements/3598-remove-wasm-loader.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Do not try to download wasms artifacts from an untrusted source.
([\#3598](https://github.com/anoma/namada/pull/3598))
7 changes: 0 additions & 7 deletions crates/apps_lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3267,7 +3267,6 @@ pub mod args {
arg("destination-validator");
pub const DISCORD_OPT: ArgOpt<String> = arg_opt("discord-handle");
pub const DO_IT: ArgFlag = flag("do-it");
pub const DONT_PREFETCH_WASM: ArgFlag = flag("dont-prefetch-wasm");
pub const DRY_RUN_TX: ArgFlag = flag("dry-run");
pub const DRY_RUN_WRAPPER_TX: ArgFlag = flag("dry-run-wrapper");
pub const DUMP_TX: ArgFlag = flag("dump-tx");
Expand Down Expand Up @@ -7767,7 +7766,6 @@ pub mod args {
pub chain_id: ChainId,
pub genesis_validator: Option<String>,
pub pre_genesis_path: Option<PathBuf>,
pub dont_prefetch_wasm: bool,
pub allow_duplicate_ip: bool,
pub add_persistent_peers: bool,
}
Expand All @@ -7777,14 +7775,12 @@ pub mod args {
let chain_id = CHAIN_ID.parse(matches);
let genesis_validator = GENESIS_VALIDATOR.parse(matches);
let pre_genesis_path = PRE_GENESIS_PATH.parse(matches);
let dont_prefetch_wasm = DONT_PREFETCH_WASM.parse(matches);
let allow_duplicate_ip = ALLOW_DUPLICATE_IP.parse(matches);
let add_persistent_peers = ADD_PERSISTENT_PEERS.parse(matches);
Self {
chain_id,
genesis_validator,
pre_genesis_path,
dont_prefetch_wasm,
allow_duplicate_ip,
add_persistent_peers,
}
Expand All @@ -7795,9 +7791,6 @@ pub mod args {
https://github.com/heliaxdev/anoma-network-config")))
.arg(GENESIS_VALIDATOR.def().help(wrap!("The alias of the genesis validator that you want to set up as, if any.")))
.arg(PRE_GENESIS_PATH.def().help(wrap!("The path to the pre-genesis directory for genesis validator, if any. Defaults to \"{base-dir}/pre-genesis/{genesis-validator}\".")))
.arg(DONT_PREFETCH_WASM.def().help(wrap!(
"Do not pre-fetch WASM.")
))
.arg(ALLOW_DUPLICATE_IP.def().help(wrap!(
"Toggle to disable guard against peers connecting from the \
same IP. This option shouldn't be used in mainnet.")
Expand Down
12 changes: 5 additions & 7 deletions crates/apps_lib/src/client/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ pub async fn join_network(
chain_id,
genesis_validator,
pre_genesis_path,
dont_prefetch_wasm,
allow_duplicate_ip,
add_persistent_peers,
}: args::JoinNetwork,
Expand Down Expand Up @@ -250,9 +249,8 @@ pub async fn join_network(
config.wasm_dir = wasm_dir_full;
}

if !dont_prefetch_wasm {
fetch_wasms_aux(&chain_id, &config.wasm_dir).await;
}
// Validate the wasm artifacts checksums
validate_wasm_artifacts_aux(&chain_id, &config.wasm_dir).await;

// Save the config and the wallet
config.write(&base_dir, &chain_id, true).unwrap();
Expand All @@ -261,9 +259,9 @@ pub async fn join_network(
println!("Successfully configured for chain ID {chain_id}");
}

async fn fetch_wasms_aux(chain_id: &ChainId, wasm_dir: &Path) {
println!("Fetching missing wasms for chain ID {chain_id}...");
wasm_loader::pre_fetch_wasm(wasm_dir).await;
async fn validate_wasm_artifacts_aux(chain_id: &ChainId, wasm_dir: &Path) {
println!("Validating wasms artifacts for chain ID {chain_id}...");
wasm_loader::validate_wasm_artifacts(wasm_dir).await;
}

pub fn validate_wasm(args::ValidateWasm { code_path }: args::ValidateWasm) {
Expand Down
108 changes: 13 additions & 95 deletions crates/apps_lib/src/wasm_loader/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! A module for loading WASM files and downloading pre-built WASMs.
use core::borrow::Borrow;
use std::fs;
use std::path::Path;

Expand Down Expand Up @@ -35,10 +34,6 @@ pub enum Error {
#[serde(transparent)]
pub struct Checksums(pub HashMap<String, String>);

/// Github URL prefix of released Namada network configs
pub const ENV_VAR_WASM_SERVER: &str = "NAMADA_NETWORK_WASM_SERVER";
const DEFAULT_WASM_SERVER: &str = "https://artifacts.heliax.click/namada-wasm";

impl Checksums {
/// Read WASM checksums from the given path
pub fn read_checksums_file(
Expand Down Expand Up @@ -115,12 +110,6 @@ impl Checksums {
}
}

fn wasm_url(wasm_name: &str) -> String {
let prefix_url = std::env::var(ENV_VAR_WASM_SERVER)
.unwrap_or_else(|_| DEFAULT_WASM_SERVER.to_string());
format!("{}/{}", prefix_url, wasm_name)
}

fn valid_wasm_checksum(
wasm_payload: &[u8],
name: &str,
Expand All @@ -141,9 +130,8 @@ fn valid_wasm_checksum(
}
}

/// Download all the pre-built wasms, or if they're already downloaded, verify
/// their checksums.
pub async fn pre_fetch_wasm(wasm_directory: impl AsRef<Path>) {
/// Validate wasm artifacts
pub async fn validate_wasm_artifacts(wasm_directory: impl AsRef<Path>) {
// load json with wasm hashes
let checksums = Checksums::read_checksums_async(&wasm_directory).await;

Expand All @@ -154,69 +142,29 @@ pub async fn pre_fetch_wasm(wasm_directory: impl AsRef<Path>) {
tokio::spawn(async move {
let wasm_path = wasm_directory.join(&full_name);
match tokio::fs::read(&wasm_path).await {
// if the file exist, first check the hash. If not matching
// download it again.
// if the file exist, check the hash
Ok(bytes) => {
if let Err(derived_name) =
valid_wasm_checksum(&bytes, &name, &full_name)
{
tracing::info!(
"WASM checksum mismatch: Got {}, expected {}. \
Fetching new version...",
Check your wasms artifacts.",
derived_name,
full_name
);
} else {
return;
}

match download_wasm(&name, &full_name).await {
Ok(bytes) => {
if let Err(e) =
tokio::fs::write(wasm_path, &bytes).await
{
eprintln!(
"Error while creating file for {}: {}",
&name, e
);
safe_exit(1);
}
}
Err(e) => {
eprintln!("Error downloading wasm: {}", e);
safe_exit(1);
}
safe_exit(1);
}
}
// if the doesn't file exist, download it.
Err(err) => match err.kind() {
std::io::ErrorKind::NotFound => {
match download_wasm(&name, &full_name).await {
Ok(bytes) => {
if let Err(e) =
tokio::fs::write(wasm_path, &bytes).await
{
eprintln!(
"Error while creating file for {}: {}",
&name, e
);
safe_exit(1);
}
}
Err(e) => {
eprintln!("Error downloading wasm: {}", e);
safe_exit(1);
}
}
}
_ => {
eprintln!(
"Can't read {}.",
wasm_path.as_os_str().to_string_lossy()
);
safe_exit(1);
}
},
Err(err) => {
eprintln!(
"Can't read {}: {}",
wasm_path.as_os_str().to_string_lossy(),
err
);
safe_exit(1);
}
}
})
}))
Expand Down Expand Up @@ -270,33 +218,3 @@ pub fn read_wasm_or_exit(
}
}
}

async fn download_wasm(name: &str, full_name: &str) -> Result<Vec<u8>, Error> {
let url = wasm_url(full_name);

tracing::info!("Downloading WASM {url}...");

let response = reqwest::get(&url).await;

match response {
Ok(body) => {
let status = body.status();
if status.is_success() {
let bytes = body.bytes().await.unwrap();
let bytes: &[u8] = bytes.borrow();

valid_wasm_checksum(bytes, name, full_name)
.map_err(Error::ChecksumMismatch)?;

let bytes: Vec<u8> = bytes.to_owned();

Ok(bytes)
} else if status.is_server_error() {
Err(Error::WasmNotFound(url))
} else {
Err(Error::ServerError(url, status.to_string()))
}
}
Err(e) => Err(Error::Download(url, e)),
}
}
3 changes: 1 addition & 2 deletions crates/node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,7 @@ async fn run_aux_setup(
wasm_dir: &PathBuf,
scheduled_migration: Option<ScheduledMigration>,
) -> RunAuxSetup {
// Prefetch needed wasm artifacts
wasm_loader::pre_fetch_wasm(wasm_dir).await;
wasm_loader::validate_wasm_artifacts(wasm_dir).await;

// Find the system available memory
let available_memory_bytes = Lazy::new(|| {
Expand Down
8 changes: 1 addition & 7 deletions crates/tests/src/e2e/ledger_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2143,13 +2143,7 @@ fn test_sync_chain() -> Result<()> {
// Setup the chain
let mut join_network = setup::run_cmd(
Bin::Client,
[
"utils",
"join-network",
"--chain-id",
chain_id_raw.as_str(),
"--dont-prefetch-wasm",
],
["utils", "join-network", "--chain-id", chain_id_raw.as_str()],
Some(60),
&test.working_dir,
base_dir,
Expand Down
2 changes: 0 additions & 2 deletions crates/tests/src/e2e/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,6 @@ pub fn network(
net.chain_id.as_str(),
"--genesis-validator",
&alias,
"--dont-prefetch-wasm",
],
Some(5),
&working_dir,
Expand Down Expand Up @@ -561,7 +560,6 @@ pub fn network(
"--add-persistent-peers",
"--chain-id",
net.chain_id.as_str(),
"--dont-prefetch-wasm",
],
Some(5),
&working_dir,
Expand Down
1 change: 0 additions & 1 deletion scripts/gen_localnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ def join_network(
genesis_validator,
"--pre-genesis-path",
genesis_validator_path,
"--dont-prefetch-wasm",
)

info(f"Validator {genesis_validator} joined {chain_id}")
Expand Down