Skip to content

Commit

Permalink
Merge branch 'grarco/validate-wasm' (#1902)
Browse files Browse the repository at this point in the history
* origin/grarco/validate-wasm:
  changelog: add #1902
  Adds a client utility to validate wasm code
  Validate wasm code in `init_chain`
  • Loading branch information
Fraccaman committed Sep 25, 2023
2 parents 592b907 + 0696199 commit b5653ad
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 0 deletions.
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 @@ -1900,6 +1900,7 @@ pub mod cmds {
pub enum Utils {
JoinNetwork(JoinNetwork),
FetchWasms(FetchWasms),
ValidateWasm(ValidateWasm),
InitNetwork(InitNetwork),
InitGenesisValidator(InitGenesisValidator),
PkToTmAddress(PkToTmAddress),
Expand All @@ -1915,6 +1916,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 @@ -1926,6 +1929,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 @@ -1939,6 +1943,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 @@ -1987,6 +1992,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 @@ -5490,6 +5517,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 @@ -670,6 +670,9 @@ impl<IO: 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 @@ -14,6 +14,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 @@ -362,6 +363,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 @@ -16,6 +16,7 @@ use namada::types::dec::Dec;
use namada::types::hash::Hash as CodeHash;
use namada::types::key::*;
use namada::types::time::{DateTimeUtc, TimeZone, Utc};
use namada::vm::validate_untrusted_wasm;

use super::*;
use crate::facade::tendermint_proto::google::protobuf;
Expand Down Expand Up @@ -121,6 +122,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

0 comments on commit b5653ad

Please sign in to comment.