functions.rs 12 KB

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