Skip to content

Commit

Permalink
feat: add version to template WASMs (#835)
Browse files Browse the repository at this point in the history
Description
---
* Updated the template definition in the ABI to include the Tari version
it was compiled on
* Validator nodes call this new function when loading a new template
WASM for execution, and check the version against the engine's own
version. For now, no errors are returned even if they don't match, only
logging is performed.

Motivation and Context
---
We want to know the Tari version (i.e. the Cargo package version of the
project) that a template was compiled with, as this determines the
engine calls that it may request during execution. The goal is to be
able to detect version incompatibilities when executing.

For now this PR only adds the version to the template WASMs and logs
version match/mismatch, no error is returned. In the future this setup
will allow us to load the appropriate `template_lib` version (and/or
other dependencies) for each template and avoid incompatibilities.

How Has This Been Tested?
---
Launching a local network and inspecting the VN logs when executing a
transaction for the Tari version messages

What process can a PR reviewer use to test or verify this change?
---
Inspect the VN logs when executing a transaction for the Tari version
messages

Breaking Changes
---

- [ ] None
- [ ] Requires data directory to be deleted
- [x] Breaking change: the Template ABI changes so all templates
(included the built-in ones) must be recompiled
  • Loading branch information
mrnaveira authored Dec 13, 2023
1 parent cb2d694 commit 8612eab
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 0 deletions.
3 changes: 3 additions & 0 deletions dan_layer/engine/src/flow/flow_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use crate::{
template::LoadedTemplate,
};

pub const TARI_VERSION: &str = env!("CARGO_PKG_VERSION");

#[derive(Debug, Clone)]
pub struct FlowFactory {
name: String,
Expand All @@ -29,6 +31,7 @@ impl FlowFactory {
) -> Result<Self, FlowEngineError> {
let template_def = TemplateDef::V1(TemplateDefV1 {
template_name: flow_definition.name.clone(),
tari_version: TARI_VERSION.to_owned(),
functions: vec![FunctionDef {
name: "main".to_string(),
arguments: flow_definition
Expand Down
20 changes: 20 additions & 0 deletions dan_layer/engine/src/wasm/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ use crate::{
LoadedWasmTemplate,
},
};

const LOG_TARGET: &str = "tari::dan::engine::wasm::process";
pub const ENGINE_TARI_VERSION: &str = env!("CARGO_PKG_VERSION");

#[derive(Debug)]
pub struct WasmProcess {
module: LoadedWasmTemplate,
Expand All @@ -69,6 +72,7 @@ impl WasmProcess {
let tari_engine = Function::new_native_with_env(store, env.clone(), Self::tari_engine_entrypoint);
let resolver = env.create_resolver(store, tari_engine);
let instance = Instance::new(module.wasm_module(), &resolver)?;
Self::validate_template_tari_version(&module)?;
env.init_with_instance(&instance)?;
Ok(Self { module, env, instance })
}
Expand Down Expand Up @@ -203,6 +207,22 @@ impl WasmProcess {
fn encoded_abi_context(&self) -> Vec<u8> {
encode(&AbiContext {}).unwrap()
}

/// Determine if the version of the template_lib crate in the WASM is valid.
/// This is just a placeholder that logs the result, as we don't manage version incompatiblities yet
fn validate_template_tari_version(module: &LoadedWasmTemplate) -> Result<(), WasmExecutionError> {
let template_tari_version = module.template_def().tari_version();

if template_tari_version == ENGINE_TARI_VERSION {
log::info!(target: LOG_TARGET, "The Tari version version in the template WASM (\"{}\") matches the one used in the engine", template_tari_version);
} else {
// For now we are going to ignore version mismatches
// In the future we could load a different version of the template_lib in the engine
log::warn!(target: LOG_TARGET, "The Tari version in the template WASM (\"{}\") does not matches the one used in the engine (\"{}\")", template_tari_version, ENGINE_TARI_VERSION);
}

Ok(())
}
}

impl Invokable for WasmProcess {
Expand Down
7 changes: 7 additions & 0 deletions dan_layer/template_abi/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ impl TemplateDef {
}
}

pub fn tari_version(&self) -> &str {
match self {
TemplateDef::V1(def) => def.tari_version.as_str(),
}
}

pub fn get_function(&self, name: &str) -> Option<&FunctionDef> {
match self {
TemplateDef::V1(def) => def.get_function(name),
Expand All @@ -52,6 +58,7 @@ impl TemplateDef {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TemplateDefV1 {
pub template_name: String,
pub tari_version: String,
pub functions: Vec<FunctionDef>,
}

Expand Down
3 changes: 3 additions & 0 deletions dan_layer/template_macros/src/template/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@ use tari_template_abi::{

use crate::template::ast::{TemplateAst, TypeAst};

pub const TARI_VERSION: &str = env!("CARGO_PKG_VERSION");

pub fn generate_abi(ast: &TemplateAst) -> Result<TokenStream> {
let template_name_as_str = ast.template_name.to_string();

let template_def = TemplateDef::V1(TemplateDefV1 {
template_name: template_name_as_str.clone(),
tari_version: TARI_VERSION.to_owned(),
functions: ast
.get_functions()
.map(|func| {
Expand Down

0 comments on commit 8612eab

Please sign in to comment.