From 0627b1ef47dc90e5c769c09bc9a609aee62eddea Mon Sep 17 00:00:00 2001 From: German Date: Mon, 4 Sep 2023 11:00:05 +0100 Subject: [PATCH] Detect `INK_STATIC_BUFFER_SIZE` env var (#1310) --- CHANGELOG.md | 1 + crates/build/src/lib.rs | 77 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21fbfaa9f..ae8600339 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Adds workflow for publishing docker images for the verifiable builds - [#1267](https://github.com/paritytech/cargo-contract/pull/1267) +- Detect `INK_STATIC_BUFFER_SIZE` env var - [#1310](https://github.com/paritytech/cargo-contract/pull/1310) - Add `verify` command - [#1306](https://github.com/paritytech/cargo-contract/pull/1306) ## [4.0.0-alpha] diff --git a/crates/build/src/lib.rs b/crates/build/src/lib.rs index 00598dcbb..da0c4f109 100644 --- a/crates/build/src/lib.rs +++ b/crates/build/src/lib.rs @@ -17,6 +17,7 @@ #![doc = include_str!("../README.md")] #![deny(unused_crate_dependencies)] +use contract_metadata::ContractMetadata; use which as _; mod args; @@ -370,6 +371,81 @@ fn exec_cargo_for_onchain_target( Ok(()) } +/// Check if the `INK_STATIC_BUFFER_SIZE` is set. +/// If so, then checks if the current contract has already been compiled with a new value. +/// If not, or metadata is not present, we need to clean binaries and rebuild. +fn check_buffer_size_invoke_cargo_clean( + crate_metadata: &CrateMetadata, + verbosity: &Verbosity, +) -> Result<()> { + if let Ok(buffer_size) = std::env::var("INK_STATIC_BUFFER_SIZE") { + let buffer_size_value: u64 = buffer_size + .parse() + .context("`INK_STATIC_BUFFER_SIZE` must have an integer value.")?; + + let extract_buffer_size = |metadata_path: PathBuf| -> Result { + let size = ContractMetadata::load(metadata_path) + .context("Metadata is not present")? + .abi + // get `spec` field + .get("spec") + .context("spec field should be present in ABI.")? + // get `environment` field + .get("environment") + .context("environment field should be present in ABI.")? + // get `staticBufferSize` field + .get("staticBufferSize") + .context("`staticBufferSize` must be specified.")? + // convert to u64 + .as_u64() + .context("`staticBufferSize` value must be an integer.")?; + + Ok(size) + }; + + let cargo = util::cargo_cmd( + "clean", + Vec::<&str>::new(), + crate_metadata.manifest_path.directory(), + *verbosity, + vec![], + ); + + match extract_buffer_size(crate_metadata.metadata_path()) { + Ok(contract_buffer_size) if contract_buffer_size == buffer_size_value => { + verbose_eprintln!( + verbosity, + "{} {}", + "info:".green().bold(), + "Detected a configured buffer size, but the value is already specified." + .bold() + ); + } + Ok(_) => { + verbose_eprintln!( + verbosity, + "{} {}", + "warning:".yellow().bold(), + "Detected a change in the configured buffer size. Rebuilding the project." + .bold() + ); + invoke_cargo_and_scan_for_error(cargo)?; + } + Err(_) => { + verbose_eprintln!( + verbosity, + "{} {}", + "warning:".yellow().bold(), + "Cannot find the previous size of the static buffer. Rebuilding the project." + .bold() + ); + invoke_cargo_and_scan_for_error(cargo)?; + } + } + } + Ok(()) +} + /// Executes the supplied cargo command, reading the output and scanning for known errors. /// Writes the captured stderr back to stderr and maintains the cargo tty progress bar. fn invoke_cargo_and_scan_for_error(cargo: duct::Expression) -> Result<()> { @@ -880,6 +956,7 @@ fn local_build( "[==]".bold(), "Building cargo project".bright_green().bold() ); + check_buffer_size_invoke_cargo_clean(crate_metadata, verbosity)?; exec_cargo_for_onchain_target( crate_metadata, "build",