substrate.rs 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238
  1. // SPDX-License-Identifier: Apache-2.0
  2. use contract_metadata::ContractMetadata;
  3. use ink::metadata::InkProject;
  4. // Create WASM virtual machine like substrate
  5. use num_derive::FromPrimitive;
  6. use num_traits::FromPrimitive;
  7. use rand::Rng;
  8. use sha2::{Digest, Sha256};
  9. use std::{collections::HashMap, ffi::OsStr, fmt, fmt::Write};
  10. use tiny_keccak::{Hasher, Keccak};
  11. use wasmi::memory_units::Pages;
  12. use wasmi::*;
  13. use solang::file_resolver::FileResolver;
  14. use solang::{compile, Target};
  15. mod substrate_tests;
  16. type StorageKey = [u8; 32];
  17. type Account = [u8; 32];
  18. /// In `ink!`, u32::MAX (which is -1 in 2s complement) represents a `None` value
  19. const NONE_SENTINEL: RuntimeValue = RuntimeValue::I32(-1);
  20. fn account_new() -> Account {
  21. let mut rng = rand::thread_rng();
  22. let mut a = [0u8; 32];
  23. rng.fill(&mut a[..]);
  24. a
  25. }
  26. #[derive(Debug, Clone, PartialEq, Eq)]
  27. struct HostCodeTerminate {}
  28. impl HostError for HostCodeTerminate {}
  29. impl fmt::Display for HostCodeTerminate {
  30. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
  31. write!(f, "seal_terminate")
  32. }
  33. }
  34. #[derive(Debug, Clone, PartialEq, Eq)]
  35. struct HostCodeReturn(i32);
  36. impl fmt::Display for HostCodeReturn {
  37. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
  38. write!(f, "return {}", self.0)
  39. }
  40. }
  41. impl HostError for HostCodeReturn {}
  42. #[derive(FromPrimitive)]
  43. #[allow(non_camel_case_types)]
  44. enum SubstrateExternal {
  45. seal_input = 0,
  46. seal_set_storage,
  47. seal_clear_storage,
  48. seal_get_storage,
  49. seal_return,
  50. seal_hash_keccak_256,
  51. seal_debug_message,
  52. seal_call,
  53. seal_instantiate,
  54. seal_value_transferred,
  55. seal_minimum_balance,
  56. instantiation_nonce,
  57. seal_address,
  58. seal_balance,
  59. seal_terminate,
  60. seal_hash_sha2_256,
  61. seal_hash_blake2_128,
  62. seal_hash_blake2_256,
  63. seal_block_number,
  64. seal_now,
  65. seal_weight_to_fee,
  66. seal_gas_left,
  67. seal_caller,
  68. seal_deposit_event,
  69. seal_transfer,
  70. }
  71. pub struct Event {
  72. topics: Vec<[u8; 32]>,
  73. data: Vec<u8>,
  74. }
  75. pub struct VirtualMachine {
  76. account: Account,
  77. caller: Account,
  78. memory: MemoryRef,
  79. input: Vec<u8>,
  80. pub output: Vec<u8>,
  81. pub value: u128,
  82. }
  83. impl VirtualMachine {
  84. fn new(account: Account, caller: Account, value: u128) -> Self {
  85. VirtualMachine {
  86. memory: MemoryInstance::alloc(Pages(16), Some(Pages(16))).unwrap(),
  87. input: Vec::new(),
  88. output: Vec::new(),
  89. account,
  90. caller,
  91. value,
  92. }
  93. }
  94. }
  95. pub struct Program {
  96. abi: InkProject,
  97. code: Vec<u8>,
  98. }
  99. pub struct MockSubstrate {
  100. pub store: HashMap<(Account, StorageKey), Vec<u8>>,
  101. pub programs: Vec<Program>,
  102. pub printbuf: String,
  103. pub accounts: HashMap<Account, (Vec<u8>, u128)>,
  104. pub current_program: usize,
  105. pub vm: VirtualMachine,
  106. pub events: Vec<Event>,
  107. }
  108. impl Externals for MockSubstrate {
  109. #[allow(clippy::cognitive_complexity)]
  110. fn invoke_index(
  111. &mut self,
  112. index: usize,
  113. args: RuntimeArgs,
  114. ) -> Result<Option<RuntimeValue>, Trap> {
  115. macro_rules! set_seal_value {
  116. ($name:literal, $dest_ptr:expr, $len_ptr:expr, $buf:expr) => {{
  117. println!("{}: {}", $name, hex::encode($buf));
  118. let len = self
  119. .vm
  120. .memory
  121. .get_value::<u32>($len_ptr)
  122. .expect(&format!("{} len_ptr should be valid", $name));
  123. assert!(
  124. (len as usize) >= $buf.len(),
  125. "{} input is {} buffer is {}",
  126. $name,
  127. $buf.len(),
  128. len
  129. );
  130. if let Err(e) = self.vm.memory.set($dest_ptr, $buf) {
  131. panic!("{}: {}", $name, e);
  132. }
  133. self.vm
  134. .memory
  135. .set_value($len_ptr, $buf.len() as u32)
  136. .expect(&format!("{} len_ptr should be valid", $name));
  137. }};
  138. }
  139. match FromPrimitive::from_usize(index) {
  140. Some(SubstrateExternal::seal_input) => {
  141. let dest_ptr: u32 = args.nth_checked(0)?;
  142. let len_ptr: u32 = args.nth_checked(1)?;
  143. let len = self
  144. .vm
  145. .memory
  146. .get_value::<u32>(len_ptr)
  147. .expect("seal_input len_ptr should be valid");
  148. assert!(
  149. (len as usize) >= self.vm.input.len(),
  150. "input is {} seal_input buffer {}",
  151. self.vm.input.len(),
  152. len
  153. );
  154. if let Err(e) = self.vm.memory.set(dest_ptr, &self.vm.input) {
  155. panic!("seal_input: {e}");
  156. }
  157. self.vm
  158. .memory
  159. .set_value(len_ptr, self.vm.input.len() as u32)
  160. .expect("seal_input len_ptr should be valid");
  161. Ok(None)
  162. }
  163. Some(SubstrateExternal::seal_get_storage) => {
  164. assert_eq!(args.len(), 4);
  165. let key_ptr: u32 = args.nth_checked(0)?;
  166. let key_len: u32 = args.nth_checked(1)?;
  167. let dest_ptr: u32 = args.nth_checked(2)?;
  168. let len_ptr: u32 = args.nth_checked(3)?;
  169. assert_eq!(key_len, 32);
  170. let mut key: StorageKey = [0; 32];
  171. if let Err(e) = self.vm.memory.get_into(key_ptr, &mut key) {
  172. panic!("seal_get_storage: {e}");
  173. }
  174. if let Some(value) = self.store.get(&(self.vm.account, key)) {
  175. println!("seal_get_storage: {key:?} = {value:?}");
  176. let len = self
  177. .vm
  178. .memory
  179. .get_value::<u32>(len_ptr)
  180. .expect("seal_get_storage len_ptr should be valid");
  181. assert!(
  182. (len as usize) >= value.len(),
  183. "seal_get_storage buffer is too small"
  184. );
  185. if let Err(e) = self.vm.memory.set(dest_ptr, value) {
  186. panic!("seal_get_storage: {e}");
  187. }
  188. self.vm
  189. .memory
  190. .set_value(len_ptr, value.len() as u32)
  191. .expect("seal_get_storage len_ptr should be valid");
  192. Ok(Some(RuntimeValue::I32(0)))
  193. } else {
  194. println!("seal_get_storage: {key:?} = nil");
  195. Ok(Some(RuntimeValue::I32(1)))
  196. }
  197. }
  198. Some(SubstrateExternal::seal_clear_storage) => {
  199. let key_ptr: u32 = args.nth_checked(0)?;
  200. let key_len: u32 = args.nth_checked(1)?;
  201. assert_eq!(key_len, 32);
  202. let mut key: StorageKey = [0; 32];
  203. if let Err(e) = self.vm.memory.get_into(key_ptr, &mut key) {
  204. panic!("seal_clear_storage: {e}");
  205. }
  206. println!("seal_clear_storage: {key:?}");
  207. let pre_existing_len = self
  208. .store
  209. .remove(&(self.vm.account, key))
  210. .map(|e| RuntimeValue::I32(e.len() as i32))
  211. .or(Some(NONE_SENTINEL));
  212. Ok(pre_existing_len)
  213. }
  214. Some(SubstrateExternal::seal_set_storage) => {
  215. assert_eq!(args.len(), 4);
  216. let key_ptr: u32 = args.nth_checked(0)?;
  217. let key_len: u32 = args.nth_checked(1)?;
  218. let data_ptr: u32 = args.nth_checked(2)?;
  219. let len: u32 = args.nth_checked(3)?;
  220. assert_eq!(key_len, 32);
  221. let mut key: StorageKey = [0; 32];
  222. if let Err(e) = self.vm.memory.get_into(key_ptr, &mut key[..]) {
  223. panic!("seal_set_storage: {e}");
  224. }
  225. let mut data = Vec::new();
  226. data.resize(len as usize, 0u8);
  227. if let Err(e) = self.vm.memory.get_into(data_ptr, &mut data) {
  228. panic!("seal_set_storage: {e}");
  229. }
  230. println!("seal_set_storage: {key:?} = {data:?}");
  231. let pre_existing_len = self
  232. .store
  233. .insert((self.vm.account, key), data)
  234. .map(|e| RuntimeValue::I32(e.len() as i32))
  235. .or(Some(NONE_SENTINEL));
  236. Ok(pre_existing_len)
  237. }
  238. Some(SubstrateExternal::seal_hash_keccak_256) => {
  239. let data_ptr: u32 = args.nth_checked(0)?;
  240. let len: u32 = args.nth_checked(1)?;
  241. let out_ptr: u32 = args.nth_checked(2)?;
  242. let mut data = Vec::new();
  243. data.resize(len as usize, 0);
  244. if let Err(e) = self.vm.memory.get_into(data_ptr, &mut data) {
  245. panic!("seal_hash_keccak_256: {e}");
  246. }
  247. let mut hasher = Keccak::v256();
  248. let mut hash = [0u8; 32];
  249. hasher.update(&data);
  250. hasher.finalize(&mut hash);
  251. println!(
  252. "seal_hash_keccak_256: {} = {}",
  253. hex::encode(data),
  254. hex::encode(hash)
  255. );
  256. if let Err(e) = self.vm.memory.set(out_ptr, &hash) {
  257. panic!("seal_hash_keccak_256: {e}");
  258. }
  259. Ok(None)
  260. }
  261. Some(SubstrateExternal::seal_hash_sha2_256) => {
  262. let data_ptr: u32 = args.nth_checked(0)?;
  263. let len: u32 = args.nth_checked(1)?;
  264. let out_ptr: u32 = args.nth_checked(2)?;
  265. let mut data = Vec::new();
  266. data.resize(len as usize, 0);
  267. if let Err(e) = self.vm.memory.get_into(data_ptr, &mut data) {
  268. panic!("seal_hash_sha2_256: {e}");
  269. }
  270. let mut hasher = Sha256::new();
  271. hasher.update(&data);
  272. let hash = hasher.finalize();
  273. println!(
  274. "seal_hash_sha2_256: {} = {}",
  275. hex::encode(data),
  276. hex::encode(hash)
  277. );
  278. if let Err(e) = self.vm.memory.set(out_ptr, &hash) {
  279. panic!("seal_hash_sha2_256: {e}");
  280. }
  281. Ok(None)
  282. }
  283. Some(SubstrateExternal::seal_hash_blake2_128) => {
  284. let data_ptr: u32 = args.nth_checked(0)?;
  285. let len: u32 = args.nth_checked(1)?;
  286. let out_ptr: u32 = args.nth_checked(2)?;
  287. let mut data = Vec::new();
  288. data.resize(len as usize, 0);
  289. if let Err(e) = self.vm.memory.get_into(data_ptr, &mut data) {
  290. panic!("seal_hash_blake2_128: {e}");
  291. }
  292. let hash = blake2_rfc::blake2b::blake2b(16, &[], &data);
  293. println!(
  294. "seal_hash_blake2_128: {} = {}",
  295. hex::encode(data),
  296. hex::encode(hash)
  297. );
  298. if let Err(e) = self.vm.memory.set(out_ptr, hash.as_bytes()) {
  299. panic!("seal_hash_blake2_128: {e}");
  300. }
  301. Ok(None)
  302. }
  303. Some(SubstrateExternal::seal_hash_blake2_256) => {
  304. let data_ptr: u32 = args.nth_checked(0)?;
  305. let len: u32 = args.nth_checked(1)?;
  306. let out_ptr: u32 = args.nth_checked(2)?;
  307. let mut data = Vec::new();
  308. data.resize(len as usize, 0);
  309. if let Err(e) = self.vm.memory.get_into(data_ptr, &mut data) {
  310. panic!("seal_hash_blake2_256: {e}");
  311. }
  312. let hash = blake2_rfc::blake2b::blake2b(32, &[], &data);
  313. println!(
  314. "seal_hash_blake2_256: {} = {}",
  315. hex::encode(data),
  316. hex::encode(hash)
  317. );
  318. if let Err(e) = self.vm.memory.set(out_ptr, hash.as_bytes()) {
  319. panic!("seal_hash_blake2_256: {e}");
  320. }
  321. Ok(None)
  322. }
  323. Some(SubstrateExternal::seal_return) => {
  324. let flags: i32 = args.nth_checked(0)?;
  325. let data_ptr: u32 = args.nth_checked(1)?;
  326. let len: u32 = args.nth_checked(2)?;
  327. self.vm.output.resize(len as usize, 0u8);
  328. if let Err(e) = self.vm.memory.get_into(data_ptr, &mut self.vm.output) {
  329. panic!("seal_return: {e}");
  330. }
  331. match flags {
  332. 0 | 1 => Err(Trap::new(TrapKind::Host(Box::new(HostCodeReturn(flags))))),
  333. _ => panic!("seal_return flag {flags} not valid"),
  334. }
  335. }
  336. Some(SubstrateExternal::seal_debug_message) => {
  337. let data_ptr: u32 = args.nth_checked(0)?;
  338. let len: u32 = args.nth_checked(1)?;
  339. let mut buf = Vec::new();
  340. buf.resize(len as usize, 0u8);
  341. if let Err(e) = self.vm.memory.get_into(data_ptr, &mut buf) {
  342. panic!("seal_debug_message: {e}");
  343. }
  344. let s = String::from_utf8(buf).expect("seal_debug_message: Invalid UFT8");
  345. println!("seal_debug_message: {s}");
  346. self.printbuf.push_str(&s);
  347. Ok(Some(RuntimeValue::I32(0)))
  348. }
  349. Some(SubstrateExternal::instantiation_nonce) => {
  350. Ok(Some(RuntimeValue::I64(self.accounts.len() as i64)))
  351. }
  352. Some(SubstrateExternal::seal_call) => {
  353. let flags: u32 = args.nth_checked(0)?;
  354. let account_ptr: u32 = args.nth_checked(1)?;
  355. // Gas usage is ignored in the mock VM
  356. let value_ptr: u32 = args.nth_checked(3)?;
  357. let input_ptr: u32 = args.nth_checked(4)?;
  358. let input_len: u32 = args.nth_checked(5)?;
  359. let output_ptr: u32 = args.nth_checked(6)?;
  360. let output_len_ptr: u32 = args.nth_checked(7)?;
  361. assert_eq!(flags, 0); //TODO: Call flags are not yet implemented
  362. let mut account = [0u8; 32];
  363. if let Err(e) = self.vm.memory.get_into(account_ptr, &mut account) {
  364. panic!("seal_call: {e}");
  365. }
  366. let mut value = [0u8; 16];
  367. if let Err(e) = self.vm.memory.get_into(value_ptr, &mut value) {
  368. panic!("seal_call: {e}");
  369. }
  370. let value = u128::from_le_bytes(value);
  371. if !self.accounts.contains_key(&account) {
  372. // substrate would return NotCallable
  373. return Ok(Some(RuntimeValue::I32(0x8)));
  374. }
  375. let mut input = Vec::new();
  376. input.resize(input_len as usize, 0u8);
  377. if let Err(e) = self.vm.memory.get_into(input_ptr, &mut input) {
  378. panic!("seal_call: {e}");
  379. }
  380. println!(
  381. "seal_call: account={} input={}",
  382. hex::encode(account),
  383. hex::encode(&input)
  384. );
  385. let mut vm = VirtualMachine::new(account, self.vm.account, value);
  386. std::mem::swap(&mut self.vm, &mut vm);
  387. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  388. self.vm.input = input;
  389. let ret = module.invoke_export("call", &[], self);
  390. let ret = match ret {
  391. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  392. TrapKind::Host(host_error) => {
  393. if let Some(ret) = host_error.downcast_ref::<HostCodeReturn>() {
  394. Some(RuntimeValue::I32(ret.0))
  395. } else if host_error.downcast_ref::<HostCodeTerminate>().is_some() {
  396. Some(RuntimeValue::I32(1))
  397. } else {
  398. return Err(trap);
  399. }
  400. }
  401. _ => {
  402. return Err(trap);
  403. }
  404. },
  405. Ok(v) => v,
  406. Err(e) => panic!("fail to invoke call: {e}"),
  407. };
  408. let output = self.vm.output.clone();
  409. std::mem::swap(&mut self.vm, &mut vm);
  410. println!("seal_call ret={:?} buf={}", ret, hex::encode(&output));
  411. if let Some(acc) = self.accounts.get_mut(&vm.account) {
  412. acc.1 += vm.value;
  413. }
  414. set_seal_value!("seal_call return buf", output_ptr, output_len_ptr, &output);
  415. Ok(ret)
  416. }
  417. Some(SubstrateExternal::seal_transfer) => {
  418. let account_ptr: u32 = args.nth_checked(0)?;
  419. let account_len: u32 = args.nth_checked(1)?;
  420. let value_ptr: u32 = args.nth_checked(2)?;
  421. let value_len: u32 = args.nth_checked(3)?;
  422. let mut account = [0u8; 32];
  423. assert!(account_len == 32, "seal_transfer: len = {account_len}");
  424. if let Err(e) = self.vm.memory.get_into(account_ptr, &mut account) {
  425. panic!("seal_transfer: {e}");
  426. }
  427. let mut value = [0u8; 16];
  428. assert!(value_len == 16, "seal_transfer: len = {value_len}");
  429. if let Err(e) = self.vm.memory.get_into(value_ptr, &mut value) {
  430. panic!("seal_transfer: {e}");
  431. }
  432. let value = u128::from_le_bytes(value);
  433. if !self.accounts.contains_key(&account) {
  434. // substrate would return TransferFailed
  435. return Ok(Some(RuntimeValue::I32(0x5)));
  436. }
  437. if let Some(acc) = self.accounts.get_mut(&account) {
  438. acc.1 += value;
  439. }
  440. Ok(Some(RuntimeValue::I32(0)))
  441. }
  442. Some(SubstrateExternal::seal_instantiate) => {
  443. let codehash_ptr: u32 = args.nth_checked(0)?;
  444. // Gas usage is ignored in the mock VM
  445. let value_ptr: u32 = args.nth_checked(2)?;
  446. let input_ptr: u32 = args.nth_checked(3)?;
  447. let input_len: u32 = args.nth_checked(4)?;
  448. let account_ptr: u32 = args.nth_checked(5)?;
  449. let account_len_ptr: u32 = args.nth_checked(6)?;
  450. let output_ptr: u32 = args.nth_checked(7)?;
  451. let output_len_ptr: u32 = args.nth_checked(8)?;
  452. let salt_ptr: u32 = args.nth_checked(9)?;
  453. let salt_len: u32 = args.nth_checked(10)?;
  454. let mut codehash = [0u8; 32];
  455. if let Err(e) = self.vm.memory.get_into(codehash_ptr, &mut codehash) {
  456. panic!("seal_instantiate: {e}");
  457. }
  458. let mut value = [0u8; 16];
  459. if let Err(e) = self.vm.memory.get_into(value_ptr, &mut value) {
  460. panic!("seal_instantiate: {e}");
  461. }
  462. let value = u128::from_le_bytes(value);
  463. let mut input = Vec::new();
  464. input.resize(input_len as usize, 0u8);
  465. if let Err(e) = self.vm.memory.get_into(input_ptr, &mut input) {
  466. panic!("seal_instantiate: {e}");
  467. }
  468. let mut salt = Vec::new();
  469. salt.resize(salt_len as usize, 0u8);
  470. if let Err(e) = self.vm.memory.get_into(salt_ptr, &mut salt) {
  471. panic!("seal_instantiate: {e}");
  472. }
  473. println!(
  474. "seal_instantiate value:{} input={} salt={}",
  475. value,
  476. hex::encode(&input),
  477. hex::encode(&salt),
  478. );
  479. let mut account = [0u8; 32];
  480. let hash_data: Vec<u8> = input.iter().chain(salt.iter()).cloned().collect();
  481. account
  482. .copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], &hash_data).as_bytes());
  483. if self.accounts.contains_key(&account) {
  484. // substrate would return TRAP_RETURN_CODE (0x0100)
  485. return Ok(Some(RuntimeValue::I32(0x100)));
  486. }
  487. let program = self
  488. .programs
  489. .iter()
  490. .find(|program| {
  491. blake2_rfc::blake2b::blake2b(32, &[], &program.code).as_bytes() == codehash
  492. })
  493. .expect("codehash not found");
  494. self.accounts.insert(account, (program.code.clone(), 0));
  495. let mut input = Vec::new();
  496. input.resize(input_len as usize, 0u8);
  497. if let Err(e) = self.vm.memory.get_into(input_ptr, &mut input) {
  498. panic!("seal_instantiate: {e}");
  499. }
  500. let mut vm = VirtualMachine::new(account, self.vm.account, value);
  501. std::mem::swap(&mut self.vm, &mut vm);
  502. let module = self.create_module(&program.code);
  503. self.vm.input = input;
  504. let ret = match module.invoke_export("deploy", &[], self) {
  505. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  506. TrapKind::Host(host_error) => {
  507. if let Some(ret) = host_error.downcast_ref::<HostCodeReturn>() {
  508. Some(RuntimeValue::I32(ret.0))
  509. } else {
  510. return Err(trap);
  511. }
  512. }
  513. _ => {
  514. return Err(trap);
  515. }
  516. },
  517. Ok(v) => v,
  518. Err(e) => panic!("fail to invoke deploy: {e}"),
  519. };
  520. let output = self.vm.output.clone();
  521. std::mem::swap(&mut self.vm, &mut vm);
  522. set_seal_value!(
  523. "seal_instantiate output",
  524. output_ptr,
  525. output_len_ptr,
  526. &output
  527. );
  528. if let Some(RuntimeValue::I32(0)) = ret {
  529. self.accounts.get_mut(&vm.account).unwrap().1 += vm.value;
  530. set_seal_value!(
  531. "seal_instantiate account",
  532. account_ptr,
  533. account_len_ptr,
  534. &account
  535. );
  536. }
  537. println!("seal_instantiate ret:{ret:?}");
  538. Ok(ret)
  539. }
  540. Some(SubstrateExternal::seal_value_transferred) => {
  541. let dest_ptr: u32 = args.nth_checked(0)?;
  542. let len_ptr: u32 = args.nth_checked(1)?;
  543. let scratch = self.vm.value.to_le_bytes();
  544. set_seal_value!("seal_value_transferred", dest_ptr, len_ptr, &scratch);
  545. Ok(None)
  546. }
  547. Some(SubstrateExternal::seal_address) => {
  548. let dest_ptr: u32 = args.nth_checked(0)?;
  549. let len_ptr: u32 = args.nth_checked(1)?;
  550. let scratch = self.vm.account;
  551. set_seal_value!("seal_address", dest_ptr, len_ptr, &scratch);
  552. Ok(None)
  553. }
  554. Some(SubstrateExternal::seal_caller) => {
  555. let dest_ptr: u32 = args.nth_checked(0)?;
  556. let len_ptr: u32 = args.nth_checked(1)?;
  557. let scratch = self.vm.caller;
  558. set_seal_value!("seal_caller", dest_ptr, len_ptr, &scratch);
  559. Ok(None)
  560. }
  561. Some(SubstrateExternal::seal_balance) => {
  562. let dest_ptr: u32 = args.nth_checked(0)?;
  563. let len_ptr: u32 = args.nth_checked(1)?;
  564. let scratch = self.accounts[&self.vm.account].1.to_le_bytes();
  565. set_seal_value!("seal_balance", dest_ptr, len_ptr, &scratch);
  566. Ok(None)
  567. }
  568. Some(SubstrateExternal::seal_minimum_balance) => {
  569. let dest_ptr: u32 = args.nth_checked(0)?;
  570. let len_ptr: u32 = args.nth_checked(1)?;
  571. let scratch = 500u128.to_le_bytes();
  572. set_seal_value!("seal_minimum_balance", dest_ptr, len_ptr, &scratch);
  573. Ok(None)
  574. }
  575. Some(SubstrateExternal::seal_block_number) => {
  576. let dest_ptr: u32 = args.nth_checked(0)?;
  577. let len_ptr: u32 = args.nth_checked(1)?;
  578. let scratch = 950_119_597u32.to_le_bytes();
  579. set_seal_value!("seal_block_number", dest_ptr, len_ptr, &scratch);
  580. Ok(None)
  581. }
  582. Some(SubstrateExternal::seal_now) => {
  583. let dest_ptr: u32 = args.nth_checked(0)?;
  584. let len_ptr: u32 = args.nth_checked(1)?;
  585. let scratch = 1594035638000u64.to_le_bytes();
  586. set_seal_value!("seal_now", dest_ptr, len_ptr, &scratch);
  587. Ok(None)
  588. }
  589. Some(SubstrateExternal::seal_gas_left) => {
  590. let dest_ptr: u32 = args.nth_checked(0)?;
  591. let len_ptr: u32 = args.nth_checked(1)?;
  592. let scratch = 2_224_097_461u64.to_le_bytes();
  593. set_seal_value!("seal_gas_left", dest_ptr, len_ptr, &scratch);
  594. Ok(None)
  595. }
  596. Some(SubstrateExternal::seal_weight_to_fee) => {
  597. let units: u64 = args.nth_checked(0)?;
  598. let dest_ptr: u32 = args.nth_checked(1)?;
  599. let len_ptr: u32 = args.nth_checked(2)?;
  600. let scratch = (59_541_253_813_967u128 * units as u128).to_le_bytes();
  601. set_seal_value!("seal_weight_to_fee", dest_ptr, len_ptr, &scratch);
  602. Ok(None)
  603. }
  604. Some(SubstrateExternal::seal_terminate) => {
  605. let account_ptr: u32 = args.nth_checked(0)?;
  606. let mut account = [0u8; 32];
  607. if let Err(e) = self.vm.memory.get_into(account_ptr, &mut account) {
  608. panic!("seal_terminate: {e}");
  609. }
  610. let remaining = self.accounts[&self.vm.account].1;
  611. self.accounts.get_mut(&account).unwrap().1 += remaining;
  612. println!("seal_terminate: {} {}", hex::encode(account), remaining);
  613. self.accounts.remove(&self.vm.account);
  614. Err(Trap::new(TrapKind::Host(Box::new(HostCodeTerminate {}))))
  615. }
  616. Some(SubstrateExternal::seal_deposit_event) => {
  617. let mut topic_ptr: u32 = args.nth_checked(0)?;
  618. let topic_len: u32 = args.nth_checked(1)?;
  619. let data_ptr: u32 = args.nth_checked(2)?;
  620. let data_len: u32 = args.nth_checked(3)?;
  621. let mut topics = Vec::new();
  622. if topic_len != 0 {
  623. assert_eq!(topic_len % 32, 1);
  624. assert_eq!((topic_len - 1) % 32, 0);
  625. let mut vec_length = [0u8];
  626. if let Err(e) = self.vm.memory.get_into(topic_ptr, &mut vec_length) {
  627. panic!("seal_deposit_event: topic: {e}");
  628. }
  629. println!("topic_len: {} first byte: {}", topic_len, vec_length[0]);
  630. assert_eq!(vec_length[0] as u32, (topic_len - 1) / 8);
  631. topic_ptr += 1;
  632. }
  633. for _ in 0..topic_len / 32 {
  634. let mut topic = [0u8; 32];
  635. if let Err(e) = self.vm.memory.get_into(topic_ptr, &mut topic) {
  636. panic!("seal_deposit_event: topic: {e}");
  637. }
  638. topics.push(topic);
  639. topic_ptr += 32;
  640. }
  641. let mut data = Vec::new();
  642. data.resize(data_len as usize, 0);
  643. if let Err(e) = self.vm.memory.get_into(data_ptr, &mut data) {
  644. panic!("seal_deposit_event: data: {e}");
  645. }
  646. println!(
  647. "seal_deposit_event: topic: {} data: {}",
  648. topics
  649. .iter()
  650. .map(hex::encode)
  651. .collect::<Vec<String>>()
  652. .join(" "),
  653. hex::encode(&data)
  654. );
  655. self.events.push(Event { topics, data });
  656. Ok(None)
  657. }
  658. _ => panic!("external {index} unknown"),
  659. }
  660. }
  661. }
  662. impl ModuleImportResolver for MockSubstrate {
  663. fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> {
  664. let index = match field_name {
  665. "seal_input" => SubstrateExternal::seal_input,
  666. "seal_get_storage" => SubstrateExternal::seal_get_storage,
  667. "seal_set_storage" => SubstrateExternal::seal_set_storage,
  668. "seal_clear_storage" => SubstrateExternal::seal_clear_storage,
  669. "seal_return" => SubstrateExternal::seal_return,
  670. "seal_hash_sha2_256" => SubstrateExternal::seal_hash_sha2_256,
  671. "seal_hash_keccak_256" => SubstrateExternal::seal_hash_keccak_256,
  672. "seal_hash_blake2_128" => SubstrateExternal::seal_hash_blake2_128,
  673. "seal_hash_blake2_256" => SubstrateExternal::seal_hash_blake2_256,
  674. "seal_debug_message" => SubstrateExternal::seal_debug_message,
  675. "seal_call" => SubstrateExternal::seal_call,
  676. "seal_instantiate" => SubstrateExternal::seal_instantiate,
  677. "seal_value_transferred" => SubstrateExternal::seal_value_transferred,
  678. "seal_minimum_balance" => SubstrateExternal::seal_minimum_balance,
  679. "instantiation_nonce" => SubstrateExternal::instantiation_nonce,
  680. "seal_address" => SubstrateExternal::seal_address,
  681. "seal_balance" => SubstrateExternal::seal_balance,
  682. "seal_terminate" => SubstrateExternal::seal_terminate,
  683. "seal_block_number" => SubstrateExternal::seal_block_number,
  684. "seal_now" => SubstrateExternal::seal_now,
  685. "seal_weight_to_fee" => SubstrateExternal::seal_weight_to_fee,
  686. "seal_gas_left" => SubstrateExternal::seal_gas_left,
  687. "seal_caller" => SubstrateExternal::seal_caller,
  688. "seal_deposit_event" => SubstrateExternal::seal_deposit_event,
  689. "seal_transfer" => SubstrateExternal::seal_transfer,
  690. _ => {
  691. panic!("{field_name} not implemented");
  692. }
  693. };
  694. Ok(FuncInstance::alloc_host(signature.clone(), index as usize))
  695. }
  696. fn resolve_memory(
  697. &self,
  698. _field_name: &str,
  699. _memory_type: &MemoryDescriptor,
  700. ) -> Result<MemoryRef, Error> {
  701. Ok(self.vm.memory.clone())
  702. }
  703. }
  704. impl MockSubstrate {
  705. fn create_module(&self, code: &[u8]) -> ModuleRef {
  706. let module = Module::from_buffer(code).expect("parse wasm should work");
  707. ModuleInstance::new(
  708. &module,
  709. &ImportsBuilder::new()
  710. .with_resolver("env", self)
  711. .with_resolver("seal0", self)
  712. .with_resolver("seal1", self)
  713. .with_resolver("seal2", self),
  714. )
  715. .expect("Failed to instantiate module")
  716. .run_start(&mut NopExternals)
  717. .expect("Failed to run start function in module")
  718. }
  719. fn invoke_deploy(&mut self, module: ModuleRef) -> Option<RuntimeValue> {
  720. match module.invoke_export("deploy", &[], self) {
  721. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  722. TrapKind::Host(host_error) => {
  723. if let Some(ret) = host_error.downcast_ref::<HostCodeReturn>() {
  724. Some(RuntimeValue::I32(ret.0))
  725. } else {
  726. panic!("did not go as planned");
  727. }
  728. }
  729. _ => panic!("fail to invoke deploy: {trap}"),
  730. },
  731. Ok(v) => v,
  732. Err(e) => panic!("fail to invoke deploy: {e}"),
  733. }
  734. }
  735. fn invoke_call(&mut self, module: ModuleRef) -> Option<RuntimeValue> {
  736. match module.invoke_export("call", &[], self) {
  737. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  738. TrapKind::Host(host_error) => {
  739. if let Some(ret) = host_error.downcast_ref::<HostCodeReturn>() {
  740. Some(RuntimeValue::I32(ret.0))
  741. } else if host_error.downcast_ref::<HostCodeTerminate>().is_some() {
  742. Some(RuntimeValue::I32(1))
  743. } else {
  744. panic!("did not go as planned");
  745. }
  746. }
  747. _ => panic!("fail to invoke call: {trap}"),
  748. },
  749. Ok(v) => v,
  750. Err(e) => panic!("fail to invoke call: {e}"),
  751. }
  752. }
  753. pub fn set_program(&mut self, index: usize) {
  754. let account = account_new();
  755. let code = self.programs[index].code.clone();
  756. self.accounts.insert(account, (code, 0));
  757. self.vm = VirtualMachine::new(account, account_new(), 0);
  758. self.current_program = index;
  759. }
  760. pub fn constructor(&mut self, index: usize, args: Vec<u8>) {
  761. let m = &self.programs[self.current_program]
  762. .abi
  763. .spec()
  764. .constructors()[index];
  765. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  766. self.vm.input = m
  767. .selector()
  768. .to_bytes()
  769. .iter()
  770. .copied()
  771. .chain(args)
  772. .collect();
  773. let ret = self.invoke_deploy(module);
  774. if let Some(RuntimeValue::I32(ret)) = ret {
  775. if ret != 0 {
  776. panic!("non zero return")
  777. }
  778. }
  779. }
  780. pub fn constructor_expect_return(&mut self, index: usize, expected_ret: i32, args: Vec<u8>) {
  781. let m = &self.programs[self.current_program]
  782. .abi
  783. .spec()
  784. .constructors()[index];
  785. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  786. self.vm.input = m
  787. .selector()
  788. .to_bytes()
  789. .iter()
  790. .copied()
  791. .chain(args)
  792. .collect();
  793. let ret = self.invoke_deploy(module);
  794. if let Some(RuntimeValue::I32(ret)) = ret {
  795. println!("function_expected_return: got {ret} expected {expected_ret}");
  796. if expected_ret != ret {
  797. panic!("non one return")
  798. }
  799. }
  800. }
  801. pub fn function(&mut self, name: &str, args: Vec<u8>) {
  802. let m = self.programs[self.current_program]
  803. .abi
  804. .spec()
  805. .messages()
  806. .iter()
  807. .find(|f| f.label() == name)
  808. .unwrap();
  809. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  810. self.vm.input = m
  811. .selector()
  812. .to_bytes()
  813. .iter()
  814. .copied()
  815. .chain(args)
  816. .collect();
  817. println!("input:{}", hex::encode(&self.vm.input));
  818. if let Some(RuntimeValue::I32(ret)) = self.invoke_call(module) {
  819. assert!(ret == 0, "non zero return: {ret}");
  820. }
  821. }
  822. pub fn function_expect_failure(&mut self, name: &str, args: Vec<u8>) {
  823. let m = self.programs[self.current_program]
  824. .abi
  825. .spec()
  826. .messages()
  827. .iter()
  828. .find(|m| m.label() == name)
  829. .unwrap();
  830. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  831. self.vm.input = m
  832. .selector()
  833. .to_bytes()
  834. .iter()
  835. .copied()
  836. .chain(args)
  837. .collect();
  838. match module.invoke_export("call", &[], self) {
  839. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  840. TrapKind::Unreachable => (),
  841. _ => panic!("trap: {trap:?}"),
  842. },
  843. Err(err) => {
  844. panic!("unexpected error: {err:?}");
  845. }
  846. Ok(v) => {
  847. panic!("unexpected return value: {v:?}");
  848. }
  849. }
  850. }
  851. pub fn raw_function(&mut self, input: Vec<u8>) {
  852. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  853. self.vm.input = input;
  854. if let Some(RuntimeValue::I32(ret)) = self.invoke_call(module) {
  855. if ret != 0 {
  856. panic!("non zero return")
  857. }
  858. }
  859. }
  860. pub fn raw_function_failure(&mut self, input: Vec<u8>) {
  861. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  862. self.vm.input = input;
  863. match module.invoke_export("call", &[], self) {
  864. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  865. TrapKind::Unreachable => (),
  866. _ => panic!("trap: {trap:?}"),
  867. },
  868. Err(err) => {
  869. panic!("unexpected error: {err:?}");
  870. }
  871. Ok(v) => {
  872. panic!("unexpected return value: {v:?}");
  873. }
  874. }
  875. }
  876. pub fn raw_constructor(&mut self, input: Vec<u8>) {
  877. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  878. self.vm.input = input;
  879. if let Some(RuntimeValue::I32(ret)) = self.invoke_deploy(module) {
  880. if ret != 0 {
  881. panic!("non zero return")
  882. }
  883. }
  884. }
  885. pub fn heap_verify(&self) {
  886. let memsize = self.vm.memory.current_size().0 * 0x10000;
  887. println!("memory size:{memsize}");
  888. let mut buf = Vec::new();
  889. buf.resize(memsize, 0);
  890. let mut current_elem = 0x10000;
  891. let mut last_elem = 0u32;
  892. loop {
  893. let next: u32 = self.vm.memory.get_value(current_elem).unwrap();
  894. let prev: u32 = self.vm.memory.get_value(current_elem + 4).unwrap();
  895. let length: u32 = self.vm.memory.get_value(current_elem + 8).unwrap();
  896. let allocated: u32 = self.vm.memory.get_value(current_elem + 12).unwrap();
  897. println!("next:{next:08x} prev:{prev:08x} length:{length} allocated:{allocated}");
  898. let mut buf = vec![0u8; length as usize];
  899. self.vm
  900. .memory
  901. .get_into(current_elem + 16, &mut buf)
  902. .unwrap();
  903. if allocated == 0 {
  904. println!("{:08x} {} not allocated", current_elem + 16, length);
  905. } else {
  906. println!("{:08x} {} allocated", current_elem + 16, length);
  907. assert_eq!(allocated & 0xffff, 1);
  908. for offset in (0..buf.len()).step_by(16) {
  909. let mut hex = "\t".to_string();
  910. let mut chars = "\t".to_string();
  911. for i in 0..16 {
  912. if offset + i >= buf.len() {
  913. break;
  914. }
  915. let b = buf[offset + i];
  916. write!(hex, " {b:02x}").unwrap();
  917. if b.is_ascii() && !b.is_ascii_control() {
  918. write!(chars, " {}", b as char).unwrap();
  919. } else {
  920. chars.push_str(" ");
  921. }
  922. }
  923. println!("{hex}\n{chars}");
  924. }
  925. }
  926. assert_eq!(last_elem, prev);
  927. if next == 0 {
  928. break;
  929. }
  930. last_elem = current_elem;
  931. current_elem = next;
  932. }
  933. }
  934. }
  935. pub fn build_solidity(src: &str) -> MockSubstrate {
  936. build_solidity_with_options(src, false, true)
  937. }
  938. pub fn build_solidity_with_options(
  939. src: &str,
  940. log_api_return_codes: bool,
  941. log_runtime_errors: bool,
  942. ) -> MockSubstrate {
  943. let mut cache = FileResolver::new();
  944. cache.set_file_contents("test.sol", src.to_string());
  945. let (res, ns) = compile(
  946. OsStr::new("test.sol"),
  947. &mut cache,
  948. inkwell::OptimizationLevel::Default,
  949. Target::default_substrate(),
  950. log_api_return_codes,
  951. log_runtime_errors,
  952. );
  953. ns.print_diagnostics_in_plain(&cache, false);
  954. assert!(!res.is_empty());
  955. let programs: Vec<Program> = res
  956. .iter()
  957. .map(|res| Program {
  958. code: res.0.clone(),
  959. abi: load_abi(&res.1),
  960. })
  961. .collect();
  962. let mut accounts = HashMap::new();
  963. let account = account_new();
  964. accounts.insert(account, (programs[0].code.clone(), 0));
  965. let vm = VirtualMachine::new(account, account_new(), 0);
  966. MockSubstrate {
  967. accounts,
  968. printbuf: String::new(),
  969. store: HashMap::new(),
  970. programs,
  971. vm,
  972. current_program: 0,
  973. events: Vec::new(),
  974. }
  975. }
  976. fn load_abi(s: &str) -> InkProject {
  977. let bundle = serde_json::from_str::<ContractMetadata>(s).unwrap();
  978. serde_json::from_value::<InkProject>(serde_json::to_value(bundle.abi).unwrap()).unwrap()
  979. }