call_flags.spec.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // SPDX-License-Identifier: Apache-2.0
  2. import expect from 'expect';
  3. import { createConnection, deploy, aliceKeypair, query, debug_buffer, } from './index';
  4. import { ContractPromise } from '@polkadot/api-contract';
  5. import { ApiPromise } from '@polkadot/api';
  6. import { KeyringPair } from '@polkadot/keyring/types';
  7. enum CallFlags {
  8. FORWARD_INPUT, CLONE_INPUT, TAIL_CALL, ALLOW_REENTRY
  9. }
  10. describe('Deploy the CallFlags contract and tests for various call flag combinations', () => {
  11. let conn: ApiPromise;
  12. let contract: ContractPromise;
  13. let alice: KeyringPair;
  14. const voyager = 987654321;
  15. const foo = [0, 0, 0, 0];
  16. before(async function () {
  17. alice = aliceKeypair();
  18. conn = await createConnection();
  19. const deployment = await deploy(conn, alice, 'CallFlags.contract', 0n);
  20. contract = new ContractPromise(conn, deployment.abi, deployment.address);
  21. });
  22. after(async function () {
  23. await conn.disconnect();
  24. });
  25. it('works with the reentry flag', async function () {
  26. const flags = [CallFlags.ALLOW_REENTRY];
  27. const answer = await query(conn, alice, contract, "echo", [contract.address, foo, voyager, flags]);
  28. expect(answer.output?.toJSON()).toStrictEqual(voyager);
  29. });
  30. it('works with the reentry and tail call flags', async function () {
  31. const flags = [CallFlags.ALLOW_REENTRY, CallFlags.TAIL_CALL];
  32. const answer = await query(conn, alice, contract, "echo", [contract.address, foo, voyager, flags]);
  33. expect(answer.output?.toJSON()).toStrictEqual(voyager);
  34. });
  35. it('works with the reentry and clone input flags', async function () {
  36. const flags = [CallFlags.ALLOW_REENTRY, CallFlags.CLONE_INPUT];
  37. const answer = await query(conn, alice, contract, "echo", [contract.address, foo, voyager, flags]);
  38. expect(answer.output?.toJSON()).toStrictEqual(voyager);
  39. });
  40. it('works with the reentry, tail call and clone input flags', async function () {
  41. const flags = [CallFlags.ALLOW_REENTRY, CallFlags.TAIL_CALL, CallFlags.CLONE_INPUT];
  42. const answer = await query(conn, alice, contract, "echo", [contract.address, foo, voyager, flags]);
  43. expect(answer.output?.toJSON()).toStrictEqual(voyager);
  44. });
  45. it('fails without the reentry flag', async function () {
  46. const flags = [CallFlags.TAIL_CALL];
  47. const answer = await query(conn, alice, contract, "echo", [contract.address, foo, voyager, flags]);
  48. const { index, error } = answer.result.asErr.asModule;
  49. // Module 8 error 0x16 is ReentranceDenied in the contracts pallet
  50. expect(index.toJSON()).toStrictEqual(8);
  51. expect(error.toJSON()).toStrictEqual("0x16000000");
  52. });
  53. it('fails with the input forwarding flag', async function () {
  54. const flags = [CallFlags.ALLOW_REENTRY, CallFlags.FORWARD_INPUT];
  55. const answer = await query(conn, alice, contract, "echo", [contract.address, foo, voyager, flags]);
  56. expect(answer.result.asOk.flags.isRevert).toStrictEqual(true);
  57. });
  58. it('test for the tail call flag to work correctly', async function () {
  59. let flags = [CallFlags.ALLOW_REENTRY];
  60. let answer = await query(conn, alice, contract, "tail_call_it", [contract.address, foo, voyager, flags]);
  61. expect(answer.output?.toJSON()).toStrictEqual(voyager + 1);
  62. flags = [CallFlags.ALLOW_REENTRY, CallFlags.TAIL_CALL];
  63. answer = await query(conn, alice, contract, "tail_call_it", [contract.address, foo, voyager, flags]);
  64. expect(answer.output?.toJSON()).toStrictEqual(voyager);
  65. });
  66. it('works on calls on "this"', async function () {
  67. const answer = await query(conn, alice, contract, "call_this", [voyager]);
  68. expect(answer.output?.toJSON()).toStrictEqual(voyager);
  69. });
  70. });