use super::*;
use gear_core::{
ids::prelude::*,
pages::WasmPage,
program::{MemoryInfix, ProgramState},
reservation::GasReservationMap,
};
use gear_wasm_instrument::{
Export, FuncType, Function, Import, Instruction, Module, ModuleBuilder, ValType,
};
use sp_io::hashing::blake2_256;
use sp_runtime::traits::Zero;
pub fn account<AccountId: Origin>(name: &'static str, index: u32, seed: u32) -> AccountId {
let entropy = (name, index, seed).using_encoded(blake2_256);
H256::from_slice(&entropy[..]).cast()
}
pub fn create_module(num_pages: WasmPage) -> Module {
let mut mbuilder = ModuleBuilder::default();
mbuilder.push_import(Import::memory(num_pages.into(), None));
mbuilder.add_func(FuncType::new([], []), Function::default());
mbuilder.push_export(Export::func("init", 0));
mbuilder.build()
}
pub fn generate_wasm(num_pages: WasmPage) -> Result<Vec<u8>, &'static str> {
let mut mbuilder = ModuleBuilder::default();
mbuilder.push_import(Import::memory(num_pages.into(), None));
let alloc_idx = mbuilder.push_type(FuncType::new([ValType::I32], [ValType::I32]));
mbuilder.push_import(Import::func("env", "alloc", alloc_idx));
let init_idx = mbuilder.add_func(FuncType::new([], []), Function::default());
mbuilder.push_export(Export::func("init", init_idx));
let handle_idx = mbuilder.add_func(
FuncType::new([], []),
Function {
locals: vec![(1, ValType::I32)],
instructions: vec![
Instruction::I32Const(u32::from(num_pages) as i32),
Instruction::Call(0),
Instruction::LocalSet(0),
Instruction::End,
],
},
);
mbuilder.push_export(Export::func("handle", handle_idx));
let code = mbuilder
.build()
.serialize()
.map_err(|_| "Failed to serialize module")?;
Ok(code)
}
pub fn set_program<ProgramStorage, BlockNumber>(program_id: ActorId, code: Vec<u8>)
where
ProgramStorage: super::ProgramStorage<BlockNumber = BlockNumber>,
BlockNumber: Zero + Copy + Saturating,
{
ProgramStorage::add_program(
program_id,
ActiveProgram {
allocations_tree_len: 0,
code_id: CodeId::generate(&code),
state: ProgramState::Initialized,
gas_reservation_map: GasReservationMap::default(),
expiration_block: Zero::zero(),
memory_infix: MemoryInfix::new(1u32),
},
)
.expect("benchmarking; program duplicates should not exist");
}