substrate.rs 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282
  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. seal_random,
  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: {:?} = nil", key);
  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 {} not valid", flags),
  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::seal_random) => {
  350. let data_ptr: u32 = args.nth_checked(0)?;
  351. let len: u32 = args.nth_checked(1)?;
  352. let dest_ptr: u32 = args.nth_checked(2)?;
  353. let len_ptr: u32 = args.nth_checked(3)?;
  354. let mut buf = Vec::new();
  355. buf.resize(len as usize, 0u8);
  356. if let Err(e) = self.vm.memory.get_into(data_ptr, &mut buf) {
  357. panic!("seal_random: {}", e);
  358. }
  359. let mut hash = [0u8; 32];
  360. hash.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], &buf).as_bytes());
  361. println!("seal_random: {} {}", hex::encode(buf), hex::encode(hash));
  362. let len = self
  363. .vm
  364. .memory
  365. .get_value::<u32>(len_ptr)
  366. .expect("seal_random len_ptr should be valid");
  367. assert!(
  368. (len as usize) >= hash.len(),
  369. "seal_random dest buffer is too small"
  370. );
  371. if let Err(e) = self.vm.memory.set(dest_ptr, &hash) {
  372. panic!("seal_random: {}", e);
  373. }
  374. self.vm
  375. .memory
  376. .set_value(len_ptr, hash.len() as u32)
  377. .expect("seal_random len_ptr should be valid");
  378. Ok(None)
  379. }
  380. Some(SubstrateExternal::seal_call) => {
  381. let flags: u32 = args.nth_checked(0)?;
  382. let account_ptr: u32 = args.nth_checked(1)?;
  383. // Gas usage is ignored in the mock VM
  384. let value_ptr: u32 = args.nth_checked(3)?;
  385. let input_ptr: u32 = args.nth_checked(4)?;
  386. let input_len: u32 = args.nth_checked(5)?;
  387. let output_ptr: u32 = args.nth_checked(6)?;
  388. let output_len_ptr: u32 = args.nth_checked(7)?;
  389. assert_eq!(flags, 0); //TODO: Call flags are not yet implemented
  390. let mut account = [0u8; 32];
  391. if let Err(e) = self.vm.memory.get_into(account_ptr, &mut account) {
  392. panic!("seal_call: {}", e);
  393. }
  394. let mut value = [0u8; 16];
  395. if let Err(e) = self.vm.memory.get_into(value_ptr, &mut value) {
  396. panic!("seal_call: {}", e);
  397. }
  398. let value = u128::from_le_bytes(value);
  399. if !self.accounts.contains_key(&account) {
  400. // substrate would return NotCallable
  401. return Ok(Some(RuntimeValue::I32(0x8)));
  402. }
  403. let mut input = Vec::new();
  404. input.resize(input_len as usize, 0u8);
  405. if let Err(e) = self.vm.memory.get_into(input_ptr, &mut input) {
  406. panic!("seal_call: {}", e);
  407. }
  408. println!(
  409. "seal_call: account={} input={}",
  410. hex::encode(account),
  411. hex::encode(&input)
  412. );
  413. let mut vm = VirtualMachine::new(account, self.vm.account, value);
  414. std::mem::swap(&mut self.vm, &mut vm);
  415. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  416. self.vm.input = input;
  417. let ret = module.invoke_export("call", &[], self);
  418. let ret = match ret {
  419. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  420. TrapKind::Host(host_error) => {
  421. if let Some(ret) = host_error.downcast_ref::<HostCodeReturn>() {
  422. Some(RuntimeValue::I32(ret.0))
  423. } else if host_error.downcast_ref::<HostCodeTerminate>().is_some() {
  424. Some(RuntimeValue::I32(1))
  425. } else {
  426. return Err(trap);
  427. }
  428. }
  429. _ => {
  430. return Err(trap);
  431. }
  432. },
  433. Ok(v) => v,
  434. Err(e) => panic!("fail to invoke call: {}", e),
  435. };
  436. let output = self.vm.output.clone();
  437. std::mem::swap(&mut self.vm, &mut vm);
  438. println!("seal_call ret={:?} buf={}", ret, hex::encode(&output));
  439. if let Some(acc) = self.accounts.get_mut(&vm.account) {
  440. acc.1 += vm.value;
  441. }
  442. set_seal_value!("seal_call return buf", output_ptr, output_len_ptr, &output);
  443. Ok(ret)
  444. }
  445. Some(SubstrateExternal::seal_transfer) => {
  446. let account_ptr: u32 = args.nth_checked(0)?;
  447. let account_len: u32 = args.nth_checked(1)?;
  448. let value_ptr: u32 = args.nth_checked(2)?;
  449. let value_len: u32 = args.nth_checked(3)?;
  450. let mut account = [0u8; 32];
  451. assert!(account_len == 32, "seal_transfer: len = {}", account_len);
  452. if let Err(e) = self.vm.memory.get_into(account_ptr, &mut account) {
  453. panic!("seal_transfer: {}", e);
  454. }
  455. let mut value = [0u8; 16];
  456. assert!(value_len == 16, "seal_transfer: len = {}", value_len);
  457. if let Err(e) = self.vm.memory.get_into(value_ptr, &mut value) {
  458. panic!("seal_transfer: {}", e);
  459. }
  460. let value = u128::from_le_bytes(value);
  461. if !self.accounts.contains_key(&account) {
  462. // substrate would return TransferFailed
  463. return Ok(Some(RuntimeValue::I32(0x5)));
  464. }
  465. if let Some(acc) = self.accounts.get_mut(&account) {
  466. acc.1 += value;
  467. }
  468. Ok(Some(RuntimeValue::I32(0)))
  469. }
  470. Some(SubstrateExternal::seal_instantiate) => {
  471. let codehash_ptr: u32 = args.nth_checked(0)?;
  472. // Gas usage is ignored in the mock VM
  473. let value_ptr: u32 = args.nth_checked(2)?;
  474. let input_ptr: u32 = args.nth_checked(3)?;
  475. let input_len: u32 = args.nth_checked(4)?;
  476. let account_ptr: u32 = args.nth_checked(5)?;
  477. let account_len_ptr: u32 = args.nth_checked(6)?;
  478. let output_ptr: u32 = args.nth_checked(7)?;
  479. let output_len_ptr: u32 = args.nth_checked(8)?;
  480. let salt_ptr: u32 = args.nth_checked(9)?;
  481. let salt_len: u32 = args.nth_checked(10)?;
  482. let mut codehash = [0u8; 32];
  483. if let Err(e) = self.vm.memory.get_into(codehash_ptr, &mut codehash) {
  484. panic!("seal_instantiate: {}", e);
  485. }
  486. let mut value = [0u8; 16];
  487. if let Err(e) = self.vm.memory.get_into(value_ptr, &mut value) {
  488. panic!("seal_instantiate: {}", e);
  489. }
  490. let value = u128::from_le_bytes(value);
  491. let mut input = Vec::new();
  492. input.resize(input_len as usize, 0u8);
  493. if let Err(e) = self.vm.memory.get_into(input_ptr, &mut input) {
  494. panic!("seal_instantiate: {}", e);
  495. }
  496. let mut salt = Vec::new();
  497. salt.resize(salt_len as usize, 0u8);
  498. if let Err(e) = self.vm.memory.get_into(salt_ptr, &mut salt) {
  499. panic!("seal_instantiate: {}", e);
  500. }
  501. println!(
  502. "seal_instantiate value:{} input={} salt={}",
  503. value,
  504. hex::encode(&input),
  505. hex::encode(&salt),
  506. );
  507. let mut account = [0u8; 32];
  508. let hash_data: Vec<u8> = input.iter().chain(salt.iter()).cloned().collect();
  509. account
  510. .copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], &hash_data).as_bytes());
  511. if self.accounts.contains_key(&account) {
  512. // substrate would return TRAP_RETURN_CODE (0x0100)
  513. return Ok(Some(RuntimeValue::I32(0x100)));
  514. }
  515. let program = self
  516. .programs
  517. .iter()
  518. .find(|program| {
  519. blake2_rfc::blake2b::blake2b(32, &[], &program.code).as_bytes() == codehash
  520. })
  521. .expect("codehash not found");
  522. self.accounts.insert(account, (program.code.clone(), 0));
  523. let mut input = Vec::new();
  524. input.resize(input_len as usize, 0u8);
  525. if let Err(e) = self.vm.memory.get_into(input_ptr, &mut input) {
  526. panic!("seal_instantiate: {}", e);
  527. }
  528. let mut vm = VirtualMachine::new(account, self.vm.account, value);
  529. std::mem::swap(&mut self.vm, &mut vm);
  530. let module = self.create_module(&program.code);
  531. self.vm.input = input;
  532. let ret = match module.invoke_export("deploy", &[], self) {
  533. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  534. TrapKind::Host(host_error) => {
  535. if let Some(ret) = host_error.downcast_ref::<HostCodeReturn>() {
  536. Some(RuntimeValue::I32(ret.0))
  537. } else {
  538. return Err(trap);
  539. }
  540. }
  541. _ => {
  542. return Err(trap);
  543. }
  544. },
  545. Ok(v) => v,
  546. Err(e) => panic!("fail to invoke deploy: {}", e),
  547. };
  548. let output = self.vm.output.clone();
  549. std::mem::swap(&mut self.vm, &mut vm);
  550. set_seal_value!(
  551. "seal_instantiate output",
  552. output_ptr,
  553. output_len_ptr,
  554. &output
  555. );
  556. if let Some(RuntimeValue::I32(0)) = ret {
  557. self.accounts.get_mut(&vm.account).unwrap().1 += vm.value;
  558. set_seal_value!(
  559. "seal_instantiate account",
  560. account_ptr,
  561. account_len_ptr,
  562. &account
  563. );
  564. }
  565. println!("seal_instantiate ret:{:?}", ret);
  566. Ok(ret)
  567. }
  568. Some(SubstrateExternal::seal_value_transferred) => {
  569. let dest_ptr: u32 = args.nth_checked(0)?;
  570. let len_ptr: u32 = args.nth_checked(1)?;
  571. let scratch = self.vm.value.to_le_bytes();
  572. set_seal_value!("seal_value_transferred", dest_ptr, len_ptr, &scratch);
  573. Ok(None)
  574. }
  575. Some(SubstrateExternal::seal_address) => {
  576. let dest_ptr: u32 = args.nth_checked(0)?;
  577. let len_ptr: u32 = args.nth_checked(1)?;
  578. let scratch = self.vm.account;
  579. set_seal_value!("seal_address", dest_ptr, len_ptr, &scratch);
  580. Ok(None)
  581. }
  582. Some(SubstrateExternal::seal_caller) => {
  583. let dest_ptr: u32 = args.nth_checked(0)?;
  584. let len_ptr: u32 = args.nth_checked(1)?;
  585. let scratch = self.vm.caller;
  586. set_seal_value!("seal_caller", dest_ptr, len_ptr, &scratch);
  587. Ok(None)
  588. }
  589. Some(SubstrateExternal::seal_balance) => {
  590. let dest_ptr: u32 = args.nth_checked(0)?;
  591. let len_ptr: u32 = args.nth_checked(1)?;
  592. let scratch = self.accounts[&self.vm.account].1.to_le_bytes();
  593. set_seal_value!("seal_balance", dest_ptr, len_ptr, &scratch);
  594. Ok(None)
  595. }
  596. Some(SubstrateExternal::seal_minimum_balance) => {
  597. let dest_ptr: u32 = args.nth_checked(0)?;
  598. let len_ptr: u32 = args.nth_checked(1)?;
  599. let scratch = 500u128.to_le_bytes();
  600. set_seal_value!("seal_minimum_balance", dest_ptr, len_ptr, &scratch);
  601. Ok(None)
  602. }
  603. Some(SubstrateExternal::seal_block_number) => {
  604. let dest_ptr: u32 = args.nth_checked(0)?;
  605. let len_ptr: u32 = args.nth_checked(1)?;
  606. let scratch = 950_119_597u32.to_le_bytes();
  607. set_seal_value!("seal_block_number", dest_ptr, len_ptr, &scratch);
  608. Ok(None)
  609. }
  610. Some(SubstrateExternal::seal_now) => {
  611. let dest_ptr: u32 = args.nth_checked(0)?;
  612. let len_ptr: u32 = args.nth_checked(1)?;
  613. let scratch = 1594035638000u64.to_le_bytes();
  614. set_seal_value!("seal_now", dest_ptr, len_ptr, &scratch);
  615. Ok(None)
  616. }
  617. Some(SubstrateExternal::seal_gas_left) => {
  618. let dest_ptr: u32 = args.nth_checked(0)?;
  619. let len_ptr: u32 = args.nth_checked(1)?;
  620. let scratch = 2_224_097_461u64.to_le_bytes();
  621. set_seal_value!("seal_gas_left", dest_ptr, len_ptr, &scratch);
  622. Ok(None)
  623. }
  624. Some(SubstrateExternal::seal_weight_to_fee) => {
  625. let units: u64 = args.nth_checked(0)?;
  626. let dest_ptr: u32 = args.nth_checked(1)?;
  627. let len_ptr: u32 = args.nth_checked(2)?;
  628. let scratch = (59_541_253_813_967u128 * units as u128).to_le_bytes();
  629. set_seal_value!("seal_weight_to_fee", dest_ptr, len_ptr, &scratch);
  630. Ok(None)
  631. }
  632. Some(SubstrateExternal::seal_terminate) => {
  633. let account_ptr: u32 = args.nth_checked(0)?;
  634. let mut account = [0u8; 32];
  635. if let Err(e) = self.vm.memory.get_into(account_ptr, &mut account) {
  636. panic!("seal_terminate: {}", e);
  637. }
  638. let remaining = self.accounts[&self.vm.account].1;
  639. self.accounts.get_mut(&account).unwrap().1 += remaining;
  640. println!("seal_terminate: {} {}", hex::encode(account), remaining);
  641. self.accounts.remove(&self.vm.account);
  642. Err(Trap::new(TrapKind::Host(Box::new(HostCodeTerminate {}))))
  643. }
  644. Some(SubstrateExternal::seal_deposit_event) => {
  645. let mut topic_ptr: u32 = args.nth_checked(0)?;
  646. let topic_len: u32 = args.nth_checked(1)?;
  647. let data_ptr: u32 = args.nth_checked(2)?;
  648. let data_len: u32 = args.nth_checked(3)?;
  649. let mut topics = Vec::new();
  650. if topic_len != 0 {
  651. assert_eq!(topic_len % 32, 1);
  652. assert_eq!((topic_len - 1) % 32, 0);
  653. let mut vec_length = [0u8];
  654. if let Err(e) = self.vm.memory.get_into(topic_ptr, &mut vec_length) {
  655. panic!("seal_deposit_event: topic: {}", e);
  656. }
  657. println!("topic_len: {} first byte: {}", topic_len, vec_length[0]);
  658. assert_eq!(vec_length[0] as u32, (topic_len - 1) / 8);
  659. topic_ptr += 1;
  660. }
  661. for _ in 0..topic_len / 32 {
  662. let mut topic = [0u8; 32];
  663. if let Err(e) = self.vm.memory.get_into(topic_ptr, &mut topic) {
  664. panic!("seal_deposit_event: topic: {}", e);
  665. }
  666. topics.push(topic);
  667. topic_ptr += 32;
  668. }
  669. let mut data = Vec::new();
  670. data.resize(data_len as usize, 0);
  671. if let Err(e) = self.vm.memory.get_into(data_ptr, &mut data) {
  672. panic!("seal_deposit_event: data: {}", e);
  673. }
  674. println!(
  675. "seal_deposit_event: topic: {} data: {}",
  676. topics
  677. .iter()
  678. .map(hex::encode)
  679. .collect::<Vec<String>>()
  680. .join(" "),
  681. hex::encode(&data)
  682. );
  683. self.events.push(Event { topics, data });
  684. Ok(None)
  685. }
  686. _ => panic!("external {} unknown", index),
  687. }
  688. }
  689. }
  690. impl ModuleImportResolver for MockSubstrate {
  691. fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> {
  692. let index = match field_name {
  693. "seal_input" => SubstrateExternal::seal_input,
  694. "seal_get_storage" => SubstrateExternal::seal_get_storage,
  695. "seal_set_storage" => SubstrateExternal::seal_set_storage,
  696. "seal_clear_storage" => SubstrateExternal::seal_clear_storage,
  697. "seal_return" => SubstrateExternal::seal_return,
  698. "seal_hash_sha2_256" => SubstrateExternal::seal_hash_sha2_256,
  699. "seal_hash_keccak_256" => SubstrateExternal::seal_hash_keccak_256,
  700. "seal_hash_blake2_128" => SubstrateExternal::seal_hash_blake2_128,
  701. "seal_hash_blake2_256" => SubstrateExternal::seal_hash_blake2_256,
  702. "seal_debug_message" => SubstrateExternal::seal_debug_message,
  703. "seal_call" => SubstrateExternal::seal_call,
  704. "seal_instantiate" => SubstrateExternal::seal_instantiate,
  705. "seal_value_transferred" => SubstrateExternal::seal_value_transferred,
  706. "seal_minimum_balance" => SubstrateExternal::seal_minimum_balance,
  707. "seal_random" => SubstrateExternal::seal_random,
  708. "seal_address" => SubstrateExternal::seal_address,
  709. "seal_balance" => SubstrateExternal::seal_balance,
  710. "seal_terminate" => SubstrateExternal::seal_terminate,
  711. "seal_block_number" => SubstrateExternal::seal_block_number,
  712. "seal_now" => SubstrateExternal::seal_now,
  713. "seal_weight_to_fee" => SubstrateExternal::seal_weight_to_fee,
  714. "seal_gas_left" => SubstrateExternal::seal_gas_left,
  715. "seal_caller" => SubstrateExternal::seal_caller,
  716. "seal_deposit_event" => SubstrateExternal::seal_deposit_event,
  717. "seal_transfer" => SubstrateExternal::seal_transfer,
  718. _ => {
  719. panic!("{} not implemented", field_name);
  720. }
  721. };
  722. Ok(FuncInstance::alloc_host(signature.clone(), index as usize))
  723. }
  724. fn resolve_memory(
  725. &self,
  726. _field_name: &str,
  727. _memory_type: &MemoryDescriptor,
  728. ) -> Result<MemoryRef, Error> {
  729. Ok(self.vm.memory.clone())
  730. }
  731. }
  732. impl MockSubstrate {
  733. fn create_module(&self, code: &[u8]) -> ModuleRef {
  734. let module = Module::from_buffer(code).expect("parse wasm should work");
  735. ModuleInstance::new(
  736. &module,
  737. &ImportsBuilder::new()
  738. .with_resolver("env", self)
  739. .with_resolver("seal0", self)
  740. .with_resolver("seal1", self)
  741. .with_resolver("seal2", self),
  742. )
  743. .expect("Failed to instantiate module")
  744. .run_start(&mut NopExternals)
  745. .expect("Failed to run start function in module")
  746. }
  747. fn invoke_deploy(&mut self, module: ModuleRef) -> Option<RuntimeValue> {
  748. match module.invoke_export("deploy", &[], self) {
  749. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  750. TrapKind::Host(host_error) => {
  751. if let Some(ret) = host_error.downcast_ref::<HostCodeReturn>() {
  752. Some(RuntimeValue::I32(ret.0))
  753. } else {
  754. panic!("did not go as planned");
  755. }
  756. }
  757. _ => panic!("fail to invoke deploy: {}", trap),
  758. },
  759. Ok(v) => v,
  760. Err(e) => panic!("fail to invoke deploy: {}", e),
  761. }
  762. }
  763. fn invoke_call(&mut self, module: ModuleRef) -> Option<RuntimeValue> {
  764. match module.invoke_export("call", &[], self) {
  765. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  766. TrapKind::Host(host_error) => {
  767. if let Some(ret) = host_error.downcast_ref::<HostCodeReturn>() {
  768. Some(RuntimeValue::I32(ret.0))
  769. } else if host_error.downcast_ref::<HostCodeTerminate>().is_some() {
  770. Some(RuntimeValue::I32(1))
  771. } else {
  772. panic!("did not go as planned");
  773. }
  774. }
  775. _ => panic!("fail to invoke call: {}", trap),
  776. },
  777. Ok(v) => v,
  778. Err(e) => panic!("fail to invoke call: {}", e),
  779. }
  780. }
  781. pub fn set_program(&mut self, index: usize) {
  782. let account = account_new();
  783. let code = self.programs[index].code.clone();
  784. self.accounts.insert(account, (code, 0));
  785. self.vm = VirtualMachine::new(account, account_new(), 0);
  786. self.current_program = index;
  787. }
  788. pub fn constructor(&mut self, index: usize, args: Vec<u8>) {
  789. let m = &self.programs[self.current_program]
  790. .abi
  791. .spec()
  792. .constructors()[index];
  793. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  794. self.vm.input = m
  795. .selector()
  796. .to_bytes()
  797. .iter()
  798. .copied()
  799. .chain(args)
  800. .collect();
  801. let ret = self.invoke_deploy(module);
  802. if let Some(RuntimeValue::I32(ret)) = ret {
  803. if ret != 0 {
  804. panic!("non zero return")
  805. }
  806. }
  807. }
  808. pub fn constructor_expect_return(&mut self, index: usize, expected_ret: i32, args: Vec<u8>) {
  809. let m = &self.programs[self.current_program]
  810. .abi
  811. .spec()
  812. .constructors()[index];
  813. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  814. self.vm.input = m
  815. .selector()
  816. .to_bytes()
  817. .iter()
  818. .copied()
  819. .chain(args)
  820. .collect();
  821. let ret = self.invoke_deploy(module);
  822. if let Some(RuntimeValue::I32(ret)) = ret {
  823. println!(
  824. "function_expected_return: got {} expected {}",
  825. ret, expected_ret
  826. );
  827. if expected_ret != ret {
  828. panic!("non one return")
  829. }
  830. }
  831. }
  832. pub fn function(&mut self, name: &str, args: Vec<u8>) {
  833. let m = self.programs[self.current_program]
  834. .abi
  835. .spec()
  836. .messages()
  837. .iter()
  838. .find(|f| f.label() == name)
  839. .unwrap();
  840. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  841. self.vm.input = m
  842. .selector()
  843. .to_bytes()
  844. .iter()
  845. .copied()
  846. .chain(args)
  847. .collect();
  848. println!("input:{}", hex::encode(&self.vm.input));
  849. if let Some(RuntimeValue::I32(ret)) = self.invoke_call(module) {
  850. assert!(ret == 0, "non zero return: {}", ret);
  851. }
  852. }
  853. pub fn function_expect_failure(&mut self, name: &str, args: Vec<u8>) {
  854. let m = self.programs[self.current_program]
  855. .abi
  856. .spec()
  857. .messages()
  858. .iter()
  859. .find(|m| m.label() == name)
  860. .unwrap();
  861. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  862. self.vm.input = m
  863. .selector()
  864. .to_bytes()
  865. .iter()
  866. .copied()
  867. .chain(args)
  868. .collect();
  869. match module.invoke_export("call", &[], self) {
  870. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  871. TrapKind::Unreachable => (),
  872. _ => panic!("trap: {:?}", trap),
  873. },
  874. Err(err) => {
  875. panic!("unexpected error: {:?}", err);
  876. }
  877. Ok(v) => {
  878. panic!("unexpected return value: {:?}", v);
  879. }
  880. }
  881. }
  882. pub fn raw_function(&mut self, input: Vec<u8>) {
  883. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  884. self.vm.input = input;
  885. if let Some(RuntimeValue::I32(ret)) = self.invoke_call(module) {
  886. if ret != 0 {
  887. panic!("non zero return")
  888. }
  889. }
  890. }
  891. pub fn raw_function_failure(&mut self, input: Vec<u8>) {
  892. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  893. self.vm.input = input;
  894. match module.invoke_export("call", &[], self) {
  895. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  896. TrapKind::Unreachable => (),
  897. _ => panic!("trap: {:?}", trap),
  898. },
  899. Err(err) => {
  900. panic!("unexpected error: {:?}", err);
  901. }
  902. Ok(v) => {
  903. panic!("unexpected return value: {:?}", v);
  904. }
  905. }
  906. }
  907. pub fn raw_constructor(&mut self, input: Vec<u8>) {
  908. let module = self.create_module(&self.accounts.get(&self.vm.account).unwrap().0);
  909. self.vm.input = input;
  910. if let Some(RuntimeValue::I32(ret)) = self.invoke_deploy(module) {
  911. if ret != 0 {
  912. panic!("non zero return")
  913. }
  914. }
  915. }
  916. pub fn heap_verify(&self) {
  917. let memsize = self.vm.memory.current_size().0 * 0x10000;
  918. println!("memory size:{}", memsize);
  919. let mut buf = Vec::new();
  920. buf.resize(memsize, 0);
  921. let mut current_elem = 0x10000;
  922. let mut last_elem = 0u32;
  923. loop {
  924. let next: u32 = self.vm.memory.get_value(current_elem).unwrap();
  925. let prev: u32 = self.vm.memory.get_value(current_elem + 4).unwrap();
  926. let length: u32 = self.vm.memory.get_value(current_elem + 8).unwrap();
  927. let allocated: u32 = self.vm.memory.get_value(current_elem + 12).unwrap();
  928. println!(
  929. "next:{:08x} prev:{:08x} length:{} allocated:{}",
  930. next, prev, length, allocated
  931. );
  932. let mut buf = vec![0u8; length as usize];
  933. self.vm
  934. .memory
  935. .get_into(current_elem + 16, &mut buf)
  936. .unwrap();
  937. if allocated == 0 {
  938. println!("{:08x} {} not allocated", current_elem + 16, length);
  939. } else {
  940. println!("{:08x} {} allocated", current_elem + 16, length);
  941. assert_eq!(allocated & 0xffff, 1);
  942. for offset in (0..buf.len()).step_by(16) {
  943. let mut hex = "\t".to_string();
  944. let mut chars = "\t".to_string();
  945. for i in 0..16 {
  946. if offset + i >= buf.len() {
  947. break;
  948. }
  949. let b = buf[offset + i];
  950. write!(hex, " {:02x}", b).unwrap();
  951. if b.is_ascii() && !b.is_ascii_control() {
  952. write!(chars, " {}", b as char).unwrap();
  953. } else {
  954. chars.push_str(" ");
  955. }
  956. }
  957. println!("{}\n{}", hex, chars);
  958. }
  959. }
  960. assert_eq!(last_elem, prev);
  961. if next == 0 {
  962. break;
  963. }
  964. last_elem = current_elem;
  965. current_elem = next;
  966. }
  967. }
  968. }
  969. pub fn build_solidity(src: &str) -> MockSubstrate {
  970. build_solidity_with_options(src, false, false)
  971. }
  972. pub fn build_solidity_with_options(
  973. src: &str,
  974. math_overflow_flag: bool,
  975. log_api_return_codes: bool,
  976. ) -> MockSubstrate {
  977. let mut cache = FileResolver::new();
  978. cache.set_file_contents("test.sol", src.to_string());
  979. let (res, ns) = compile(
  980. OsStr::new("test.sol"),
  981. &mut cache,
  982. inkwell::OptimizationLevel::Default,
  983. Target::default_substrate(),
  984. math_overflow_flag,
  985. log_api_return_codes,
  986. );
  987. ns.print_diagnostics_in_plain(&cache, false);
  988. assert!(!res.is_empty());
  989. let programs: Vec<Program> = res
  990. .iter()
  991. .map(|res| Program {
  992. code: res.0.clone(),
  993. abi: load_abi(&res.1),
  994. })
  995. .collect();
  996. let mut accounts = HashMap::new();
  997. let account = account_new();
  998. accounts.insert(account, (programs[0].code.clone(), 0));
  999. let vm = VirtualMachine::new(account, account_new(), 0);
  1000. MockSubstrate {
  1001. accounts,
  1002. printbuf: String::new(),
  1003. store: HashMap::new(),
  1004. programs,
  1005. vm,
  1006. current_program: 0,
  1007. events: Vec::new(),
  1008. }
  1009. }
  1010. fn load_abi(s: &str) -> InkProject {
  1011. let bundle = serde_json::from_str::<ContractMetadata>(s).unwrap();
  1012. serde_json::from_value::<InkProject>(serde_json::to_value(bundle.abi).unwrap()).unwrap()
  1013. }