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

Modify static buffer size via env var #1869

Merged
merged 14 commits into from
Aug 18, 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
6 changes: 5 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,11 @@ examples-test:
cargo test --verbose --manifest-path ${example}/Cargo.toml --features "foo, bar";
fi;
if grep -q "e2e-tests = \[\]" "${example}/Cargo.toml"; then
cargo test --verbose --manifest-path ${example}/Cargo.toml --features e2e-tests;
if [ "$example" = "integration-tests/static-buffer/" ]; then
cargo clean && INK_STATIC_BUFFER_SIZE=30 cargo test --verbose --manifest-path ${example}/Cargo.toml --features e2e-tests && cargo clean;
else
cargo test --verbose --manifest-path ${example}/Cargo.toml --features e2e-tests;
fi;
else
cargo test --verbose --manifest-path ${example}/Cargo.toml;
fi;
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
- Stabilize `call_runtime` ‒ [#1749](https://github.com/paritytech/ink/pull/1749)
- Make E2E testcases generic over `E2EBackend` trait - [#1867](https://github.com/paritytech/ink/pull/1867)
- Modify static buffer size via environmental variables - [#1869](https://github.com/paritytech/ink/pull/1869)

### Added
- Schema generation - [#1765](https://github.com/paritytech/ink/pull/1765)
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ tracing-subscriber = { version = "0.3.17" }
trybuild = { version = "1.0.60" }
which = { version = "4.4.0" }
xxhash-rust = { version = "0.8" }
const_env = { version = "0.1"}

# Substrate dependencies
pallet-contracts-primitives = { version = "24.0.0", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions crates/env/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ cfg-if = { workspace = true }
paste = { workspace = true }
arrayref = { workspace = true }
static_assertions = { workspace = true }
const_env = { workspace = true }

[target.'cfg(target_arch = "wasm32")'.dependencies]
rlibc = "1"
Expand Down
2 changes: 1 addition & 1 deletion crates/env/src/engine/off_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use ink_storage_traits::Storable;
/// The capacity of the static buffer.
/// This is the same size as the ink! on-chain environment. We chose to use the same size
/// to be as close to the on-chain behavior as possible.
const BUFFER_SIZE: usize = 1 << 14; // 16 kB
const BUFFER_SIZE: usize = crate::BUFFER_SIZE;

impl CryptoHash for Blake2x128 {
fn hash(input: &[u8], output: &mut <Self as HashOutput>::Type) {
Expand Down
8 changes: 5 additions & 3 deletions crates/env/src/engine/on_chain/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.

/// A static buffer with 16 kB of capacity.
/// A static buffer of variable capacity.
pub struct StaticBuffer {
/// The static buffer with a total capacity of 16 kB.
/// A static buffer of variable capacity.
buffer: [u8; Self::CAPACITY],
}

impl StaticBuffer {
/// The capacity of the static buffer.
const CAPACITY: usize = 1 << 14; // 16 kB
/// Usually set to 16 kB.
/// Can be modified by setting `INK_STATIC_BUFFER_SIZE` environmental variable.
const CAPACITY: usize = crate::BUFFER_SIZE;

/// Creates a new static buffer.
pub const fn new() -> Self {
Expand Down
6 changes: 6 additions & 0 deletions crates/env/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@
unused_extern_crates
)]

/// The capacity of the static buffer.
/// Usually set to 16 kB.
/// Can be modified by setting `INK_STATIC_BUFFER_SIZE` environmental variable.
#[const_env::from_env("INK_STATIC_BUFFER_SIZE")]
pub const BUFFER_SIZE: usize = 16384;

#[cfg(all(not(feature = "std"), target_arch = "wasm32"))]
#[allow(unused_extern_crates)]
extern crate rlibc;
Expand Down
9 changes: 9 additions & 0 deletions integration-tests/static-buffer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Ignore build artifacts from the local tests sub-crate.
/target/

# Ignore backup files creates by cargo fmt.
**/*.rs.bk

# Remove Cargo.lock when creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock
28 changes: 28 additions & 0 deletions integration-tests/static-buffer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "static-buffer"
version = "4.2.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
publish = false

[dependencies]
ink = { path = "../../crates/ink", default-features = false }

scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true }

[dev-dependencies]
ink_e2e = { path = "../../crates/e2e" }

[lib]
path = "lib.rs"

[features]
default = ["std"]
std = [
"ink/std",
"scale/std",
"scale-info/std",
]
ink-as-dependency = []
e2e-tests = []
18 changes: 18 additions & 0 deletions integration-tests/static-buffer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Static buffer configuration demo

This is a dummy contract illustrating how the [static buffer](/ARCHITECTURE.md#communication-with-the-pallet)
can be be configured using the environmental variables.

Simply, run:
```bash
cargo clean
INK_STATIC_BUFFER_SIZE=30 cargo test -F e2e-tests
```

This will configure the buffer to have enough space to instantiate the contract,
but not enough space to retrieve the caller's address as it is of 32 bytes,
but we only allocated 30 bytes to the contract.

## Note
You must run `cargo clean` every time you want to modify the buffer size
SkymanOne marked this conversation as resolved.
Show resolved Hide resolved
because the value is baked into the binaries.
78 changes: 78 additions & 0 deletions integration-tests/static-buffer/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#![cfg_attr(not(feature = "std"), no_std, no_main)]

#[ink::contract]
pub mod static_buffer {
#[allow(unused_imports)]
use ink::env::BUFFER_SIZE;
#[ink(storage)]
pub struct StaticBuffer {
value: bool,
}

impl StaticBuffer {
/// Creates a dummy smart contract.
#[ink(constructor)]
pub fn new(init_value: bool) -> Self {
Self { value: init_value }
}

/// Sets a default value.
#[ink(constructor)]
pub fn new_default() -> Self {
Self::new(Default::default())
}

/// Returns the caller of the contract.
/// Should panic if the buffer size is less than 32 bytes.
#[ink(message)]
pub fn get_caller(&self) -> AccountId {
self.env().caller()
}
}

#[cfg(test)]
mod tests {
use super::*;

#[ink::test]
#[should_panic(expected = "the output buffer is too small!")]
fn run_out_buffer_memory() {
let flipper = StaticBuffer::new(false);
flipper.get_caller()
}
}

#[cfg(all(test, feature = "e2e-tests"))]
mod e2e_tests {
use super::*;
use ink_e2e::ContractsBackend;

type E2EResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;

#[ink_e2e::test]
async fn e2e_run_out_of_buffer_memory<Client: E2EBackend>(
mut client: Client,
) -> E2EResult<()> {
// given
let constructor = StaticBufferRef::new(false);
let contract = client
.instantiate("static_buffer", &ink_e2e::alice(), constructor, 0, None)
.await
.expect("instantiate failed");
let call = contract.call::<StaticBuffer>();

// when
let get = call.get_caller();
// then panics if `INK_STATIC_BUFFER_SIZE` is less than 32 bytes.
let res = client.call_dry_run(&ink_e2e::bob(), &get, 0, None).await;
println!("{}", super::BUFFER_SIZE);
assert!(
res.is_err(),
"Buffer size was larger than expected: {}",
super::BUFFER_SIZE.to_string()
);

Ok(())
}
}
}