functions.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. // SPDX-License-Identifier: Apache-2.0
  2. use parity_scale_codec::{Decode, Encode};
  3. use crate::build_solidity;
  4. #[test]
  5. fn constructors() {
  6. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  7. struct Val(u64);
  8. // parse
  9. let mut runtime = build_solidity(
  10. "
  11. contract test {
  12. uint64 result;
  13. constructor() public {
  14. result = 1;
  15. }
  16. function get() public returns (uint64) {
  17. return result;
  18. }
  19. }",
  20. );
  21. runtime.constructor(0, Vec::new());
  22. runtime.function("get", Vec::new());
  23. assert_eq!(runtime.output(), Val(1).encode());
  24. // parse
  25. let mut runtime = build_solidity(
  26. "
  27. contract test {
  28. uint64 result;
  29. constructor(uint64 x) public {
  30. result = x;
  31. }
  32. function get() public returns (uint64) {
  33. return result;
  34. }
  35. }",
  36. );
  37. runtime.constructor(0, Val(0xaa_bb_cc_dd).encode());
  38. runtime.function("get", Vec::new());
  39. assert_eq!(runtime.output(), Val(0xaa_bb_cc_dd).encode());
  40. }
  41. #[test]
  42. #[should_panic]
  43. fn constructor_wrong_selector() {
  44. let mut runtime = build_solidity(
  45. "
  46. contract test {
  47. uint64 result;
  48. constructor(uint64 x) public {
  49. result = x;
  50. }
  51. function get() public returns (uint64) {
  52. return result;
  53. }
  54. }",
  55. );
  56. runtime.raw_constructor(vec![0xaa, 0xbb, 0xcc, 0xdd]);
  57. }
  58. #[test]
  59. fn constructor_override_selector() {
  60. let mut runtime = build_solidity(
  61. r#"
  62. contract test {
  63. uint64 result;
  64. @selector([1, 2, 3, 4])
  65. constructor(uint64 x) {
  66. result = x;
  67. }
  68. function get() public returns (uint64) {
  69. return result;
  70. }
  71. }"#,
  72. );
  73. let mut input: Vec<u8> = vec![1, 2, 3, 4];
  74. input.extend(0xaa_bb_cc_ddu64.encode());
  75. runtime.raw_constructor(input);
  76. runtime.function("get", Vec::new());
  77. assert_eq!(runtime.output(), 0xaa_bb_cc_ddu64.encode());
  78. }
  79. #[test]
  80. fn function_override_selector() {
  81. let mut runtime = build_solidity(
  82. r#"
  83. contract test {
  84. uint64 result;
  85. constructor() {
  86. result = 1;
  87. }
  88. @selector([1, 2, 3, 4])
  89. function set(uint64 x) public {
  90. result = x;
  91. }
  92. function get() public returns (uint64) {
  93. return result;
  94. }
  95. }"#,
  96. );
  97. let mut input: Vec<u8> = vec![1, 2, 3, 4];
  98. input.extend(0xaa_bb_cc_ddu64.encode());
  99. runtime.raw_function(input);
  100. runtime.function("get", Vec::new());
  101. assert_eq!(runtime.output(), 0xaa_bb_cc_ddu64.encode());
  102. }
  103. #[test]
  104. fn fallback() {
  105. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  106. struct Val(u64);
  107. // parse
  108. let mut runtime = build_solidity(
  109. "
  110. contract test {
  111. int64 result = 102;
  112. function get() public returns (int64) {
  113. return result;
  114. }
  115. fallback() external {
  116. result = 356;
  117. }
  118. }",
  119. );
  120. runtime.raw_function([0xaa, 0xbb, 0xcc, 0xdd, 0xff].to_vec());
  121. runtime.function("get", Vec::new());
  122. assert_eq!(runtime.output(), Val(356).encode());
  123. }
  124. #[test]
  125. #[should_panic]
  126. fn function_wrong_selector() {
  127. let mut runtime = build_solidity(
  128. "
  129. contract test {
  130. uint64 result;
  131. constructor(uint64 x) public {
  132. result = x;
  133. }
  134. function get() public returns (uint64) {
  135. return result;
  136. }
  137. }",
  138. );
  139. runtime.raw_function(vec![0xaa, 0xbb, 0xcc, 0xdd]);
  140. }
  141. #[test]
  142. #[should_panic]
  143. fn nofallback() {
  144. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  145. struct Val(u64);
  146. // parse
  147. let mut runtime = build_solidity(
  148. "
  149. contract test {
  150. int64 result = 102;
  151. function get() public returns (int64) {
  152. return result;
  153. }
  154. }",
  155. );
  156. runtime.raw_function([0xaa, 0xbb, 0xcc, 0xdd, 0xff].to_vec());
  157. runtime.function("get", Vec::new());
  158. assert_eq!(runtime.output(), Val(356).encode());
  159. }
  160. #[test]
  161. fn test_overloading() {
  162. // parse
  163. let mut runtime = build_solidity(
  164. "
  165. contract test {
  166. uint32 public result = 1;
  167. constructor() public {
  168. foo(true);
  169. assert(result == 102);
  170. foo(500);
  171. assert(result == 510);
  172. }
  173. function foo(bool x) private {
  174. if (x) {
  175. result = 102;
  176. }
  177. }
  178. function foo(uint32 x) private {
  179. result = x + 10;
  180. }
  181. }",
  182. );
  183. runtime.constructor(0, Vec::new());
  184. }
  185. #[test]
  186. fn shadowing() {
  187. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  188. struct Val(u64);
  189. let src = "
  190. contract test {
  191. uint64 result;
  192. function goodset(uint64 val) public {
  193. result = val;
  194. }
  195. function badset(uint64 val) public {
  196. uint64 result = val;
  197. }
  198. function get() public returns (uint64) {
  199. return result;
  200. }
  201. }";
  202. // parse
  203. let mut runtime = build_solidity(src);
  204. runtime.constructor(0, Vec::new());
  205. runtime.function("goodset", Val(0x1234_5678_9abc_def0).encode());
  206. runtime.function("get", Vec::new());
  207. assert_eq!(runtime.output(), Val(0x1234_5678_9abc_def0).encode());
  208. runtime.function("badset", Val(1).encode());
  209. runtime.function("get", Vec::new());
  210. assert_eq!(runtime.output(), Val(0x1234_5678_9abc_def0).encode());
  211. }
  212. #[test]
  213. fn test_loops() {
  214. // parse
  215. let mut runtime = build_solidity(
  216. "
  217. contract test {
  218. uint32 public result = 1;
  219. constructor() public {
  220. uint32 n = 0;
  221. for (uint32 i = 0; i < 1000; i += 100) {
  222. n += 1;
  223. }
  224. assert(n == 10);
  225. n = 0;
  226. for (uint32 i = 0; i < 1000; i += 100) {
  227. if (true)
  228. continue;
  229. n += 1;
  230. }
  231. assert(n == 0);
  232. n = 0;
  233. for (uint32 i = 0; i < 1000; i += 100) {
  234. n += 1;
  235. break;
  236. }
  237. assert(n == 1);
  238. n = 0;
  239. while (n < 10) {
  240. n += 9;
  241. }
  242. assert(n == 18);
  243. n = 0;
  244. while (false) {
  245. n += 1000;
  246. }
  247. assert(n == 0);
  248. do {
  249. n += 9;
  250. }
  251. while(false);
  252. assert(n == 9);
  253. }
  254. }",
  255. );
  256. runtime.constructor(0, Vec::new());
  257. }
  258. #[test]
  259. fn test_example() {
  260. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  261. struct Val32(i32);
  262. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  263. struct Val64(i64);
  264. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  265. struct ValBool(bool);
  266. // parse
  267. let src = include_str!("../../examples/example.sol");
  268. let mut runtime = build_solidity(src);
  269. runtime.constructor(0, Val32(102).encode());
  270. runtime.function("is_zombie_reaper", Vec::new());
  271. assert_eq!(runtime.output(), ValBool(false).encode());
  272. runtime.function("reap_processes", Vec::new());
  273. runtime.function("run_queue", Vec::new());
  274. }
  275. #[test]
  276. fn test_large_vals() {
  277. // parse
  278. let src = "
  279. contract test {
  280. function large() public returns (int) {
  281. return 102;
  282. }
  283. function large2(int x) public returns (int) {
  284. return x + 100;
  285. }
  286. function doda() public {
  287. int x = large();
  288. assert(large2(10) == 110);
  289. }
  290. }";
  291. let mut runtime = build_solidity(src);
  292. runtime.constructor(0, Vec::new());
  293. runtime.function("doda", Vec::new());
  294. }
  295. #[test]
  296. fn args_and_returns() {
  297. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  298. struct Val32(i32);
  299. let mut runtime = build_solidity(
  300. "
  301. contract foobar {
  302. function foo1() public returns (int32 a) {
  303. a = -102;
  304. }
  305. function foo2() public returns (int32 a) {
  306. a = -102;
  307. return 553;
  308. }
  309. }",
  310. );
  311. runtime.function("foo1", Vec::new());
  312. assert_eq!(runtime.output(), Val32(-102).encode());
  313. runtime.function("foo2", Vec::new());
  314. assert_eq!(runtime.output(), Val32(553).encode());
  315. }
  316. #[test]
  317. fn named_argument_call() {
  318. let mut runtime = build_solidity(
  319. "
  320. contract foobar {
  321. function foo1(bool x) public returns (int32 a) {
  322. return 2;
  323. }
  324. function foo1(uint32 x) public returns (int32 a) {
  325. a = bar({});
  326. }
  327. function bar() private returns (int32) {
  328. return 1;
  329. }
  330. function test() public {
  331. assert(foo1({ x: true }) == 2);
  332. assert(foo1({ x: 102 }) == 1);
  333. }
  334. }",
  335. );
  336. runtime.function("test", Vec::new());
  337. }
  338. #[test]
  339. fn positional_argument_call() {
  340. let mut runtime = build_solidity(
  341. "
  342. contract foobar {
  343. function foo1(bool x) public returns (int32 a) {
  344. return 2;
  345. }
  346. function foo1(uint32 x) public returns (int32 a) {
  347. return 1;
  348. }
  349. function test() public {
  350. assert(foo1(true) == 2);
  351. assert(foo1(102) == 1);
  352. }
  353. }",
  354. );
  355. runtime.function("test", Vec::new());
  356. }
  357. #[test]
  358. fn print() {
  359. let mut runtime = build_solidity(
  360. r#"
  361. contract foobar {
  362. function test() public {
  363. print("Hello, world");
  364. }
  365. }"#,
  366. );
  367. runtime.function("test", Vec::new());
  368. }
  369. #[test]
  370. fn destructuring_call() {
  371. let mut runtime = build_solidity(
  372. r#"
  373. contract c {
  374. function func1() public returns (int32, bool) {
  375. return (102, true);
  376. }
  377. function test() public {
  378. (int32 a, bool b) = func1();
  379. assert(a == 102 && b == true);
  380. }
  381. }"#,
  382. );
  383. runtime.constructor(0, Vec::new());
  384. runtime.function("test", Vec::new());
  385. let mut runtime = build_solidity(
  386. r#"
  387. contract c {
  388. function func1(int32 x) public returns (int32, bool) {
  389. return (102 + x, true);
  390. }
  391. function test() public {
  392. (int32 a, bool b) = func1({x: 5});
  393. assert(a == 107 && b == true);
  394. }
  395. }"#,
  396. );
  397. runtime.constructor(0, Vec::new());
  398. runtime.function("test", Vec::new());
  399. let mut runtime = build_solidity(
  400. r#"
  401. contract c {
  402. function test() public {
  403. b x = new b();
  404. (int32 a, bool b) = x.func1({x: 5});
  405. assert(a == 107 && b == true);
  406. (a, b) = x.func1(-1);
  407. assert(a == 101 && b == true);
  408. }
  409. }
  410. contract b {
  411. function func1(int32 x) public returns (int32, bool) {
  412. return (102 + x, true);
  413. }
  414. }"#,
  415. );
  416. runtime.constructor(0, Vec::new());
  417. runtime.function("test", Vec::new());
  418. }
  419. #[test]
  420. fn global_functions() {
  421. let mut runtime = build_solidity(
  422. r#"
  423. function global_function() pure returns (uint32) {
  424. return 102;
  425. }
  426. contract c {
  427. function test() public {
  428. uint64 x = global_function();
  429. assert(x == 102);
  430. }
  431. }"#,
  432. );
  433. runtime.function("test", Vec::new());
  434. let mut runtime = build_solidity(
  435. r#"
  436. function global_function() pure returns (uint32) {
  437. return 102;
  438. }
  439. function global_function2() pure returns (uint32) {
  440. return global_function() + 5;
  441. }
  442. contract c {
  443. function test() public {
  444. uint64 x = global_function2();
  445. assert(x == 107);
  446. }
  447. }"#,
  448. );
  449. runtime.function("test", Vec::new());
  450. let mut runtime = build_solidity(
  451. r#"
  452. function global_function() pure returns (uint32) {
  453. return 102;
  454. }
  455. function global_function2() pure returns (uint32) {
  456. return global_function() + 5;
  457. }
  458. contract c {
  459. function test() public {
  460. function() internal returns (uint32) ftype = global_function2;
  461. uint64 x = ftype();
  462. assert(x == 107);
  463. }
  464. }"#,
  465. );
  466. runtime.function("test", Vec::new());
  467. }