substrate.rs 43 KB

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