From cb0d8544dc8828c7b5e7f6a5fc20ce8c6ef9bbb4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandre=20R=2E=20Bald=C3=A9?= <alexandre.balde@parity.io>
Date: Wed, 15 Jan 2025 13:14:54 +0000
Subject: [PATCH] Remove 0 as a special case in gas/storage meters (#6890)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #6846 .

---------

Signed-off-by: xermicus <cyrill@parity.io>
Co-authored-by: command-bot <>
Co-authored-by: Alexander Theißen <alex.theissen@me.com>
Co-authored-by: xermicus <cyrill@parity.io>
---
 .../people-westend/src/tests/governance.rs    |   2 +-
 prdoc/pr_6890.prdoc                           |  19 ++++
 .../frame/revive/fixtures/contracts/call.rs   |   8 +-
 .../contracts/call_diverging_out_len.rs       |  12 +--
 .../fixtures/contracts/call_return_code.rs    |   8 +-
 .../contracts/call_runtime_and_call.rs        |   8 +-
 .../contracts/call_with_flags_and_value.rs    |   8 +-
 .../fixtures/contracts/call_with_limit.rs     |   4 +-
 .../fixtures/contracts/caller_contract.rs     |  48 +++++-----
 .../contracts/chain_extension_temp_storage.rs |   8 +-
 .../fixtures/contracts/create1_with_value.rs  |  12 ++-
 .../contracts/create_storage_and_call.rs      |   8 +-
 .../create_storage_and_instantiate.rs         |   6 +-
 .../create_transient_storage_and_call.rs      |   8 +-
 .../fixtures/contracts/delegate_call.rs       |  10 +-
 .../contracts/delegate_call_deposit_limit.rs  |  10 +-
 .../contracts/delegate_call_simple.rs         |  10 +-
 .../contracts/destroy_and_transfer.rs         |  18 ++--
 .../frame/revive/fixtures/contracts/drain.rs  |   2 +-
 .../contracts/instantiate_return_code.rs      |   7 +-
 .../contracts/locking_delegate_dependency.rs  |  10 +-
 .../frame/revive/fixtures/contracts/origin.rs |   6 +-
 .../fixtures/contracts/read_only_call.rs      |   8 +-
 .../revive/fixtures/contracts/recurse.rs      |   8 +-
 .../fixtures/contracts/return_data_api.rs     |  24 +++--
 .../fixtures/contracts/self_destruct.rs       |   8 +-
 .../contracts/transfer_return_code.rs         |   2 +-
 substrate/frame/revive/fixtures/src/lib.rs    |   2 +-
 .../rpc/examples/js/pvm/FlipperCaller.polkavm | Bin 4532 -> 4584 bytes
 .../rpc/examples/js/pvm/PiggyBank.polkavm     | Bin 5062 -> 5088 bytes
 .../frame/revive/src/benchmarking/mod.rs      |  14 +--
 substrate/frame/revive/src/exec.rs            |  60 +++++-------
 substrate/frame/revive/src/gas.rs             |  74 +++++++++++----
 substrate/frame/revive/src/primitives.rs      |   2 +-
 substrate/frame/revive/src/storage/meter.rs   |  89 ++++++++++--------
 substrate/frame/revive/src/tests.rs           |  72 +++++++-------
 substrate/frame/revive/src/wasm/runtime.rs    |   6 +-
 substrate/frame/revive/uapi/src/host.rs       |   6 +-
 .../frame/revive/uapi/src/host/riscv64.rs     |  12 +--
 39 files changed, 355 insertions(+), 264 deletions(-)
 create mode 100644 prdoc/pr_6890.prdoc

diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/governance.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/governance.rs
index ea438f80552..3b1779e40b6 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/governance.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/governance.rs
@@ -396,7 +396,7 @@ fn relay_commands_add_remove_username_authority() {
 		);
 	});
 
