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

Validate wasm in init_chain #1902

Merged
merged 3 commits into from
Sep 25, 2023
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/bug-fixes/1902-validate-wasm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Added wasm validation in `init_chain` and in client utils.
([\#1902](https://github.com/anoma/namada/pull/1902))
47 changes: 47 additions & 0 deletions apps/src/lib/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1898,6 +1898,7 @@ pub mod cmds {
pub enum Utils {
JoinNetwork(JoinNetwork),
FetchWasms(FetchWasms),
ValidateWasm(ValidateWasm),
InitNetwork(InitNetwork),
InitGenesisValidator(InitGenesisValidator),
PkToTmAddress(PkToTmAddress),
Expand All @@ -1913,6 +1914,8 @@ pub mod cmds {
let join_network =
SubCmd::parse(matches).map(Self::JoinNetwork);
let fetch_wasms = SubCmd::parse(matches).map(Self::FetchWasms);
let validate_wasm =
SubCmd::parse(matches).map(Self::ValidateWasm);
let init_network =
SubCmd::parse(matches).map(Self::InitNetwork);
let init_genesis =
Expand All @@ -1924,6 +1927,7 @@ pub mod cmds {
let epoch_sleep = SubCmd::parse(matches).map(Self::EpochSleep);
join_network
.or(fetch_wasms)
.or(validate_wasm)
.or(init_network)
.or(init_genesis)
.or(pk_to_tm_address)
Expand All @@ -1937,6 +1941,7 @@ pub mod cmds {
.about("Utilities.")
.subcommand(JoinNetwork::def())
.subcommand(FetchWasms::def())
.subcommand(ValidateWasm::def())
.subcommand(InitNetwork::def())
.subcommand(InitGenesisValidator::def())
.subcommand(PkToTmAddress::def())
Expand Down Expand Up @@ -1985,6 +1990,28 @@ pub mod cmds {
}
}

#[derive(Clone, Debug)]
pub struct ValidateWasm(pub args::ValidateWasm);

impl SubCmd for ValidateWasm {
const CMD: &'static str = "validate-wasm";

fn parse(matches: &ArgMatches) -> Option<Self> {
matches
.subcommand_matches(Self::CMD)
.map(|matches| Self(args::ValidateWasm::parse(matches)))
}

fn def() -> App {
App::new(Self::CMD)
.about(
"Check that the provided wasm code is valid by the Namada \
standards.",
)
.add_args::<args::ValidateWasm>()
}
}

#[derive(Clone, Debug)]
pub struct InitNetwork(pub args::InitNetwork);

Expand Down Expand Up @@ -5481,6 +5508,26 @@ pub mod args {
}
}

#[derive(Clone, Debug)]
pub struct ValidateWasm {
pub code_path: PathBuf,
}

impl Args for ValidateWasm {
fn parse(matches: &ArgMatches) -> Self {
let code_path = CODE_PATH.parse(matches);
Self { code_path }
}

fn def(app: App) -> App {
app.arg(
CODE_PATH
.def()
.help("The path to the wasm file to validate."),
)
}
}

#[derive(Clone, Debug)]
pub struct InitNetwork {
pub genesis_path: PathBuf,
Expand Down
3 changes: 3 additions & 0 deletions apps/src/lib/cli/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,9 @@ impl<IO> CliApi<IO> {
Utils::FetchWasms(FetchWasms(args)) => {
utils::fetch_wasms(global_args, args).await
}
Utils::ValidateWasm(ValidateWasm(args)) => {
utils::validate_wasm(args)
}
Utils::InitNetwork(InitNetwork(args)) => {
utils::init_network(global_args, args)
}
Expand Down
12 changes: 12 additions & 0 deletions apps/src/lib/client/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use namada::types::address;
use namada::types::chain::ChainId;
use namada::types::dec::Dec;
use namada::types::key::*;
use namada::vm::validate_untrusted_wasm;
use prost::bytes::Bytes;
use rand::prelude::ThreadRng;
use rand::thread_rng;
Expand Down Expand Up @@ -363,6 +364,17 @@ pub async fn fetch_wasms_aux(base_dir: &Path, chain_id: &ChainId) {
wasm_loader::pre_fetch_wasm(&wasm_dir).await;
}

pub fn validate_wasm(args::ValidateWasm { code_path }: args::ValidateWasm) {
let code = std::fs::read(code_path).unwrap();
match validate_untrusted_wasm(code) {
Ok(()) => println!("Wasm code is valid"),
Err(e) => {
eprintln!("Wasm code is invalid: {e}");
cli::safe_exit(1)
}
}
}

/// Length of a Tendermint Node ID in bytes
const TENDERMINT_NODE_ID_LENGTH: usize = 20;

Expand Down
4 changes: 4 additions & 0 deletions apps/src/lib/node/ledger/shell/init_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use namada::types::hash::Hash as CodeHash;
use namada::types::key::*;
use namada::types::time::{DateTimeUtc, TimeZone, Utc};
use namada::types::token;
use namada::vm::validate_untrusted_wasm;

use super::*;
use crate::facade::tendermint_proto::google::protobuf;
Expand Down Expand Up @@ -142,6 +143,9 @@ where
|| tx_whitelist.contains(&code_hash.to_string().to_lowercase())
|| vp_whitelist.contains(&code_hash.to_string().to_lowercase())
{
validate_untrusted_wasm(&code)
.map_err(|e| Error::LoadingWasm(e.to_string()))?;

#[cfg(not(test))]
if name.starts_with("tx_") {
self.tx_wasm_cache.pre_compile(&code);
Expand Down
Loading