Repository: paritytech/substrate
File: frame/contracts/src/exec.rs (Rust)

Code before:
				// if we reached this point the origin has an associated account.
				let origin = &self.origin.account_id()?;
				let frame = top_frame_mut!(self);
				frame.nested_storage.charge_instantiate(
					origin,
					&frame.account_id,
					frame.contract_info.get(&frame.account_id),
					executable.code_info(),
				)?;
			}

			// Every non delegate call or instantiate also optionally transfers the balance.
			self.initial_transfer()?;

			#[cfg(feature = "unsafe-debug")]
			let code_hash = executable.code_hash().clone();
			#[cfg(feature = "unsafe-debug")]
			T::Debug::before_call(&code_hash, entry_point, &input_data);

			// Call into the Wasm blob.
			let output = executable
				.execute(self, &entry_point, input_data.clone())
				.map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee })?;

			#[cfg(feature = "unsafe-debug")]
			T::Debug::after_call(&code_hash, entry_point, &input_data, &output);

			// Avoid useless work that would be reverted anyways.
			if output.did_revert() {
				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();
			let account_id = &frame.account_id.clone();
			match (entry_point, delegated_code_hash) {
				(ExportedFunction::Constructor, _) => {
					// It is not allowed to terminate a contract inside its constructor.
					if matches!(frame.contract_info, CachedContract::Terminated(_)) {
						return Err(Error::<T>::TerminatedInConstructor.into())
					}

Review comment (bug):
We can move the input vector since we don't need it anymore. In case the debugger wants to store the data.

```suggestion
			T::Debug::after_call(&code_hash, entry_point, input_clone, &output);
```

Code after:
				// Root origin can't be used to instantiate a contract, so it is safe to assume that
				// if we reached this point the origin has an associated account.
				let origin = &self.origin.account_id()?;
				let frame = top_frame_mut!(self);
				frame.nested_storage.charge_instantiate(
					origin,
					&frame.account_id,
					frame.contract_info.get(&frame.account_id),
					executable.code_info(),
				)?;
			}

			// Every non delegate call or instantiate also optionally transfers the balance.
			self.initial_transfer()?;

			#[cfg(feature = "unsafe-debug")]
			let (code_hash, input_clone) = {
				let code_hash = *executable.code_hash();
				T::Debug::before_call(&code_hash, entry_point, &input_data);
				(code_hash, input_data.clone())
			};

			// Call into the Wasm blob.
			let output = executable
				.execute(self, &entry_point, input_data)
				.map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee })?;

			#[cfg(feature = "unsafe-debug")]
			T::Debug::after_call(&code_hash, entry_point, input_clone, &output);

			// Avoid useless work that would be reverted anyways.
			if output.did_revert() {
				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();
			let account_id = &frame.account_id.clone();
			match (entry_point, delegated_code_hash) {
				(ExportedFunction::Constructor, _) => {
					// It is not allowed to terminate a contract inside its constructor.