substrate.rs 42 KB

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