-	// Now, remove the username authority with another priviledged XCM call.
+	// Now, remove the username authority with another privileged XCM call.
 	Westend::execute_with(|| {
 		type Runtime = <Westend as Chain>::Runtime;
 		type RuntimeCall = <Westend as Chain>::RuntimeCall;
diff --git a/prdoc/pr_6890.prdoc b/prdoc/pr_6890.prdoc
new file mode 100644
index 00000000000..b22a339035d
--- /dev/null
+++ b/prdoc/pr_6890.prdoc
@@ -0,0 +1,19 @@
+# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
+# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
+
+title: Alter semantic meaning of 0 in metering limits of EVM contract calls
+
+doc:
+  - audience: [ Runtime Dev, Runtime User ]
+    description: |
+      A limit of 0, for gas meters and storage meters, no longer has the meaning of unlimited metering.
+
+crates:
+  - name: pallet-revive
+    bump: patch
+  - name: pallet-revive-fixtures
+    bump: patch
+  - name: pallet-revive-uapi
+    bump: patch
+  - name: pallet-revive-eth-rpc
+    bump: patch
diff --git a/substrate/frame/revive/fixtures/contracts/call.rs b/substrate/frame/revive/fixtures/contracts/call.rs
index ee51548879d..7c4c0882c6b 100644
--- a/substrate/frame/revive/fixtures/contracts/call.rs
+++ b/substrate/frame/revive/fixtures/contracts/call.rs
@@ -38,10 +38,10 @@ pub extern "C" fn call() {
 	api::call(
 		uapi::CallFlags::empty(),
 		callee_addr,
-		0u64,       // How much ref_time to devote for the execution. 0 = all.
-		0u64,       // How much proof_size to devote for the execution. 0 = all.
-		None,       // No deposit limit.
-		&[0u8; 32], // Value transferred to the contract.
+		u64::MAX,       // How much ref_time to devote for the execution. u64::MAX = use all.
+		u64::MAX,       // How much proof_size to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32], // No deposit limit.
+		&[0u8; 32],     // Value transferred to the contract.
 		callee_input,
 		None,
 	)
diff --git a/substrate/frame/revive/fixtures/contracts/call_diverging_out_len.rs b/substrate/frame/revive/fixtures/contracts/call_diverging_out_len.rs
index 129adde2cec..9a8fe5f5f6c 100644
--- a/substrate/frame/revive/fixtures/contracts/call_diverging_out_len.rs
+++ b/substrate/frame/revive/fixtures/contracts/call_diverging_out_len.rs
@@ -42,9 +42,9 @@ fn assert_call<const N: usize>(callee_address: &[u8; 20], expected_output: [u8;
 	api::call(
 		uapi::CallFlags::ALLOW_REENTRY,
 		callee_address,
-		0u64,
-		0u64,
-		None,
+		u64::MAX,
+		u64::MAX,
+		&[u8::MAX; 32],
 		&[0u8; 32],
 		&[],
 		Some(output_buf_capped),
@@ -67,9 +67,9 @@ fn assert_instantiate<const N: usize>(expected_output: [u8; BUF_SIZE]) {
 
 	api::instantiate(
 		&code_hash,
-		0u64,
-		0u64,
-		None,
+		u64::MAX,
+		u64::MAX,
+		&[u8::MAX; 32],
 		&[0; 32],
 		&[0; 32],
 		None,
diff --git a/substrate/frame/revive/fixtures/contracts/call_return_code.rs b/substrate/frame/revive/fixtures/contracts/call_return_code.rs
index 2d13b9f7095..19b3ae3fdb2 100644
--- a/substrate/frame/revive/fixtures/contracts/call_return_code.rs
+++ b/substrate/frame/revive/fixtures/contracts/call_return_code.rs
@@ -42,10 +42,10 @@ pub extern "C" fn call() {
 	let err_code = match api::call(
 		uapi::CallFlags::empty(),
 		callee_addr,
-		0u64,                // How much ref_time to devote for the execution. 0 = all.
-		0u64,                // How much proof_size to devote for the execution. 0 = all.
-		None,                // No deposit limit.
-		value, 				 // Value transferred to the contract.
+		u64::MAX,                 // How much ref_time to devote for the execution. u64::MAX = use all.
+		u64::MAX,                 // How much proof_size to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32], // No deposit limit.
+		value,                    // Value transferred to the contract.
 		input,
 		None,
 	) {
diff --git a/substrate/frame/revive/fixtures/contracts/call_runtime_and_call.rs b/substrate/frame/revive/fixtures/contracts/call_runtime_and_call.rs
index 8c8aee96284..78b275459f0 100644
--- a/substrate/frame/revive/fixtures/contracts/call_runtime_and_call.rs
+++ b/substrate/frame/revive/fixtures/contracts/call_runtime_and_call.rs
@@ -42,10 +42,10 @@ pub extern "C" fn call() {
 	api::call(
 		uapi::CallFlags::empty(),
 		callee_addr,
-		0u64,       // How much ref_time to devote for the execution. 0 = all.
-		0u64,       // How much proof_size to devote for the execution. 0 = all.
-		None,       // No deposit limit.
-		&[0u8; 32], // Value transferred to the contract.
+		u64::MAX,                 // How much ref_time to devote for the execution. u64::MAX = use all.
+		u64::MAX,                 // How much proof_size to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32],           // No deposit limit.
+		&[0u8; 32],               // Value transferred to the contract.
 		callee_input,
 		None,
 	)
diff --git a/substrate/frame/revive/fixtures/contracts/call_with_flags_and_value.rs b/substrate/frame/revive/fixtures/contracts/call_with_flags_and_value.rs
index 330393e706e..155a4b41bd9 100644
--- a/substrate/frame/revive/fixtures/contracts/call_with_flags_and_value.rs
+++ b/substrate/frame/revive/fixtures/contracts/call_with_flags_and_value.rs
@@ -40,10 +40,10 @@ pub extern "C" fn call() {
 	api::call(
 		uapi::CallFlags::from_bits(flags).unwrap(),
 		callee_addr,
-		0u64,               // How much ref_time to devote for the execution. 0 = all.
-		0u64,               // How much proof_size to devote for the execution. 0 = all.
-		None,               // No deposit limit.
-		&u256_bytes(value), // Value transferred to the contract.
+		u64::MAX,                 // How much ref_time to devote for the execution. u64::MAX = use all.
+		u64::MAX,                 // How much proof_size to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32],           // No deposit limit.
+		&u256_bytes(value),       // Value transferred to the contract.
 		forwarded_input,
 		None,
 	)
diff --git a/substrate/frame/revive/fixtures/contracts/call_with_limit.rs b/substrate/frame/revive/fixtures/contracts/call_with_limit.rs
index 6ab892a6b7a..af5c301a353 100644
--- a/substrate/frame/revive/fixtures/contracts/call_with_limit.rs
+++ b/substrate/frame/revive/fixtures/contracts/call_with_limit.rs
@@ -43,8 +43,8 @@ pub extern "C" fn call() {
 		callee_addr,
 		ref_time,
 		proof_size,
-		None,       // No deposit limit.
-		&[0u8; 32], // value transferred to the contract.
+		&[u8::MAX; 32],   // No deposit limit.
+		&[0u8; 32],       // value transferred to the contract.
 		forwarded_input,
 		None,
 	)
diff --git a/substrate/frame/revive/fixtures/contracts/caller_contract.rs b/substrate/frame/revive/fixtures/contracts/caller_contract.rs
index edad43fae25..d042dc2c22a 100644
--- a/substrate/frame/revive/fixtures/contracts/caller_contract.rs
+++ b/substrate/frame/revive/fixtures/contracts/caller_contract.rs
@@ -42,9 +42,9 @@ pub extern "C" fn call() {
 	// Fail to deploy the contract since it returns a non-zero exit status.
 	let res = api::instantiate(
 		code_hash,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		0u64, // How much proof_size weight to devote for the execution. 0 = all.
-		None, // No deposit limit.
+		u64::MAX,       // How much ref_time weight to devote for the execution. u64::MAX = use all.
+		u64::MAX,       // How much proof_size weight to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32], // No deposit limit.
 		&value,
 		&reverted_input,
 		None,
@@ -56,9 +56,9 @@ pub extern "C" fn call() {
 	// Fail to deploy the contract due to insufficient ref_time weight.
 	let res = api::instantiate(
 		code_hash,
-		1u64, // too little ref_time weight
-		0u64, // How much proof_size weight to devote for the execution. 0 = all.
-		None, // No deposit limit.
+		1u64,           // too little ref_time weight
+		u64::MAX,       // How much proof_size weight to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32], // No deposit limit.
 		&value,
 		&input,
 		None,
@@ -70,9 +70,9 @@ pub extern "C" fn call() {
 	// Fail to deploy the contract due to insufficient proof_size weight.
 	let res = api::instantiate(
 		code_hash,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		1u64, // Too little proof_size weight
-		None, // No deposit limit.
+		u64::MAX,       // How much ref_time weight to devote for the execution. u64::MAX = use all.
+		1u64,           // Too little proof_size weight
+		&[u8::MAX; 32], // No deposit limit.
 		&value,
 		&input,
 		None,
@@ -86,9 +86,9 @@ pub extern "C" fn call() {
 
 	api::instantiate(
 		code_hash,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		0u64, // How much proof_size weight to devote for the execution. 0 = all.
-		None, // No deposit limit.
+		u64::MAX,       // How much ref_time weight to devote for the execution. u64::MAX = use all.
+		u64::MAX,       // How much proof_size weight to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32], // No deposit limit.
 		&value,
 		&input,
 		Some(&mut callee),
@@ -101,9 +101,9 @@ pub extern "C" fn call() {
 	let res = api::call(
 		uapi::CallFlags::empty(),
 		&callee,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		0u64, // How much proof_size weight to devote for the execution. 0 = all.
-		None, // No deposit limit.
+		u64::MAX,       // How much ref_time weight to devote for the execution. u64::MAX = use all.
+		u64::MAX,       // How much proof_size weight to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32], // No deposit limit.
 		&value,
 		&reverted_input,
 		None,
@@ -114,9 +114,9 @@ pub extern "C" fn call() {
 	let res = api::call(
 		uapi::CallFlags::empty(),
 		&callee,
-		1u64, // Too little ref_time weight.
-		0u64, // How much proof_size weight to devote for the execution. 0 = all.
-		None, // No deposit limit.
+		1u64,           // Too little ref_time weight.
+		u64::MAX,       // How much proof_size weight to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32], // No deposit limit.
 		&value,
 		&input,
 		None,
@@ -127,9 +127,9 @@ pub extern "C" fn call() {
 	let res = api::call(
 		uapi::CallFlags::empty(),
 		&callee,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		1u64, // too little proof_size weight
-		None, // No deposit limit.
+		u64::MAX,       // How much ref_time weight to devote for the execution. u64::MAX = use all.
+		1u64,           // too little proof_size weight
+		&[u8::MAX; 32], // No deposit limit.
 		&value,
 		&input,
 		None,
@@ -141,9 +141,9 @@ pub extern "C" fn call() {
 	api::call(
 		uapi::CallFlags::empty(),
 		&callee,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		0u64, // How much proof_size weight to devote for the execution. 0 = all.
-		None, // No deposit limit.
+		u64::MAX,       // How much ref_time weight to devote for the execution. u64::MAX = use all.
+		u64::MAX,       // How much proof_size weight to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32], // No deposit limit.
 		&value,
 		&input,
 		Some(&mut &mut output[..]),
diff --git a/substrate/frame/revive/fixtures/contracts/chain_extension_temp_storage.rs b/substrate/frame/revive/fixtures/contracts/chain_extension_temp_storage.rs
index 22d6c5b548d..9b76b9d39ee 100644
--- a/substrate/frame/revive/fixtures/contracts/chain_extension_temp_storage.rs
+++ b/substrate/frame/revive/fixtures/contracts/chain_extension_temp_storage.rs
@@ -54,10 +54,10 @@ pub extern "C" fn call() {
 		api::call(
 			uapi::CallFlags::ALLOW_REENTRY,
 			&addr,
-			0u64,       // How much ref_time to devote for the execution. 0 = all.
-			0u64,       // How much proof_size to devote for the execution. 0 = all.
-			None,       // No deposit limit.
-			&[0u8; 32], // Value transferred to the contract.
+			u64::MAX,       // How much ref_time to devote for the execution. u64::MAX = use all.
+			u64::MAX,       // How much proof_size to devote for the execution. u64::MAX = use all.
+			&[u8::MAX; 32], // No deposit limit.
+			&[0u8; 32],     // Value transferred to the contract.
 			input,
 			None,
 		)
diff --git a/substrate/frame/revive/fixtures/contracts/create1_with_value.rs b/substrate/frame/revive/fixtures/contracts/create1_with_value.rs
index c6adab82886..3554f8f620a 100644
--- a/substrate/frame/revive/fixtures/contracts/create1_with_value.rs
+++ b/substrate/frame/revive/fixtures/contracts/create1_with_value.rs
@@ -34,6 +34,16 @@ pub extern "C" fn call() {
 	api::value_transferred(&mut value);
 
 	// Deploy the contract with no salt (equivalent to create1).
-	let ret = api::instantiate(code_hash, 0u64, 0u64, None, &value, &[], None, None, None);
+	let ret = api::instantiate(
+		code_hash,
+		u64::MAX,
+		u64::MAX,
+		&[u8::MAX; 32],
+		&value,
+		&[],
+		None,
+		None,
+		None
+	);
 	assert!(ret.is_ok());
 }
diff --git a/substrate/frame/revive/fixtures/contracts/create_storage_and_call.rs b/substrate/frame/revive/fixtures/contracts/create_storage_and_call.rs
index a12c36af856..5bb11e27903 100644
--- a/substrate/frame/revive/fixtures/contracts/create_storage_and_call.rs
+++ b/substrate/frame/revive/fixtures/contracts/create_storage_and_call.rs
@@ -43,10 +43,10 @@ pub extern "C" fn call() {
 	let ret = api::call(
 		uapi::CallFlags::empty(),
 		callee,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		0u64, // How much proof_size weight to devote for the execution. 0 = all.
-		Some(deposit_limit),
-		&[0u8; 32], // Value transferred to the contract.
+		u64::MAX,      // How much ref_time weight to devote for the execution. u64::MAX = use all resources.
+		u64::MAX,      // How much proof_size weight to devote for the execution. u64::MAX = use all resources.
+		deposit_limit,
+		&[0u8; 32],    // Value transferred to the contract.
 		input,
 		None,
 	);
diff --git a/substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs b/substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs
index ecc0fc79e6f..f627bc8ba6c 100644
--- a/substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs
+++ b/substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs
@@ -41,9 +41,9 @@ pub extern "C" fn call() {
 
 	let ret = api::instantiate(
 		code_hash,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		0u64, // How much proof_size weight to devote for the execution. 0 = all.
-		Some(deposit_limit),
+		u64::MAX, // How much ref_time weight to devote for the execution. u64::MAX = use all.
+		u64::MAX, // How much proof_size weight to devote for the execution. u64::MAX = use all.
+		deposit_limit,
 		&value,
 		input,
 		Some(&mut address),
diff --git a/substrate/frame/revive/fixtures/contracts/create_transient_storage_and_call.rs b/substrate/frame/revive/fixtures/contracts/create_transient_storage_and_call.rs
index cf12fed2756..660db84028d 100644
--- a/substrate/frame/revive/fixtures/contracts/create_transient_storage_and_call.rs
+++ b/substrate/frame/revive/fixtures/contracts/create_transient_storage_and_call.rs
@@ -49,10 +49,10 @@ pub extern "C" fn call() {
 	api::call(
 		uapi::CallFlags::empty(),
 		callee,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		0u64, // How much proof_size weight to devote for the execution. 0 = all.
-		None,
-		&[0u8; 32], // Value transferred to the contract.
+		u64::MAX,       // How much ref_time weight to devote for the execution. u64::MAX = all.
+		u64::MAX,       // How much proof_size weight to devote for the execution. u64::MAX = all.
+		&[u8::MAX; 32], // No deposit limit.
+		&[0u8; 32],     // Value transferred to the contract.
 		input,
 		None,
 	)
diff --git a/substrate/frame/revive/fixtures/contracts/delegate_call.rs b/substrate/frame/revive/fixtures/contracts/delegate_call.rs
index 3cf74acf132..0dedd5f704c 100644
--- a/substrate/frame/revive/fixtures/contracts/delegate_call.rs
+++ b/substrate/frame/revive/fixtures/contracts/delegate_call.rs
@@ -46,7 +46,15 @@ pub extern "C" fn call() {
 	assert!(value[0] == 2u8);
 
 	let input = [0u8; 0];
-	api::delegate_call(uapi::CallFlags::empty(), address, ref_time, proof_size, None, &input, None).unwrap();
+	api::delegate_call(
+		uapi::CallFlags::empty(),
+		address,
+		ref_time,
+		proof_size,
+		&[u8::MAX; 32],
+		&input,
+		None
+	).unwrap();
 
 	api::get_storage(StorageFlags::empty(), &key, value).unwrap();
 	assert!(value[0] == 1u8);
diff --git a/substrate/frame/revive/fixtures/contracts/delegate_call_deposit_limit.rs b/substrate/frame/revive/fixtures/contracts/delegate_call_deposit_limit.rs
index 0f157f5a18a..0c503aa93c5 100644
--- a/substrate/frame/revive/fixtures/contracts/delegate_call_deposit_limit.rs
+++ b/substrate/frame/revive/fixtures/contracts/delegate_call_deposit_limit.rs
@@ -34,7 +34,15 @@ pub extern "C" fn call() {
 	);
 
 	let input = [0u8; 0];
-	let ret = api::delegate_call(uapi::CallFlags::empty(), address, 0, 0, Some(&u256_bytes(deposit_limit)), &input, None);
+	let ret = api::delegate_call(
+		uapi::CallFlags::empty(),
+		address,
+		u64::MAX,
+		u64::MAX,
+		&u256_bytes(deposit_limit),
+		&input,
+		None
+	);
 
 	if let Err(code) = ret {
 		api::return_value(uapi::ReturnFlags::REVERT, &(code as u32).to_le_bytes());
diff --git a/substrate/frame/revive/fixtures/contracts/delegate_call_simple.rs b/substrate/frame/revive/fixtures/contracts/delegate_call_simple.rs
index a8501dad469..b7bdb792c76 100644
--- a/substrate/frame/revive/fixtures/contracts/delegate_call_simple.rs
+++ b/substrate/frame/revive/fixtures/contracts/delegate_call_simple.rs
@@ -32,5 +32,13 @@ pub extern "C" fn call() {
 
 	// Delegate call into passed address.
 	let input = [0u8; 0];
-	api::delegate_call(uapi::CallFlags::empty(), address, 0, 0, None, &input, None).unwrap();
+	api::delegate_call(
+		uapi::CallFlags::empty(),
+		address,
+		u64::MAX,
+		u64::MAX,
+		&[u8::MAX; 32],
+		&input,
+		None
+	).unwrap();
 }
diff --git a/substrate/frame/revive/fixtures/contracts/destroy_and_transfer.rs b/substrate/frame/revive/fixtures/contracts/destroy_and_transfer.rs
index 8342f4acf95..c2c7da528ba 100644
--- a/substrate/frame/revive/fixtures/contracts/destroy_and_transfer.rs
+++ b/substrate/frame/revive/fixtures/contracts/destroy_and_transfer.rs
@@ -35,9 +35,9 @@ pub extern "C" fn deploy() {
 
 	api::instantiate(
 		code_hash,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		0u64, // How much proof_size weight to devote for the execution. 0 = all.
-		None, // No deposit limit.
+		u64::MAX,       // How much ref_time weight to devote for the execution. u64::MAX = use all.
+		u64::MAX,       // How much proof_size weight to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32], // No deposit limit.
 		&VALUE,
 		&input,
 		Some(&mut address),
@@ -62,9 +62,9 @@ pub extern "C" fn call() {
 	let res = api::call(
 		uapi::CallFlags::empty(),
 		&callee_addr,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		0u64, // How much proof_size weight to devote for the execution. 0 = all.
-		None, // No deposit limit.
+		u64::MAX,       // How much ref_time weight to devote for the execution. u64::MAX = use all.
+		u64::MAX,       // How much proof_size weight to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32], // No deposit limit.
 		&VALUE,
 		&[0u8; 1],
 		None,
@@ -75,9 +75,9 @@ pub extern "C" fn call() {
 	api::call(
 		uapi::CallFlags::empty(),
 		&callee_addr,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		0u64, // How much proof_size weight to devote for the execution. 0 = all.
-		None, // No deposit limit.
+		u64::MAX,       // How much ref_time weight to devote for the execution. u64::MAX = use all.
+		u64::MAX,       // How much proof_size weight to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32], // No deposit limit.
 		&VALUE,
 		&[0u8; 0],
 		None,
diff --git a/substrate/frame/revive/fixtures/contracts/drain.rs b/substrate/frame/revive/fixtures/contracts/drain.rs
index 6e3e708a6b3..53fb213143c 100644
--- a/substrate/frame/revive/fixtures/contracts/drain.rs
+++ b/substrate/frame/revive/fixtures/contracts/drain.rs
@@ -41,7 +41,7 @@ pub extern "C" fn call() {
 		&[0u8; 20],
 		0,
 		0,
-		None,
+		&[u8::MAX; 32],
 		&u256_bytes(balance),
 		&[],
 		None,
diff --git a/substrate/frame/revive/fixtures/contracts/instantiate_return_code.rs b/substrate/frame/revive/fixtures/contracts/instantiate_return_code.rs
index 9764859c619..f7cbd75be5a 100644
--- a/substrate/frame/revive/fixtures/contracts/instantiate_return_code.rs
+++ b/substrate/frame/revive/fixtures/contracts/instantiate_return_code.rs
@@ -33,10 +33,9 @@ pub extern "C" fn call() {
 
 	let err_code = match api::instantiate(
 		code_hash,
-		0u64, // How much ref_time weight to devote for the execution. 0 = all.
-		0u64, /* How much proof_size weight to devote for the execution. 0 =
-		       * all. */
-		None,                   // No deposit limit.
+		u64::MAX,               // How much ref_time weight to devote for the execution. u64::MAX = use all.
+		u64::MAX,               // How much proof_size weight to devote for the execution. u64::MAX = use all.
+		&[u8::MAX; 32],         // No deposit limit.
 		&u256_bytes(10_000u64), // Value to transfer.
 		input,
 		None,
diff --git a/substrate/frame/revive/fixtures/contracts/locking_delegate_dependency.rs b/substrate/frame/revive/fixtures/contracts/locking_delegate_dependency.rs
index 3d7702c6537..6be5d5c72f9 100644
--- a/substrate/frame/revive/fixtures/contracts/locking_delegate_dependency.rs
+++ b/substrate/frame/revive/fixtures/contracts/locking_delegate_dependency.rs
@@ -52,7 +52,15 @@ fn load_input(delegate_call: bool) {
 	}
 
 	if delegate_call {
-		api::delegate_call(uapi::CallFlags::empty(), address, 0, 0, None, &[], None).unwrap();
+		api::delegate_call(
+			uapi::CallFlags::empty(),
+			address,
+			u64::MAX,
+			u64::MAX,
+			&[u8::MAX; 32],
+			&[],
+			None
+		).unwrap();
 	}
 }
 
diff --git a/substrate/frame/revive/fixtures/contracts/origin.rs b/substrate/frame/revive/fixtures/contracts/origin.rs
index 8e9afd8e805..151ca3da77c 100644
--- a/substrate/frame/revive/fixtures/contracts/origin.rs
+++ b/substrate/frame/revive/fixtures/contracts/origin.rs
@@ -49,9 +49,9 @@ pub extern "C" fn call() {
 	api::call(
 		uapi::CallFlags::ALLOW_REENTRY,
 		&addr,
-		0u64,
-		0u64,
-		None,
+		u64::MAX,
+		u64::MAX,
+		&[u8::MAX; 32],
 		&[0; 32],
 		&[],
 		Some(&mut &mut buf[..]),
diff --git a/substrate/frame/revive/fixtures/contracts/read_only_call.rs b/substrate/frame/revive/fixtures/contracts/read_only_call.rs
index ea74d56867f..0a87ecbb9b1 100644
--- a/substrate/frame/revive/fixtures/contracts/read_only_call.rs
+++ b/substrate/frame/revive/fixtures/contracts/read_only_call.rs
@@ -39,10 +39,10 @@ pub extern "C" fn call() {
 	api::call(
 		uapi::CallFlags::READ_ONLY,
 		callee_addr,
-		0u64,       // How much ref_time to devote for the execution. 0 = all.
-		0u64,       // How much proof_size to devote for the execution. 0 = all.
-		None,       // No deposit limit.
-		&[0u8; 32], // Value transferred to the contract.
+		u64::MAX,                 // How much ref_time to devote for the execution. u64::MAX = all.
+		u64::MAX,                 // How much proof_size to devote for the execution. u64::MAX = all.
+		&[u8::MAX; 32],           // No deposit limit.
+		&[0u8; 32],               // Value transferred to the contract.
 		callee_input,
 		None,
 	)
diff --git a/substrate/frame/revive/fixtures/contracts/recurse.rs b/substrate/frame/revive/fixtures/contracts/recurse.rs
index 2e70d67d8c7..ead565c0145 100644
--- a/substrate/frame/revive/fixtures/contracts/recurse.rs
+++ b/substrate/frame/revive/fixtures/contracts/recurse.rs
@@ -43,10 +43,10 @@ pub extern "C" fn call() {
 	api::call(
 		uapi::CallFlags::ALLOW_REENTRY,
 		&addr,
-		0u64,       // How much ref_time to devote for the execution. 0 = all.
-		0u64,       // How much deposit_limit to devote for the execution. 0 = all.
-		None,       // No deposit limit.
-		&[0u8; 32], // Value transferred to the contract.
+		u64::MAX,       // How much ref_time to devote for the execution. u64::MAX = use all resources.
+		u64::MAX,       // How much proof_size to devote for the execution. u64::MAX = use all resources.
+		&[u8::MAX; 32], // No deposit limit.
+		&[0u8; 32],     // Value transferred to the contract.
 		&(calls_left - 1).to_le_bytes(),
 		None,
 	)
diff --git a/substrate/frame/revive/fixtures/contracts/return_data_api.rs b/substrate/frame/revive/fixtures/contracts/return_data_api.rs
index 1d483373cff..1407e5323ea 100644
--- a/substrate/frame/revive/fixtures/contracts/return_data_api.rs
+++ b/substrate/frame/revive/fixtures/contracts/return_data_api.rs
@@ -80,8 +80,16 @@ fn assert_return_data_size_of(expected: u64) {
 
 /// Assert the return data to be reset after a balance transfer.
 fn assert_balance_transfer_does_reset() {
-	api::call(uapi::CallFlags::empty(), &[0u8; 20], 0, 0, None, &u256_bytes(128), &[], None)
-		.unwrap();
+	api::call(
+		uapi::CallFlags::empty(),
+		&[0u8; 20],
+		u64::MAX,
+		u64::MAX,
+		&[u8::MAX; 32],
+		&u256_bytes(128),
+		&[],
+		None
+	).unwrap();
 	assert_return_data_size_of(0);
 }
 
@@ -111,9 +119,9 @@ pub extern "C" fn call() {
 	let mut instantiate = |exit_flag| {
 		api::instantiate(
 			code_hash,
-			0u64,
-			0u64,
-			None,
+			u64::MAX,
+			u64::MAX,
+			&[u8::MAX; 32],
 			&[0; 32],
 			&construct_input(exit_flag),
 			Some(&mut address_buf),
@@ -125,9 +133,9 @@ pub extern "C" fn call() {
 		api::call(
 			uapi::CallFlags::empty(),
 			address_buf,
-			0u64,
-			0u64,
-			None,
+			u64::MAX,
+			u64::MAX,
+			&[u8::MAX; 32],
 			&[0; 32],
 			&construct_input(exit_flag),
 			None,
diff --git a/substrate/frame/revive/fixtures/contracts/self_destruct.rs b/substrate/frame/revive/fixtures/contracts/self_destruct.rs
index 2f37706634b..053e545deb1 100644
--- a/substrate/frame/revive/fixtures/contracts/self_destruct.rs
+++ b/substrate/frame/revive/fixtures/contracts/self_destruct.rs
@@ -42,10 +42,10 @@ pub extern "C" fn call() {
 		api::call(
 			uapi::CallFlags::ALLOW_REENTRY,
 			&addr,
-			0u64,       // How much ref_time to devote for the execution. 0 = all.
-			0u64,       // How much proof_size to devote for the execution. 0 = all.
-			None,       // No deposit limit.
-			&[0u8; 32], // Value to transfer.
+			u64::MAX,                 // How much ref_time to devote for the execution. u64 = all.
+			u64::MAX,                 // How much proof_size to devote for the execution. u64 = all.
+			&[u8::MAX; 32],           // No deposit limit.
+			&[0u8; 32],               // Value to transfer.
 			&[0u8; 0],
 			None,
 		)
diff --git a/substrate/frame/revive/fixtures/contracts/transfer_return_code.rs b/substrate/frame/revive/fixtures/contracts/transfer_return_code.rs
index 09d45d0a841..053f97feda4 100644
--- a/substrate/frame/revive/fixtures/contracts/transfer_return_code.rs
+++ b/substrate/frame/revive/fixtures/contracts/transfer_return_code.rs
@@ -33,7 +33,7 @@ pub extern "C" fn call() {
 		&[0u8; 20],
 		0,
 		0,
-		None,
+		&[u8::MAX; 32],
 		&u256_bytes(100u64),
 		&[],
 		None,
diff --git a/substrate/frame/revive/fixtures/src/lib.rs b/substrate/frame/revive/fixtures/src/lib.rs
index 38171edf115..7685253d1ea 100644
--- a/substrate/frame/revive/fixtures/src/lib.rs
+++ b/substrate/frame/revive/fixtures/src/lib.rs
@@ -22,7 +22,7 @@ extern crate alloc;
 // generated file that tells us where to find the fixtures
 include!(concat!(env!("OUT_DIR"), "/fixture_location.rs"));
 
-/// Load a given wasm module and returns a wasm binary contents along with it's hash.
+/// Load a given wasm module and returns a wasm binary contents along with its hash.
 #[cfg(feature = "std")]
 pub fn compile_module(fixture_name: &str) -> anyhow::Result<(Vec<u8>, sp_core::H256)> {
 	let out_dir: std::path::PathBuf = FIXTURE_DIR.into();
diff --git a/substrate/frame/revive/rpc/examples/js/pvm/FlipperCaller.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/FlipperCaller.polkavm
index 585fbb392a314c15a35e7e529106738bde3be02a..38a1098fe3a767aa0af74764bf7247e59f6110b7 100644
GIT binary patch
delta 1279
zcmY+CT}&KR6vy}8S>|h5m|e@38e(^sVY0h1Ep^(6SQDhH>}<fyEEMr04aVvWl*o=r
zv$IVM)UN4liG<Fr3XKmWk`(ZvO-f(<3VuBBAf`4^YZ{YP`_KmsL9x<Bif6FYHkoth
zo_o&y&u`8-bM-gsX|=n<<GFE~UI|TjUw&y|V04l`{7QCUFi($Ndl-+-5CKVhzNHh)
z*US#~3-&VG$Gy&ta4Vd~zsSGq`_89T9;y7HGURXe|L)&i^?cQds>!P9i#ocF8;1We
z1&cCkvXmJzsF9js>R6z3I3zPIG8<Nf2R-W=6DL{k-gt>J`_;T2Ml#D|l+*Vkt?i@5
ztCMe2THB{bUsz&LrtQSs>Z>1<Mejb}amv!wT&{Dw*CPIkK~zWHsCX1zCzmRcb*J!F
z>^N4Waj-Ek8*CVpF;+&yM4{tY!X(1&!Z#7oxDXw^P}Z0q$vizVG>x-;7qDqe!i}q7
zm%$dm=CRCrExkz<#HCvrQwyZwO;;*`%b}E1!eK?Kr8X2va2M8HJk&-?3RATspl2E)
zrAUqLag5p+(LI!@H&G+{JT~?Hlw}B}(LzO2Qj+qTMhXHY2((jB6^ch0<`(8zbZ~pP
zNPcCW@V!P`hT2uT^Ql<gEeYvmgZ|R0%&J1-+G>WuG#O&wM~{&@uATnvZ;h$hAfMB{
z<Qwk5&;f7<ZUeiU{m4G>4&4TN1n}5}cNf-OJlKWDEWjgxhaxn($1&`}16vaYcm(kH
zKX?r6*ky<F5}dbVV8<@|Zb}JRN+_#@429(RJr9wa8uQ6|&ghXDnd3RMH4;t7An*ZM
z;M0%yted(znhR%`XV&xQa)xT^DX5StGzTE3c^%rE)q7zQdMqO~dy>f;y%cCMIlY&3
z_}VIF{?eE$7bkoPw9Q%D(r+1D(U|cytG|bQM#by;*YY{&BPgpvYa@i7TXXgLQgiRI
zWRdP7S^timbAM{gPi2>t3(L$suuq?b$d_c=-*M<@8E`gXkCg9&P3?l5XWb~k!f5^v
zi|@c<WEm~vC*?A<chm}J*myZ_S?<58s*qm#17?kMR$W20M5=xgf4@xns^jQGLaJlZ
zo68x->&ZhAk<5ua2gUSs$L5x0Misix!wacG&pGmQ^}-MvDcC|Z8jM7LF=By0F&T{p
zf=b5ecg~3MMEon;o)X`g61CImOk7cd#pGT`P@Gv&fuvwmam1~sAOstNMcWpWd>~Q~
zqOG=_D%f_tdq)f;lCz2}Dw%YrGbJjb<_Ja5wArD}54w_fgc|Pd?%#Adj+1H?l|)<#
zHbl0v-JFcGEjn|Lc(mvgQeyE`QA$Jp*)x*jr0?culug+wF~T3@BL(q+_*(^`byyU~
MKxn~9Ll-^&0#ACHtN;K2

delta 1201
zcmY+CT}&KR6vy}8ncX|HA26&fC8pA0xJ-5l*6L^^*2Z-+Ei-FLW=5dI57KJu43x+Y
zMt8T3p(sh0U<mAOt2UYtvk9ONl9VP&Vx-1sec(Y&{Ys34^a0~TEn<t?QoI9!w8@;z
zx##@v|NiElS*)F|4H#|BKHv0cV7c-*`|^?Q?&03R(PQcEo?KvLya5iMBm$5ho(bHC
zE+WW%!hO!|<yHPg{u{nFxI5^C#zVE?ec{RQVmKW6G6KpP%38~M%T8Rd!Bto{d)pNn
z8F%|0#;uGoL)#O~iHiB7l?qBIoM;I5`&La9C2982_;-xkW#nuTC|nSNjQu1qn`Y*I
z8GC~<o4$Dc`D+MRO>a-Hyiz1{>|>!WCTkm+%(FY#BP8PQ0e<qP|8X!!F8bA-uffe;
z7u4k}jWi91#$iaR{R%it^gtYzL(<6auKokKoub<vbC2(FyQ*^Il*_dn4MCbJndmDr
z8+gAj57V6^&~;8xi_d6G(U_ny1{IFYdSZO-KNA6pF0L=-dAeNkY4R)-HF+LZ4cVul
zYhR^%{)TIsyaLyBc@eG+*<-YP8)hBBb$pB_vkdDx95ZCk(t4Q5+4C?6LKa$pK@PO;
z5PL}p?F$_WWF4cWYS;eQOWtLW3>S^uTv0efs9##K&|iLXj{5)@MBxuYW`*?g<A<KR
zX`=2s6wXsUa*(b%?ocwI$v((Y4B*-<r4u~5Dvyry=w@ko=LVe!H5o%n7lT9gJgqmt
zob4m$g30PjH%#>7YQ||-kirLfusPhu3EG$;H-f3XJ*%#53}-|O9b3(fXB@+|HP=ZP
z!V^zXjk!t(mbOJY)Ap>ReS8|_9Fd`3C}WG{WT?si^S>tg^TM~GdLT^R+VoF+xNM?N
z35Yxx?Z1`FtPf5zgk%RTr%57`*|qSGiIz(q880g6F0=!eY3DccQ>3}$of18K9qp~s
zJ!sksRP(CWP1_0jOKqVg;09U(f~=Ex?{um}hclcNEiO^YWwYLw8HSL0fNp<?^q2hr
z4v?1ery;vU-Yt)VU&*ENm^^jeLaZ-GuM8+W4)XNsd~LCX>k2Z2w%_Rs7()9MQZ8KX
z%X2j<PO4vjZ%9&fP*o*dDB>$Pu3IfuzM?|c>vjDj>1@#|6mWFV!8HZksuw(wTEH~f
zc=#He!ci*EZ<CTLS0hzO(lFL>bX1)XCS|%wk2mYoVpP?WxS;NrB<hw|wZ7z*$(gO}
z-o(;VDTyD&lSQnb8PGP5^bXdoeDN;xL7a+8qqtr^AEWwC>pZ6PTl%`X^}H|;Yl#mC
Wh2pkok^_;#NP;SAo~e&x*7rX_jeaBm

diff --git a/substrate/frame/revive/rpc/examples/js/pvm/PiggyBank.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/PiggyBank.polkavm
index 3f96fdfc21d8d8fc5bf68a34f0c9f7b055afa2a4..d0082db90e5e398832e4a32a9ec86dce83d16dd5 100644
GIT binary patch
delta 1052
zcmY*WZA@EL7{2Gw_S}z_-8R4wr?xkz7m8*QJKg?h8rF;+;@s^O6m*LyGwlzeYnDOL
zOo#y~Rt-HbnCv4NHkbfe6h#-~4>NTxL}MhzD1Ic?s0qd;$P$NhVR$Yg!{j{Y&3VrA
zydURWtS!}gtcUhXQmNosZhy+v`FK~?$T831Cy#VJ-Rt3B8+hcoLsGZ&taL^y!@F=Z
zK8XAAW%ru9lN8BOIiqmpBjpzLpn9*?p{;5Ud&9m*eUrY{^5ycEw^isn^#l4b{rIef
z9>d|_YDQncnaX*bshY$2$`XFYUpibBC9$X+wDiE>YLcwLS7p1=EO=ct>SCGQl)H4|
zV{pSV+2w6_XH#uGJr8boS#Ee+sfBs619iYVE*f~rlWdyt{XD<mvYYlFui5#n%W-ID
zTpJGhDn#60pikhcyMP)X?|Hv(5JyQ=w)85`-$|0i39}zD^F6f2%o%5!bhdG{mN3sF
zIiHT9O!|Tl%sccPTFa-#Q6{y3@~I9He?Zxkl}VLQ!u&-X7X{rf;w99ZI*-&$s!f%V
zO@4Q}vB|F<X70fnGaE27>jZ-Ep;GM(;|k)sx8M)5*ViU!OCTW-gP43bib1y=MnyO+
z--kNkd-;Q#iYx2GwQhF>{+(n8U$Mz=L;|l?4WBBvqkg!e%%V}4R)gp$e5T$R+IuBQ
z-o4(FwxR?@6{;%E%%aAOz@)%9+^kVF4l%9Lv-oF{JaQdglkb2b&4;F7Oe>)|==K`u
zbvWTYjbymT*N)zR5#Q&#OP7<xz9wEFo8B`$M6&6`k+g(+1)_>dP)|z2*>vpW&}~=i
z>aYFx;df2LX!-r<5d2hr7R|sb+fJbhsMk-SEL_xIz{^YUfWO-F%~F!Ezu--^2FK1p
z&VQ@^<5HAZdgFH@AWM&b3FrJ5`Wj__C?2PV@kGsVE;m8PCTOxi!&4?>#$Zlnte&x=
zF-9XSM_D+`iZsqgZB7|?uw^ydEjhn`i=Oiq*ec)^278{y8-yzo=lkL`%=n9a6K06h
zu~9nAb!In5{+Cj?*DFyL;?t&5pi|8o30ru8@i?cUO$#4L+~{asHo<Vh9;QOXX>p(7
z^xrD%frv=7StiLE2PmSEa6!mK!p#f8RkDD=ZZIqm<F+H)pbW#{xm-f@eX^0VkpY>v
Iuuw?)2l-oAiU0rr

delta 1068
zcmY*XZ)h839KPS%OYTpa^e)h5|8Qx1b8REIvCCKmDKXsWy<w5$=Cm7gcC32&P_+SF
z(oRi2I2R4o_TCEW1{;!MyN*$)!X`ypt#cnNPVkc;21Q{gy7j}lIct2=b=?N{@ZLT5
z{GR7|@7`+Lr8al!=_JQp8g*aa{|tZRaDV^EA$Q;N1N|=#x}Dh&8nK_{j&jGi(_90J
zq69jKifGAIbL|nz!a?zXbWEC(-12T&^AOMPo>-&LYj{V!UA`ZEN1Ilf0!pWHNO@r<
z1<#>yY$dB)K-uPLlx>+n<>omwq*nV{bRnjT!Ia`ZzLFNI^oNFBaEdnao22g>tnSjE
zAAa>3-Nx_S9CzjIo?LEkfPc(Iv>rsX6obhSqXj++G5RTw{ja*y-P7J*ugvpSck=a3
zkABJ1?R?Zz;@5_8fp)mQgY)#3YZNxpvitMGOGp=VF{QM)|49pnk*O8I)XsodwquaB
zD?qeqsF~UYs1a=fYGu2Z(X)`ZQ(1eCNf+4TWhmQ4wtfqP_8E|~c8@HACHzs3wS?c?
zMBBiMDhwh6hsuHKP_EjSC4mjJ%(uHZ)PDKjdQ<wi=xgd^n(Ykj3_%3+im;QuD`L1v
zXT&ZTqD$fz8!s-e?r2|t_ur|%WpddPt_mC-;M?dmX$$mHuRH@&bY2d^JM<TMTkC-v
zY2mZ~a+#DafG%NKVtf05WsESC7>aa<2M3Bsmuk8vs0*?O?*1HHqc3{8V2+;iRN-ej
z+!%scI^B2*w$h|`KYUF;@h<LKUP=qrZT4aEna;B(gnY&v$W&pFL6>9!a&{H+nb=1s
zw%%%w+`j9)W1dd=_P{IjrtchlL&uv=!Xxwv<s`gEe^TDsEM7|sM{edavDMCftTQ_-
zx{y-3{-STFL0F`x)rXWDf7hw_b+$lCF|N`@b)lffOQvBgME$BtNQ97&LnL7(9mkMW
z)p4F;H@hRmaunhu5{^MixMLg>2ZtH%yT&RL%EO`i^f)}JJ)r3@9G;YV*_2hn!zDA}
z;AWDH7chx*5P!JUsf<|<STg&{orpNzm-L5-_5NDoBn~_HZA{|pBUl=}*Jx~2M){G7
zpD+<7#;{TEf40tB%;;Xso8prMnN}jiWXy2=1>+(PHXL)Eac~ij*JW!W!!WR_j^b7)
Pdfaq^l8Pstc%1tmWiL>e

diff --git a/substrate/frame/revive/src/benchmarking/mod.rs b/substrate/frame/revive/src/benchmarking/mod.rs
index e67c39ec089..1796348ff32 100644
--- a/substrate/frame/revive/src/benchmarking/mod.rs
+++ b/substrate/frame/revive/src/benchmarking/mod.rs
@@ -1648,8 +1648,8 @@ mod benchmarks {
 				memory.as_mut_slice(),
 				CallFlags::CLONE_INPUT.bits(), // flags
 				0,                             // callee_ptr
-				0,                             // ref_time_limit
-				0,                             // proof_size_limit
+				u64::MAX,                      // ref_time_limit
+				u64::MAX,                      // proof_size_limit
 				callee_len,                    // deposit_ptr
 				callee_len + deposit_len,      // value_ptr
 				0,                             // input_data_ptr
@@ -1688,8 +1688,8 @@ mod benchmarks {
 				memory.as_mut_slice(),
 				0,           // flags
 				0,           // address_ptr
-				0,           // ref_time_limit
-				0,           // proof_size_limit
+				u64::MAX,    // ref_time_limit
+				u64::MAX,    // proof_size_limit
 				address_len, // deposit_ptr
 				0,           // input_data_ptr
 				0,           // input_data_len
@@ -1715,7 +1715,7 @@ mod benchmarks {
 		let value_bytes = Into::<U256>::into(value).encode();
 		let value_len = value_bytes.len() as u32;
 
-		let deposit: BalanceOf<T> = 0u32.into();
+		let deposit: BalanceOf<T> = BalanceOf::<T>::max_value();
 		let deposit_bytes = Into::<U256>::into(deposit).encode();
 		let deposit_len = deposit_bytes.len() as u32;
 
@@ -1750,8 +1750,8 @@ mod benchmarks {
 			result = runtime.bench_instantiate(
 				memory.as_mut_slice(),
 				0,                   // code_hash_ptr
-				0,                   // ref_time_limit
-				0,                   // proof_size_limit
+				u64::MAX,            // ref_time_limit
+				u64::MAX,            // proof_size_limit
 				offset(hash_len),    // deposit_ptr
 				offset(deposit_len), // value_ptr
 				offset(value_len),   // input_data_ptr
diff --git a/substrate/frame/revive/src/exec.rs b/substrate/frame/revive/src/exec.rs
index 478e96dc994..c069216d6cc 100644
--- a/substrate/frame/revive/src/exec.rs
+++ b/substrate/frame/revive/src/exec.rs
@@ -53,7 +53,7 @@ use sp_core::{
 };
 use sp_io::{crypto::secp256k1_ecdsa_recover_compressed, hashing::blake2_256};
 use sp_runtime::{
-	traits::{BadOrigin, Convert, Dispatchable, Saturating, Zero},
+	traits::{BadOrigin, Bounded, Convert, Dispatchable, Saturating, Zero},
 	DispatchError, SaturatedConversion,
 };
 
@@ -885,9 +885,9 @@ where
 			args,
 			value,
 			gas_meter,
-			Weight::zero(),
+			Weight::max_value(),
 			storage_meter,
-			BalanceOf::<T>::zero(),
+			BalanceOf::<T>::max_value(),
 			false,
 			true,
 		)?
@@ -1117,25 +1117,15 @@ where
 				return Ok(output);
 			}
 
-			// Storage limit is normally enforced as late as possible (when the last frame returns)
-			// so that the ordering of storage accesses does not matter.
-			// (However, if a special limit was set for a sub-call, it should be enforced right
-			// after the sub-call returned. See below for this case of enforcement).
-			if self.frames.is_empty() {
-				let frame = &mut self.first_frame;
-				frame.contract_info.load(&frame.account_id);
-				let contract = frame.contract_info.as_contract();
-				frame.nested_storage.enforce_limit(contract)?;
-			}
-
 			let frame = self.top_frame_mut();
 
-			// If a special limit was set for the sub-call, we enforce it here.
-			// The sub-call will be rolled back in case the limit is exhausted.
+			// The storage deposit is only charged at the end of every call stack.
+			// To make sure that no sub call uses more than it is allowed to,
+			// the limit is manually enforced here.
 			let contract = frame.contract_info.as_contract();
 			frame
 				.nested_storage
-				.enforce_subcall_limit(contract)
+				.enforce_limit(contract)
 				.map_err(|e| ExecError { error: e, origin: ErrorOrigin::Callee })?;
 
 			let account_id = T::AddressMapper::to_address(&frame.account_id);
@@ -1463,7 +1453,7 @@ where
 				FrameArgs::Call { dest: dest.clone(), cached_info, delegated_call: None },
 				value,
 				gas_limit,
-				deposit_limit.try_into().map_err(|_| Error::<T>::BalanceConversionFailed)?,
+				deposit_limit.saturated_into::<BalanceOf<T>>(),
 				// Enable read-only access if requested; cannot disable it if already set.
 				read_only || self.is_read_only(),
 			)? {
@@ -1519,7 +1509,7 @@ where
 			},
 			value,
 			gas_limit,
-			deposit_limit.try_into().map_err(|_| Error::<T>::BalanceConversionFailed)?,
+			deposit_limit.saturated_into::<BalanceOf<T>>(),
 			self.is_read_only(),
 		)?;
 		self.run(executable.expect(FRAME_ALWAYS_EXISTS_ON_INSTANTIATE), input_data)
@@ -1549,7 +1539,7 @@ where
 			},
 			value.try_into().map_err(|_| Error::<T>::BalanceConversionFailed)?,
 			gas_limit,
-			deposit_limit.try_into().map_err(|_| Error::<T>::BalanceConversionFailed)?,
+			deposit_limit.saturated_into::<BalanceOf<T>>(),
 			self.is_read_only(),
 		)?;
 		let address = T::AddressMapper::to_address(&self.top_frame().account_id);
@@ -3098,8 +3088,8 @@ mod tests {
 				let (address, output) = ctx
 					.ext
 					.instantiate(
-						Weight::zero(),
-						U256::zero(),
+						Weight::MAX,
+						U256::MAX,
 						dummy_ch,
 						<Test as Config>::Currency::minimum_balance().into(),
 						vec![],
@@ -3802,8 +3792,8 @@ mod tests {
 		let succ_fail_code = MockLoader::insert(Constructor, move |ctx, _| {
 			ctx.ext
 				.instantiate(
-					Weight::zero(),
-					U256::zero(),
+					Weight::MAX,
+					U256::MAX,
 					fail_code,
 					ctx.ext.minimum_balance() * 100,
 					vec![],
@@ -3819,8 +3809,8 @@ mod tests {
 			let addr = ctx
 				.ext
 				.instantiate(
-					Weight::zero(),
-					U256::zero(),
+					Weight::MAX,
+					U256::MAX,
 					success_code,
 					ctx.ext.minimum_balance() * 100,
 					vec![],
@@ -4597,7 +4587,7 @@ mod tests {
 				// Successful instantiation should set the output
 				let address = ctx
 					.ext
-					.instantiate(Weight::zero(), U256::zero(), ok_ch, value, vec![], None)
+					.instantiate(Weight::MAX, U256::MAX, ok_ch, value, vec![], None)
 					.unwrap();
 				assert_eq!(
 					ctx.ext.last_frame_output(),
@@ -4606,15 +4596,7 @@ mod tests {
 
 				// Balance transfers should reset the output
 				ctx.ext
-					.call(
-						Weight::zero(),
-						U256::zero(),
-						&address,
-						U256::from(1),
-						vec![],
-						true,
-						false,
-					)
+					.call(Weight::MAX, U256::MAX, &address, U256::from(1), vec![], true, false)
 					.unwrap();
 				assert_eq!(ctx.ext.last_frame_output(), &Default::default());
 
@@ -4827,7 +4809,7 @@ mod tests {
 
 				// Constructors can not access the immutable data
 				ctx.ext
-					.instantiate(Weight::zero(), U256::zero(), dummy_ch, value, vec![], None)
+					.instantiate(Weight::MAX, U256::MAX, dummy_ch, value, vec![], None)
 					.unwrap();
 
 				exec_success()
@@ -4944,7 +4926,7 @@ mod tests {
 			move |ctx, _| {
 				let value = <Test as Config>::Currency::minimum_balance().into();
 				ctx.ext
-					.instantiate(Weight::zero(), U256::zero(), dummy_ch, value, vec![], None)
+					.instantiate(Weight::MAX, U256::MAX, dummy_ch, value, vec![], None)
 					.unwrap();
 
 				exec_success()
@@ -4989,7 +4971,7 @@ mod tests {
 			move |ctx, _| {
 				let value = <Test as Config>::Currency::minimum_balance().into();
 				ctx.ext
-					.instantiate(Weight::zero(), U256::zero(), dummy_ch, value, vec![], None)
+					.instantiate(Weight::MAX, U256::MAX, dummy_ch, value, vec![], None)
 					.unwrap();
 
 				exec_success()
diff --git a/substrate/frame/revive/src/gas.rs b/substrate/frame/revive/src/gas.rs
index 5c30a0a5100..e8338db1219 100644
--- a/substrate/frame/revive/src/gas.rs
+++ b/substrate/frame/revive/src/gas.rs
@@ -22,7 +22,7 @@ use frame_support::{
 	weights::Weight,
 	DefaultNoBound,
 };
-use sp_runtime::{traits::Zero, DispatchError};
+use sp_runtime::DispatchError;
 
 #[cfg(test)]
 use std::{any::Any, fmt::Debug};
@@ -168,25 +168,19 @@ impl<T: Config> GasMeter<T> {
 		}
 	}
 
-	/// Create a new gas meter by removing gas from the current meter.
+	/// Create a new gas meter by removing *all* the gas from the current meter.
 	///
-	/// # Note
-	///
-	/// Passing `0` as amount is interpreted as "all remaining gas".
+	/// This should only be used by the primordial frame in a sequence of calls - every subsequent
+	/// frame should use [`nested`](Self::nested).
+	pub fn nested_take_all(&mut self) -> Self {
+		let gas_left = self.gas_left;
+		self.gas_left -= gas_left;
+		GasMeter::new(gas_left)
+	}
+
+	/// Create a new gas meter for a nested call by removing gas from the current meter.
 	pub fn nested(&mut self, amount: Weight) -> Self {
-		let amount = Weight::from_parts(
-			if amount.ref_time().is_zero() {
-				self.gas_left().ref_time()
-			} else {
-				amount.ref_time()
-			},
-			if amount.proof_size().is_zero() {
-				self.gas_left().proof_size()
-			} else {
-				amount.proof_size()
-			},
-		)
-		.min(self.gas_left);
+		let amount = amount.min(self.gas_left);
 		self.gas_left -= amount;
 		GasMeter::new(amount)
 	}
@@ -392,6 +386,50 @@ mod tests {
 		assert!(gas_meter.charge(SimpleToken(1)).is_err());
 	}
 
+	/// Previously, passing a `Weight` of 0 to `nested` would consume all of the meter's current
+	/// gas.
+	///
+	/// Now, a `Weight` of 0 means no gas for the nested call.
+	#[test]
+	fn nested_zero_gas_requested() {
+		let test_weight = 50000.into();
+		let mut gas_meter = GasMeter::<Test>::new(test_weight);
+		let gas_for_nested_call = gas_meter.nested(0.into());
+
+		assert_eq!(gas_meter.gas_left(), 50000.into());
+		assert_eq!(gas_for_nested_call.gas_left(), 0.into())
+	}
+
+	#[test]
+	fn nested_some_gas_requested() {
+		let test_weight = 50000.into();
+		let mut gas_meter = GasMeter::<Test>::new(test_weight);
+		let gas_for_nested_call = gas_meter.nested(10000.into());
+
+		assert_eq!(gas_meter.gas_left(), 40000.into());
+		assert_eq!(gas_for_nested_call.gas_left(), 10000.into())
+	}
+
+	#[test]
+	fn nested_all_gas_requested() {
+		let test_weight = Weight::from_parts(50000, 50000);
+		let mut gas_meter = GasMeter::<Test>::new(test_weight);
+		let gas_for_nested_call = gas_meter.nested(test_weight);
+
+		assert_eq!(gas_meter.gas_left(), Weight::from_parts(0, 0));
+		assert_eq!(gas_for_nested_call.gas_left(), 50_000.into())
+	}
+
+	#[test]
+	fn nested_excess_gas_requested() {
+		let test_weight = Weight::from_parts(50000, 50000);
+		let mut gas_meter = GasMeter::<Test>::new(test_weight);
+		let gas_for_nested_call = gas_meter.nested(test_weight + 10000.into());
+
+		assert_eq!(gas_meter.gas_left(), Weight::from_parts(0, 0));
+		assert_eq!(gas_for_nested_call.gas_left(), 50_000.into())
+	}
+
 	// Make sure that the gas meter does not charge in case of overcharge
 	#[test]
 	fn overcharge_does_not_charge() {
diff --git a/substrate/frame/revive/src/primitives.rs b/substrate/frame/revive/src/primitives.rs
index a7127f812b4..452d2c8a306 100644
--- a/substrate/frame/revive/src/primitives.rs
+++ b/substrate/frame/revive/src/primitives.rs
@@ -72,7 +72,7 @@ pub struct ContractResult<R, Balance, EventRecord> {
 	///
 	/// # Note
 	///
-	/// This can only different from [`Self::gas_consumed`] when weight pre charging
+	/// This can only be different from [`Self::gas_consumed`] when weight pre charging
 	/// is used. Currently, only `seal_call_runtime` makes use of pre charging.
 	/// Additionally, any `seal_call` or `seal_instantiate` makes use of pre-charging
 	/// when a non-zero `gas_limit` argument is supplied.
diff --git a/substrate/frame/revive/src/storage/meter.rs b/substrate/frame/revive/src/storage/meter.rs
index 6eddf048be9..4febcb0c406 100644
--- a/substrate/frame/revive/src/storage/meter.rs
+++ b/substrate/frame/revive/src/storage/meter.rs
@@ -101,12 +101,8 @@ pub struct Root;
 
 /// State parameter that constitutes a meter that is in its nested state.
 /// Its value indicates whether the nested meter has its own limit.
-#[derive(DefaultNoBound, RuntimeDebugNoBound)]
-pub enum Nested {
-	#[default]
-	DerivedLimit,
-	OwnLimit,
-}
+#[derive(Default, Debug)]
+pub struct Nested;
 
 impl State for Root {}
 impl State for Nested {}
@@ -125,10 +121,8 @@ pub struct RawMeter<T: Config, E, S: State + Default + Debug> {
 	/// We only have one charge per contract hence the size of this vector is
 	/// limited by the maximum call depth.
 	charges: Vec<Charge<T>>,
-	/// We store the nested state to determine if it has a special limit for sub-call.
-	nested: S,
 	/// Type parameter only used in impls.
-	_phantom: PhantomData<E>,
+	_phantom: PhantomData<(E, S)>,
 }
 
 /// This type is used to describe a storage change when charging from the meter.
@@ -281,21 +275,14 @@ where
 	S: State + Default + Debug,
 {
 	/// Create a new child that has its `limit`.
-	/// Passing `0` as the limit is interpreted as to take whatever is remaining from its parent.
 	///
 	/// This is called whenever a new subcall is initiated in order to track the storage
 	/// usage for this sub call separately. This is necessary because we want to exchange balance
 	/// with the current contract we are interacting with.
 	pub fn nested(&self, limit: BalanceOf<T>) -> RawMeter<T, E, Nested> {
 		debug_assert!(matches!(self.contract_state(), ContractState::Alive));
-		// If a special limit is specified higher than it is available,
-		// we want to enforce the lesser limit to the nested meter, to fail in the sub-call.
-		let limit = self.available().min(limit);
-		if limit.is_zero() {
-			RawMeter { limit: self.available(), ..Default::default() }
-		} else {
-			RawMeter { limit, nested: Nested::OwnLimit, ..Default::default() }
-		}
+
+		RawMeter { limit: self.available().min(limit), ..Default::default() }
 	}
 
 	/// Absorb a child that was spawned to handle a sub call.
@@ -477,13 +464,6 @@ impl<T: Config, E: Ext<T>> RawMeter<T, E, Nested> {
 
 	/// [`Self::charge`] does not enforce the storage limit since we want to do this check as late
 	/// as possible to allow later refunds to offset earlier charges.
-	///
-	/// # Note
-	///
-	/// We normally need to call this **once** for every call stack and not for every cross contract
-	/// call. However, if a dedicated limit is specified for a sub-call, this needs to be called
-	/// once the sub-call has returned. For this, the [`Self::enforce_subcall_limit`] wrapper is
-	/// used.
 	pub fn enforce_limit(
 		&mut self,
 		info: Option<&mut ContractInfo<T>>,
@@ -502,18 +482,6 @@ impl<T: Config, E: Ext<T>> RawMeter<T, E, Nested> {
 		}
 		Ok(())
 	}
-
-	/// This is a wrapper around [`Self::enforce_limit`] to use on the exit from a sub-call to
-	/// enforce its special limit if needed.
-	pub fn enforce_subcall_limit(
-		&mut self,
-		info: Option<&mut ContractInfo<T>>,
-	) -> Result<(), DispatchError> {
-		match self.nested {
-			Nested::OwnLimit => self.enforce_limit(info),
-			Nested::DerivedLimit => Ok(()),
-		}
-	}
 }
 
 impl<T: Config> Ext<T> for ReservingExt {
@@ -724,6 +692,49 @@ mod tests {
 		)
 	}
 
+	/// Previously, passing a limit of 0 meant unlimited storage for a nested call.
+	///
+	/// Now, a limit of 0 means the subcall will not be able to use any storage.
+	#[test]
+	fn nested_zero_limit_requested() {
+		clear_ext();
+
+		let meter = TestMeter::new(&Origin::from_account_id(ALICE), 1_000, 0).unwrap();
+		assert_eq!(meter.available(), 1_000);
+		let nested0 = meter.nested(BalanceOf::<Test>::zero());
+		assert_eq!(nested0.available(), 0);
+	}
+
+	#[test]
+	fn nested_some_limit_requested() {
+		clear_ext();
+
+		let meter = TestMeter::new(&Origin::from_account_id(ALICE), 1_000, 0).unwrap();
+		assert_eq!(meter.available(), 1_000);
+		let nested0 = meter.nested(500);
+		assert_eq!(nested0.available(), 500);
+	}
+
+	#[test]
+	fn nested_all_limit_requested() {
+		clear_ext();
+
+		let meter = TestMeter::new(&Origin::from_account_id(ALICE), 1_000, 0).unwrap();
+		assert_eq!(meter.available(), 1_000);
+		let nested0 = meter.nested(1_000);
+		assert_eq!(nested0.available(), 1_000);
+	}
+
+	#[test]
+	fn nested_over_limit_requested() {
+		clear_ext();
+
+		let meter = TestMeter::new(&Origin::from_account_id(ALICE), 1_000, 0).unwrap();
+		assert_eq!(meter.available(), 1_000);
+		let nested0 = meter.nested(2_000);
+		assert_eq!(nested0.available(), 1_000);
+	}
+
 	#[test]
 	fn empty_charge_works() {
 		clear_ext();
@@ -879,7 +890,7 @@ mod tests {
 			let mut meter = TestMeter::new(&test_case.origin, 1_000, 0).unwrap();
 			assert_eq!(meter.available(), 1_000);
 
-			let mut nested0 = meter.nested(BalanceOf::<Test>::zero());
+			let mut nested0 = meter.nested(BalanceOf::<Test>::max_value());
 			nested0.charge(&Diff {
 				bytes_added: 5,
 				bytes_removed: 1,
@@ -895,7 +906,7 @@ mod tests {
 				items_deposit: 20,
 				immutable_data_len: 0,
 			});
-			let mut nested1 = nested0.nested(BalanceOf::<Test>::zero());
+			let mut nested1 = nested0.nested(BalanceOf::<Test>::max_value());
 			nested1.charge(&Diff { items_removed: 5, ..Default::default() });
 			nested1.charge(&Diff { bytes_added: 20, ..Default::default() });
 			nested1.terminate(&nested1_info, CHARLIE);
diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs
index 664578bf767..cf02d17a4d0 100644
--- a/substrate/frame/revive/src/tests.rs
+++ b/substrate/frame/revive/src/tests.rs
@@ -1149,7 +1149,7 @@ fn delegate_call() {
 
 		assert_ok!(builder::call(caller_addr)
 			.value(1337)
-			.data((callee_addr, 0u64, 0u64).encode())
+			.data((callee_addr, u64::MAX, u64::MAX).encode())
 			.build());
 	});
 }
@@ -2261,12 +2261,12 @@ fn gas_estimation_for_subcalls() {
 
 		// Run the test for all of those weight limits for the subcall
 		let weights = [
-			Weight::zero(),
+			Weight::MAX,
 			GAS_LIMIT,
 			GAS_LIMIT * 2,
 			GAS_LIMIT / 5,
-			Weight::from_parts(0, GAS_LIMIT.proof_size()),
-			Weight::from_parts(GAS_LIMIT.ref_time(), 0),
+			Weight::from_parts(u64::MAX, GAS_LIMIT.proof_size()),
+			Weight::from_parts(GAS_LIMIT.ref_time(), u64::MAX),
 		];
 
 		// This call is passed to the sub call in order to create a large `required_weight`
@@ -3453,13 +3453,13 @@ fn deposit_limit_in_nested_calls() {
 
 		// We do not remove any storage but add a storage item of 12 bytes in the caller
 		// contract. This would cost 12 + 2 = 14 Balance.
-		// The nested call doesn't get a special limit, which is set by passing 0 to it.
+		// The nested call doesn't get a special limit, which is set by passing `u64::MAX` to it.
 		// This should fail as the specified parent's limit is less than the cost: 13 <
 		// 14.
 		assert_err_ignore_postinfo!(
 			builder::call(addr_caller)
 				.storage_deposit_limit(13)
-				.data((100u32, &addr_callee, U256::from(0u64)).encode())
+				.data((100u32, &addr_callee, U256::MAX).encode())
 				.build(),
 			<Error<Test>>::StorageDepositLimitExhausted,
 		);
@@ -3467,13 +3467,13 @@ fn deposit_limit_in_nested_calls() {
 		// Now we specify the parent's limit high enough to cover the caller's storage
 		// additions. However, we use a single byte more in the callee, hence the storage
 		// deposit should be 15 Balance.
-		// The nested call doesn't get a special limit, which is set by passing 0 to it.
+		// The nested call doesn't get a special limit, which is set by passing `u64::MAX` to it.
 		// This should fail as the specified parent's limit is less than the cost: 14
 		// < 15.
 		assert_err_ignore_postinfo!(
 			builder::call(addr_caller)
 				.storage_deposit_limit(14)
-				.data((101u32, &addr_callee, U256::from(0u64)).encode())
+				.data((101u32, &addr_callee, &U256::MAX).encode())
 				.build(),
 			<Error<Test>>::StorageDepositLimitExhausted,
 		);
@@ -3495,7 +3495,7 @@ fn deposit_limit_in_nested_calls() {
 		assert_err_ignore_postinfo!(
 			builder::call(addr_caller)
 				.storage_deposit_limit(0)
-				.data((87u32, &addr_callee, U256::from(0u64)).encode())
+				.data((87u32, &addr_callee, &U256::MAX.to_little_endian()).encode())
 				.build(),
 			<Error<Test>>::StorageDepositLimitExhausted,
 		);
@@ -3551,28 +3551,24 @@ fn deposit_limit_in_nested_instantiate() {
 		//
 		// Provided the limit is set to be 1 Balance less,
 		// this call should fail on the return from the caller contract.
-		assert_err_ignore_postinfo!(
-			builder::call(addr_caller)
-				.origin(RuntimeOrigin::signed(BOB))
-				.storage_deposit_limit(callee_info_len + 2 + ED + 1)
-				.data((0u32, &code_hash_callee, U256::from(0u64)).encode())
-				.build(),
-			<Error<Test>>::StorageDepositLimitExhausted,
-		);
+		let ret = builder::bare_call(addr_caller)
+			.origin(RuntimeOrigin::signed(BOB))
+			.storage_deposit_limit(DepositLimit::Balance(callee_info_len + 2 + ED + 1))
+			.data((0u32, &code_hash_callee, &U256::MAX.to_little_endian()).encode())
+			.build_and_unwrap_result();
+		assert_return_code!(ret, RuntimeReturnCode::OutOfResources);
 		// The charges made on instantiation should be rolled back.
 		assert_eq!(<Test as Config>::Currency::free_balance(&BOB), 1_000_000);
 
 		// Now we give enough limit for the instantiation itself, but require for 1 more storage
 		// byte in the constructor. Hence +1 Balance to the limit is needed. This should fail on
 		// the return from constructor.
-		assert_err_ignore_postinfo!(
-			builder::call(addr_caller)
-				.origin(RuntimeOrigin::signed(BOB))
-				.storage_deposit_limit(callee_info_len + 2 + ED + 2)
-				.data((1u32, &code_hash_callee, U256::from(0u64)).encode())
-				.build(),
-			<Error<Test>>::StorageDepositLimitExhausted,
-		);
+		let ret = builder::bare_call(addr_caller)
+			.origin(RuntimeOrigin::signed(BOB))
+			.storage_deposit_limit(DepositLimit::Balance(callee_info_len + 2 + ED + 2))
+			.data((1u32, &code_hash_callee, U256::from(0u64)).encode())
+			.build_and_unwrap_result();
+		assert_return_code!(ret, RuntimeReturnCode::OutOfResources);
 		// The charges made on the instantiation should be rolled back.
 		assert_eq!(<Test as Config>::Currency::free_balance(&BOB), 1_000_000);
 
@@ -4856,20 +4852,18 @@ fn skip_transfer_works() {
 		);
 
 		// fails when calling from a contract when gas is specified.
-		assert_err!(
-			Pallet::<Test>::bare_eth_transact(
-				GenericTransaction {
-					from: Some(BOB_ADDR),
-					to: Some(caller_addr),
-					input: Some((0u32, &addr).encode().into()),
-					gas: Some(1u32.into()),
-					..Default::default()
-				},
-				Weight::MAX,
-				|_| 0u32
-			),
-			EthTransactError::Message(format!("insufficient funds for gas * price + value: address {BOB_ADDR:?} have 0 (supplied gas 1)"))
-		);
+		assert!(Pallet::<Test>::bare_eth_transact(
+			GenericTransaction {
+				from: Some(BOB_ADDR),
+				to: Some(caller_addr),
+				input: Some((0u32, &addr).encode().into()),
+				gas: Some(1u32.into()),
+				..Default::default()
+			},
+			Weight::MAX,
+			|_| 0u32
+		)
+		.is_err(),);
 
 		// works when no gas is specified.
 		assert_ok!(Pallet::<Test>::bare_eth_transact(
diff --git a/substrate/frame/revive/src/wasm/runtime.rs b/substrate/frame/revive/src/wasm/runtime.rs
index 52f79f2eb55..8529c7d9e73 100644
--- a/substrate/frame/revive/src/wasm/runtime.rs
+++ b/substrate/frame/revive/src/wasm/runtime.rs
@@ -1004,8 +1004,7 @@ impl<'a, E: Ext, M: ?Sized + Memory<E::T>> Runtime<'a, E, M> {
 		self.charge_gas(call_type.cost())?;
 
 		let callee = memory.read_h160(callee_ptr)?;
-		let deposit_limit =
-			if deposit_ptr == SENTINEL { U256::zero() } else { memory.read_u256(deposit_ptr)? };
+		let deposit_limit = memory.read_u256(deposit_ptr)?;
 
 		let input_data = if flags.contains(CallFlags::CLONE_INPUT) {
 			let input = self.input_data.as_ref().ok_or(Error::<E::T>::InputForwarded)?;
@@ -1091,8 +1090,7 @@ impl<'a, E: Ext, M: ?Sized + Memory<E::T>> Runtime<'a, E, M> {
 		salt_ptr: u32,
 	) -> Result<ReturnErrorCode, TrapReason> {
 		self.charge_gas(RuntimeCosts::Instantiate { input_data_len })?;
-		let deposit_limit: U256 =
-			if deposit_ptr == SENTINEL { U256::zero() } else { memory.read_u256(deposit_ptr)? };
+		let deposit_limit: U256 = memory.read_u256(deposit_ptr)?;
 		let value = memory.read_u256(value_ptr)?;
 		let code_hash = memory.read_h256(code_hash_ptr)?;
 		let input_data = memory.read(input_data_ptr, input_data_len)?;
diff --git a/substrate/frame/revive/uapi/src/host.rs b/substrate/frame/revive/uapi/src/host.rs
index d90c0f45205..ba0a63b15c3 100644
--- a/substrate/frame/revive/uapi/src/host.rs
+++ b/substrate/frame/revive/uapi/src/host.rs
@@ -113,7 +113,7 @@ pub trait HostFn: private::Sealed {
 		callee: &[u8; 20],
 		ref_time_limit: u64,
 		proof_size_limit: u64,
-		deposit: Option<&[u8; 32]>,
+		deposit: &[u8; 32],
 		value: &[u8; 32],
 		input_data: &[u8],
 		output: Option<&mut &mut [u8]>,
@@ -202,7 +202,7 @@ pub trait HostFn: private::Sealed {
 		address: &[u8; 20],
 		ref_time_limit: u64,
 		proof_size_limit: u64,
-		deposit_limit: Option<&[u8; 32]>,
+		deposit_limit: &[u8; 32],
 		input_data: &[u8],
 		output: Option<&mut &mut [u8]>,
 	) -> Result;
@@ -318,7 +318,7 @@ pub trait HostFn: private::Sealed {
 		code_hash: &[u8; 32],
 		ref_time_limit: u64,
 		proof_size_limit: u64,
-		deposit: Option<&[u8; 32]>,
+		deposit: &[u8; 32],
 		value: &[u8; 32],
 		input: &[u8],
 		address: Option<&mut [u8; 20]>,
diff --git a/substrate/frame/revive/uapi/src/host/riscv64.rs b/substrate/frame/revive/uapi/src/host/riscv64.rs
index c83be942a97..8c40bc9f48e 100644
--- a/substrate/frame/revive/uapi/src/host/riscv64.rs
+++ b/substrate/frame/revive/uapi/src/host/riscv64.rs
@@ -168,7 +168,7 @@ impl HostFn for HostFnImpl {
 		code_hash: &[u8; 32],
 		ref_time_limit: u64,
 		proof_size_limit: u64,
-		deposit_limit: Option<&[u8; 32]>,
+		deposit_limit: &[u8; 32],
 		value: &[u8; 32],
 		input: &[u8],
 		mut address: Option<&mut [u8; 20]>,
@@ -180,7 +180,7 @@ impl HostFn for HostFnImpl {
 			None => crate::SENTINEL as _,
 		};
 		let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
-		let deposit_limit_ptr = ptr_or_sentinel(&deposit_limit);
+		let deposit_limit_ptr = deposit_limit.as_ptr();
 		let salt_ptr = ptr_or_sentinel(&salt);
 		#[repr(C)]
 		#[allow(dead_code)]
@@ -225,13 +225,13 @@ impl HostFn for HostFnImpl {
 		callee: &[u8; 20],
 		ref_time_limit: u64,
 		proof_size_limit: u64,
-		deposit_limit: Option<&[u8; 32]>,
+		deposit_limit: &[u8; 32],
 		value: &[u8; 32],
 		input: &[u8],
 		mut output: Option<&mut &mut [u8]>,
 	) -> Result {
 		let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
-		let deposit_limit_ptr = ptr_or_sentinel(&deposit_limit);
+		let deposit_limit_ptr = deposit_limit.as_ptr();
 		#[repr(C)]
 		#[allow(dead_code)]
 		struct Args {
@@ -273,12 +273,12 @@ impl HostFn for HostFnImpl {
 		address: &[u8; 20],
 		ref_time_limit: u64,
 		proof_size_limit: u64,
-		deposit_limit: Option<&[u8; 32]>,
+		deposit_limit: &[u8; 32],
 		input: &[u8],
 		mut output: Option<&mut &mut [u8]>,
 	) -> Result {
 		let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
-		let deposit_limit_ptr = ptr_or_sentinel(&deposit_limit);
+		let deposit_limit_ptr = deposit_limit.as_ptr();
 		#[repr(C)]
 		#[allow(dead_code)]
 		struct Args {
-- 
GitLab