lib.rs 41.4 KiB
Newer Older
		let schedule = T::Schedule::get();
		PrefabWasmModule::store_code_unchecked(code, &schedule, owner)?;
		Ok(())
	}

	/// This exists so that benchmarks can determine the weight of running an instrumentation.
	#[cfg(feature = "runtime-benchmarks")]
	fn reinstrument_module(
		module: &mut PrefabWasmModule<T>,
		schedule: &Schedule<T>,
	) -> frame_support::dispatch::DispatchResult {
		self::wasm::reinstrument(module, schedule).map(|_| ())

	/// Internal function that does the actual call.
	///
	/// Called by dispatchables and public functions.
	fn internal_call(
		origin: T::AccountId,
		dest: T::AccountId,
		value: BalanceOf<T>,
		gas_limit: Weight,
		storage_deposit_limit: Option<BalanceOf<T>>,
		data: Vec<u8>,
		debug_message: Option<&mut Vec<u8>>,
	) -> InternalCallOutput<T> {
		let mut gas_meter = GasMeter::new(gas_limit);
		let mut storage_meter = match StorageMeter::new(&origin, storage_deposit_limit, value) {
			Ok(meter) => meter,
			Err(err) =>
				return InternalCallOutput {
					result: Err(err.into()),
					gas_meter,
					storage_deposit: Default::default(),
				},
		};
		let schedule = T::Schedule::get();
		let result = ExecStack::<T, PrefabWasmModule<T>>::run_call(
			origin,
			dest,
			&mut gas_meter,
			&mut storage_meter,
		InternalCallOutput { result, gas_meter, storage_deposit: storage_meter.into_deposit() }
	}

	/// Internal function that does the actual instantiation.
	///
	/// Called by dispatchables and public functions.
	fn internal_instantiate(
		origin: T::AccountId,
		value: BalanceOf<T>,
		storage_deposit_limit: Option<BalanceOf<T>>,
		code: Code<CodeHash<T>>,
		data: Vec<u8>,
		salt: Vec<u8>,
		mut debug_message: Option<&mut Vec<u8>>,
	) -> InternalInstantiateOutput<T> {
		let mut storage_deposit = Default::default();
		let mut gas_meter = GasMeter::new(gas_limit);
		let try_exec = || {
			let schedule = T::Schedule::get();
			let (extra_deposit, executable) = match code {
				Code::Upload(Bytes(binary)) => {
					let executable = PrefabWasmModule::from_code(binary, &schedule, origin.clone())
							debug_message.as_mut().map(|buffer| buffer.extend(msg.as_bytes()));
					// The open deposit will be charged during execution when the
					// uploaded module does not already exist. This deposit is not part of the
Sacha Lansky's avatar
Sacha Lansky committed
					// storage meter because it is not transferred to the contract but
					// reserved on the uploading account.
					(executable.open_deposit(), executable)
				Code::Existing(hash) => (
					Default::default(),
					PrefabWasmModule::from_storage(hash, &schedule, &mut gas_meter)?,
			let mut storage_meter = StorageMeter::new(
				&origin,
				storage_deposit_limit,
				value.saturating_add(extra_deposit),
			)?;
			let result = ExecStack::<T, PrefabWasmModule<T>>::run_instantiate(
				&mut storage_meter,
			);
			storage_deposit = storage_meter
				.into_deposit()
				.saturating_add(&StorageDeposit::Charge(extra_deposit));
			result
		InternalInstantiateOutput { result: try_exec(), gas_meter, storage_deposit }

	fn deposit_event(topics: Vec<T::Hash>, event: Event<T>) {
		<frame_system::Pallet<T>>::deposit_event_indexed(
			&topics,
			<T as Config>::RuntimeEvent::from(event).into(),