calls.rs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::{build_solidity, build_solidity_with_options};
  3. use parity_scale_codec::{Decode, Encode};
  4. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  5. struct RevertReturn(u32, String);
  6. #[test]
  7. fn revert() {
  8. let mut runtime = build_solidity(
  9. r##"
  10. contract bar {
  11. function test() public {
  12. revert("yo!");
  13. }
  14. function a() public {
  15. b();
  16. }
  17. function b() public {
  18. c();
  19. }
  20. function c() public {
  21. d();
  22. }
  23. function d() public {
  24. revert("revert value has to be passed down the stack");
  25. }
  26. }"##,
  27. );
  28. runtime.function_expect_failure("test", Vec::new());
  29. assert_eq!(runtime.output().len(), 0);
  30. runtime.function_expect_failure("a", Vec::new());
  31. assert_eq!(runtime.output().len(), 0);
  32. let mut runtime = build_solidity(
  33. r##"
  34. contract c {
  35. function test() public {
  36. revert();
  37. }
  38. }"##,
  39. );
  40. runtime.function_expect_failure("test", Vec::new());
  41. assert_eq!(runtime.output().len(), 0);
  42. }
  43. #[test]
  44. fn require() {
  45. let mut runtime = build_solidity(
  46. r##"
  47. contract c {
  48. function test1() public {
  49. require(false, "Program testing can be used to show the presence of bugs, but never to show their absence!");
  50. }
  51. function test2() public {
  52. require(true, "Program testing can be used to show the presence of bugs, but never to show their absence!");
  53. }
  54. }"##,
  55. );
  56. runtime.function_expect_failure("test1", Vec::new());
  57. // The reason is lost
  58. assert_eq!(runtime.output().len(), 0);
  59. runtime.function("test2", Vec::new());
  60. assert_eq!(runtime.output().len(), 0);
  61. }
  62. #[test]
  63. fn input_wrong_size() {
  64. let mut runtime = build_solidity(
  65. r##"
  66. contract c {
  67. function test(int32 x) public {
  68. }
  69. }"##,
  70. );
  71. runtime.function_expect_failure("test", b"A".to_vec());
  72. // the decoder does check if there is too much data
  73. runtime.function_expect_failure("test", b"ABCDE".to_vec());
  74. }
  75. #[test]
  76. fn external_call_not_exist() {
  77. let mut runtime = build_solidity(
  78. r##"
  79. contract c {
  80. function test() public {
  81. other o = other(address(102));
  82. o.test();
  83. }
  84. }
  85. contract other {
  86. function test() public {
  87. }
  88. }"##,
  89. );
  90. runtime.function_expect_failure("test", Vec::new());
  91. }
  92. #[test]
  93. fn contract_already_exists() {
  94. let mut runtime = build_solidity(
  95. r##"
  96. contract c {
  97. function test() public {
  98. other o = new other{salt: 0}();
  99. other t = new other{salt: 0}();
  100. }
  101. }
  102. contract other {
  103. function test() public {
  104. }
  105. }"##,
  106. );
  107. runtime.constructor(0, Vec::new());
  108. runtime.function_expect_failure("test", Vec::new());
  109. let mut runtime = build_solidity(
  110. r##"
  111. contract c {
  112. function test() public {
  113. other o = new other();
  114. other t = new other();
  115. }
  116. }
  117. contract other {
  118. function test() public {
  119. }
  120. }"##,
  121. );
  122. runtime.constructor(0, Vec::new());
  123. runtime.function("test", Vec::new());
  124. }
  125. #[test]
  126. fn try_catch_external_calls() {
  127. let mut runtime = build_solidity(
  128. r##"
  129. contract c {
  130. function test() public {
  131. other o = new other();
  132. int32 x = 0;
  133. try o.test() returns (int32 y, bool) {
  134. x = y;
  135. } catch (bytes) {
  136. x = 2;
  137. }
  138. assert(x == 102);
  139. }
  140. }
  141. contract other {
  142. function test() public returns (int32, bool) {
  143. return (102, true);
  144. }
  145. }
  146. "##,
  147. );
  148. runtime.constructor(0, Vec::new());
  149. runtime.function("test", Vec::new());
  150. let mut runtime = build_solidity(
  151. r##"
  152. contract c {
  153. function test() public {
  154. other o = new other();
  155. int32 x = 0;
  156. try o.test() returns (int32 y, bool) {
  157. x = y;
  158. } catch (bytes c) {
  159. assert(c == hex"a079c3080c666f6f");
  160. x = 2;
  161. }
  162. assert(x == 2);
  163. }
  164. }
  165. contract other {
  166. function test() public returns (int32, bool) {
  167. revert("foo");
  168. }
  169. }
  170. "##,
  171. );
  172. runtime.constructor(0, Vec::new());
  173. runtime.function_expect_failure("test", Vec::new());
  174. let mut runtime = build_solidity(
  175. r##"
  176. contract c {
  177. function test() public {
  178. other o = new other();
  179. try o.test(1) {
  180. print("shouldn't be here");
  181. assert(false);
  182. } catch Error(string foo) {
  183. print(foo);
  184. assert(foo == "yes");
  185. } catch (bytes c) {
  186. print("shouldn't be here");
  187. assert(false);
  188. }
  189. try o.test(2) {
  190. print("shouldn't be here");
  191. assert(false);
  192. } catch Error(string foo) {
  193. print(foo);
  194. assert(foo == "no");
  195. } catch (bytes c) {
  196. print("shouldn't be here");
  197. assert(false);
  198. }
  199. try o.test(3) {
  200. print("shouldn't be here");
  201. assert(false);
  202. } catch Error(string foo) {
  203. print("shouldn't be here");
  204. assert(false);
  205. } catch (bytes c) {
  206. assert(c.length == 0);
  207. }
  208. }
  209. }
  210. contract other {
  211. function test(int x) public {
  212. if (x == 1) {
  213. revert("yes");
  214. } else if (x == 2) {
  215. revert("no");
  216. } else {
  217. revert();
  218. }
  219. }
  220. }
  221. "##,
  222. );
  223. runtime.constructor(0, Vec::new());
  224. runtime.function_expect_failure("test", Vec::new());
  225. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  226. struct Ret(u32);
  227. let mut runtime = build_solidity(
  228. r##"
  229. contract dominator {
  230. child c;
  231. function create_child() public {
  232. c = (new child)();
  233. }
  234. function call_child() public view returns (int64) {
  235. return c.get_a();
  236. }
  237. function test() public pure returns (int32) {
  238. try c.go_bang() returns (int32 l) {
  239. print("try call success");
  240. return 8000;
  241. }
  242. catch Error(string l) {
  243. print("try error path");
  244. print(l);
  245. return 4000;
  246. }
  247. catch {
  248. print("try catch path");
  249. return 2000;
  250. }
  251. }
  252. }
  253. contract child {
  254. int64 a;
  255. constructor() public {
  256. a = 102;
  257. }
  258. function get_a() public view returns (int64) {
  259. return a;
  260. }
  261. function set_a(int64 l) public {
  262. a = l;
  263. }
  264. function go_bang() public pure returns (int32) {
  265. revert("gone bang in child");
  266. }
  267. }"##,
  268. );
  269. runtime.constructor(0, Vec::new());
  270. runtime.function("create_child", Vec::new());
  271. runtime.function_expect_failure("test", Vec::new());
  272. }
  273. #[test]
  274. fn try_catch_constructor() {
  275. let mut runtime = build_solidity(
  276. r##"
  277. contract c {
  278. function test() public {
  279. int x;
  280. try (new other)() {
  281. x = 102;
  282. } catch (bytes) {
  283. x = 2;
  284. }
  285. assert(x == 102);
  286. }
  287. }
  288. contract other {
  289. function test() public returns (int32, bool) {
  290. return (102, true);
  291. }
  292. }
  293. "##,
  294. );
  295. runtime.constructor(0, Vec::new());
  296. runtime.function("test", Vec::new());
  297. let mut runtime = build_solidity(
  298. r##"
  299. contract c {
  300. function test() public {
  301. int x;
  302. try new other({foo: true}) returns (other o) {
  303. (x, bool yata) = o.test();
  304. } catch (bytes) {
  305. x = 2;
  306. }
  307. assert(x == 102);
  308. }
  309. }
  310. contract other {
  311. constructor(bool foo) public {
  312. //
  313. }
  314. function test() public returns (int32, bool) {
  315. return (102, true);
  316. }
  317. }
  318. "##,
  319. );
  320. runtime.constructor(0, Vec::new());
  321. runtime.function("test", Vec::new());
  322. let mut runtime = build_solidity(
  323. r##"
  324. contract c {
  325. function test() public {
  326. int32 x = 0;
  327. try new other(true) {
  328. x = 1;
  329. } catch (bytes c) {
  330. assert(c == hex"a079c3080c666f6f");
  331. x = 2;
  332. }
  333. assert(x == 2);
  334. }
  335. }
  336. contract other {
  337. constructor(bool foo) public {
  338. revert("foo");
  339. }
  340. function _ext() public {}
  341. }
  342. "##,
  343. );
  344. runtime.constructor(0, Vec::new());
  345. // TODO / REGRESSION
  346. // This traps with InstructionTrap(MemoryOutOfBounds). Which does not seem right
  347. // runtime.function_expect_failure("test", Vec::new());
  348. }
  349. #[test]
  350. fn local_destructure_call() {
  351. let mut runtime = build_solidity(
  352. r##"
  353. contract c {
  354. function test() public {
  355. (, bytes32 b, string s) = foo();
  356. assert(b == "0123");
  357. assert(s == "abcd");
  358. }
  359. function foo() public returns (bool, bytes32, string) {
  360. return (true, "0123", "abcd");
  361. }
  362. }
  363. "##,
  364. );
  365. runtime.function("test", Vec::new());
  366. }
  367. #[test]
  368. fn payable_constructors() {
  369. // no contructors means constructor is not payable
  370. // however there is no check for value transfers on constructor so endowment can be received
  371. let mut runtime = build_solidity(
  372. r##"
  373. contract c {
  374. function test(string a) public {
  375. }
  376. }"##,
  377. );
  378. runtime.set_transferred_value(1);
  379. runtime.constructor(0, Vec::new());
  380. // contructors w/o payable means can't send value
  381. // however there is no check for value transfers on constructor so endowment can be received
  382. let mut runtime = build_solidity(
  383. r##"
  384. contract c {
  385. constructor() public {
  386. int32 a = 0;
  387. }
  388. function test(string a) public {
  389. }
  390. }"##,
  391. );
  392. runtime.set_transferred_value(1);
  393. runtime.constructor(0, Vec::new());
  394. // contructors w/ payable means can send value
  395. let mut runtime = build_solidity(
  396. r##"
  397. contract c {
  398. constructor() public payable {
  399. int32 a = 0;
  400. }
  401. function test(string a) public {
  402. }
  403. }"##,
  404. );
  405. runtime.set_transferred_value(1);
  406. runtime.constructor(0, Vec::new());
  407. }
  408. #[test]
  409. fn payable_functions() {
  410. // function w/o payable means can't send value
  411. let mut runtime = build_solidity(
  412. r##"
  413. contract c {
  414. function test() public {
  415. }
  416. }"##,
  417. );
  418. runtime.constructor(0, Vec::new());
  419. runtime.set_transferred_value(1);
  420. runtime.function_expect_failure("test", Vec::new());
  421. // test both
  422. let mut runtime = build_solidity(
  423. r##"
  424. contract c {
  425. function test() payable public {
  426. }
  427. function test2() public {
  428. }
  429. }"##,
  430. );
  431. runtime.constructor(0, Vec::new());
  432. runtime.set_transferred_value(1);
  433. runtime.function_expect_failure("test2", Vec::new());
  434. runtime.set_transferred_value(1);
  435. runtime.function("test", Vec::new());
  436. // test fallback and receive
  437. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  438. struct Ret(u32);
  439. let mut runtime = build_solidity(
  440. r##"
  441. contract c {
  442. int32 x;
  443. function get_x() public returns (int32) {
  444. return x;
  445. }
  446. function test() payable public {
  447. x = 1;
  448. }
  449. fallback() external {
  450. x = 2;
  451. }
  452. receive() payable external {
  453. x = 3;
  454. }
  455. }"##,
  456. );
  457. runtime.constructor(0, Vec::new());
  458. runtime.set_transferred_value(1);
  459. runtime.raw_function(b"abde".to_vec());
  460. runtime.function("get_x", Vec::new());
  461. assert_eq!(runtime.output(), Ret(3).encode());
  462. runtime.raw_function(b"abde".to_vec());
  463. runtime.function("get_x", Vec::new());
  464. assert_eq!(runtime.output(), Ret(2).encode());
  465. let mut runtime = build_solidity(
  466. r##"
  467. contract c {
  468. int32 x;
  469. function get_x() public returns (int32) {
  470. return x;
  471. }
  472. function test() payable public {
  473. x = 1;
  474. }
  475. receive() payable external {
  476. x = 3;
  477. }
  478. }"##,
  479. );
  480. runtime.constructor(0, Vec::new());
  481. runtime.set_transferred_value(1);
  482. runtime.raw_function(b"abde".to_vec());
  483. runtime.function("get_x", Vec::new());
  484. assert_eq!(runtime.output(), Ret(3).encode());
  485. runtime.raw_function_failure(b"abde".to_vec());
  486. let mut runtime = build_solidity(
  487. r##"
  488. contract c {
  489. int32 x;
  490. function get_x() public returns (int32) {
  491. return x;
  492. }
  493. function test() payable public {
  494. x = 1;
  495. }
  496. fallback() external {
  497. x = 2;
  498. }
  499. }"##,
  500. );
  501. runtime.constructor(0, Vec::new());
  502. runtime.set_transferred_value(1);
  503. runtime.raw_function_failure(b"abde".to_vec());
  504. runtime.set_transferred_value(0);
  505. runtime.raw_function(b"abde".to_vec());
  506. runtime.function("get_x", Vec::new());
  507. assert_eq!(runtime.output(), Ret(2).encode());
  508. }
  509. #[test]
  510. fn hash_tests() {
  511. let mut runtime = build_solidity(
  512. r##"
  513. contract tester {
  514. function test() public {
  515. bytes32 hash = keccak256("Hello, World!");
  516. assert(hash == hex"acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f");
  517. }
  518. }"##,
  519. );
  520. runtime.function("test", Vec::new());
  521. let mut runtime = build_solidity(
  522. r##"
  523. contract tester {
  524. function test() public {
  525. bytes memory s = "Hello, World!";
  526. bytes32 hash = keccak256(s);
  527. assert(hash == hex"acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f");
  528. }
  529. }"##,
  530. );
  531. runtime.function("test", Vec::new());
  532. let mut runtime = build_solidity(
  533. r##"
  534. contract tester {
  535. bytes s = "Hello, World!";
  536. function test() public {
  537. bytes32 hash = keccak256(s);
  538. assert(hash == hex"acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f");
  539. }
  540. }"##,
  541. );
  542. runtime.constructor(0, Vec::new());
  543. runtime.function("test", Vec::new());
  544. let mut runtime = build_solidity(
  545. r##"
  546. contract tester {
  547. function test() public {
  548. bytes32 hash = sha256("Hello, World!");
  549. assert(hash == hex"dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f");
  550. }
  551. }"##,
  552. );
  553. runtime.function("test", Vec::new());
  554. let mut runtime = build_solidity(
  555. r##"
  556. contract tester {
  557. function test() public {
  558. bytes32 hash = blake2_256("Hello, World!");
  559. assert(hash == hex"511bc81dde11180838c562c82bb35f3223f46061ebde4a955c27b3f489cf1e03");
  560. }
  561. }"##,
  562. );
  563. runtime.function("test", Vec::new());
  564. let mut runtime = build_solidity(
  565. r##"
  566. contract tester {
  567. function test() public {
  568. bytes16 hash = blake2_128("Hello, World!");
  569. assert(hash == hex"3895c59e4aeb0903396b5be3fbec69fe");
  570. }
  571. }"##,
  572. );
  573. runtime.function("test", Vec::new());
  574. let mut runtime = build_solidity(
  575. r##"
  576. contract tester {
  577. function test() public {
  578. bytes20 hash = ripemd160("Hello, World!");
  579. assert(hash == hex"527a6a4b9a6da75607546842e0e00105350b1aaf");
  580. }
  581. }"##,
  582. );
  583. runtime.function("test", Vec::new());
  584. }
  585. #[test]
  586. fn try_catch_reachable() {
  587. // ensure that implicit return gets added correctly if catch reachable not
  588. let _ = build_solidity(
  589. r##"
  590. contract AddNumbers { function add(uint256 a, uint256 b) external returns (uint256 c) {c = a + b;} }
  591. contract Example {
  592. AddNumbers addContract;
  593. event StringFailure(string stringFailure);
  594. event BytesFailure(bytes bytesFailure);
  595. function exampleFunction(uint256 _a, uint256 _b) public returns (uint256 _c) {
  596. try addContract.add(_a, _b) returns (uint256 _value) {
  597. return (_value);
  598. } catch Error(string memory _err) {
  599. // This may occur if there is an overflow with the two numbers and the `AddNumbers` contract explicitly fails with a `revert()`
  600. emit StringFailure(_err);
  601. } catch (bytes memory _err) {
  602. emit BytesFailure(_err);
  603. }
  604. _c = 1;
  605. }
  606. }"##,
  607. );
  608. let _ = build_solidity(
  609. r##"
  610. contract AddNumbers { function add(uint256 a, uint256 b) external returns (uint256 c) {c = a + b;} }
  611. contract Example {
  612. AddNumbers addContract;
  613. event StringFailure(string stringFailure);
  614. event BytesFailure(bytes bytesFailure);
  615. function exampleFunction(uint256 _a, uint256 _b) public returns (uint256 _c) {
  616. try addContract.add(_a, _b) returns (uint256 _value) {
  617. return (_value);
  618. } catch Error(string memory _err) {
  619. // This may occur if there is an overflow with the two numbers and the `AddNumbers` contract explicitly fails with a `revert()`
  620. emit StringFailure(_err);
  621. } catch (bytes memory _err) {
  622. emit BytesFailure(_err);
  623. return;
  624. }
  625. _c = 1;
  626. }
  627. }"##,
  628. );
  629. }
  630. #[test]
  631. fn log_api_call_return_values_works() {
  632. let mut runtime = build_solidity_with_options(
  633. r##"
  634. contract Test {
  635. constructor () payable {}
  636. function test() public {
  637. try new Other() returns (Other o) {
  638. o.foo();
  639. }
  640. catch {}
  641. }
  642. }
  643. contract Other {
  644. function foo() public pure {
  645. print("hi!");
  646. }
  647. }
  648. "##,
  649. true,
  650. false,
  651. );
  652. runtime.constructor(0, vec![]);
  653. runtime.function("test", vec![]);
  654. assert_eq!(
  655. &runtime.debug_buffer(),
  656. r##"call: instantiation_nonce=2,
  657. call: seal_instantiate=0,
  658. print: hi!,
  659. call: seal_debug_message=0,
  660. call: seal_call=0,
  661. "##
  662. );
  663. }
  664. #[test]
  665. fn selector() {
  666. let mut runtime = build_solidity_with_options(
  667. r##"
  668. contract c {
  669. function g() pure public returns (bytes4) {
  670. return this.f.selector ^ this.x.selector;
  671. }
  672. function f() public pure {}
  673. function x() public pure {}
  674. }"##,
  675. false,
  676. true,
  677. );
  678. runtime.function("g", vec![]);
  679. runtime.contracts()[0].code.messages["f"]
  680. .iter()
  681. .zip(&runtime.contracts()[0].code.messages["x"])
  682. .map(|(f, x)| f ^ x)
  683. .zip(runtime.output())
  684. .for_each(|(actual, expected)| assert_eq!(actual, expected));
  685. }