/ tests / tests / execution / complex_finalization.adl
complex_finalization.adl
  1  /*
  2  seed = 123456789
  3  min_height = 16
  4  
  5  [case]
  6  program = "four_program.alpha"
  7  function = "a"
  8  input = []
  9  */
 10  
 11  // This test checks that the finalization order is correct.
 12  // The functions are invoked in the following order:
 13  // "four::a"
 14  //   --> "two::b"
 15  //        --> "zero::c"
 16  //        --> "one::d"
 17  //   --> "three::e"
 18  //        --> "two::b"
 19  //             --> "zero::c"
 20  //             --> "one::d"
 21  //        --> "one::d"
 22  //        --> "zero::c"
 23  // The future (call graph) produced by the top-level finalize should reflect this structure.
 24  
 25  program zero_program.alpha {
 26  
 27    mapping counts: address => u64;
 28  
 29    async transition c() -> Future {
 30      return finalize_c(self.signer);
 31    }
 32  
 33    async function finalize_c(addr: address) {
 34      let count: u64 = counts.get_or_use(addr, 0u64);
 35      counts.set(addr, count + 1u64);
 36    }
 37  
 38    @noupgrade
 39    async constructor() {}
 40  
 41  }
 42  
 43  
 44  // --- Next Program --- //
 45  
 46  
 47  program one_program.alpha {
 48  
 49    mapping counts: address => u64;
 50  
 51    async transition d() -> Future {
 52      return finalize_d(self.signer);
 53    }
 54  
 55    async function finalize_d(addr: address) {
 56      let count: u64 = counts.get_or_use(addr, 0u64);
 57      counts.set(addr, count + 1u64);
 58    }
 59  
 60    @noupgrade
 61    async constructor() {}
 62  
 63  }
 64  
 65  
 66  // --- Next Program --- //
 67  
 68  
 69  import zero_program.alpha;
 70  import one_program.alpha;
 71  
 72  program two_program.alpha {
 73  
 74    mapping counts: address => u64;
 75  
 76    async transition b() -> Future {
 77      let f0: Future = zero_program.alpha/c();
 78      let f1: Future = one_program.alpha/d();
 79      return finalize_b(f0, f1, self.signer);
 80    }
 81  
 82    async function finalize_b(f0: Future, f1: Future, addr: address) {
 83        f0.await();
 84        f1.await();
 85        let count: u64 = counts.get_or_use(addr, 0u64);
 86        counts.set(addr, count + 1u64);
 87    }
 88  
 89    @noupgrade
 90    async constructor() {}
 91  
 92  }
 93  
 94  
 95  // --- Next Program --- //
 96  
 97  
 98  import zero_program.alpha;
 99  import one_program.alpha;
100  import two_program.alpha;
101  
102  program three_program.alpha {
103  
104    mapping counts: address => u64;
105  
106    async transition e() -> Future {
107      let f0: Future = two_program.alpha/b();
108      let f1: Future = one_program.alpha/d();
109      let f2: Future = zero_program.alpha/c();
110      return finalize_e(f0, f1, f2, self.signer);
111    }
112  
113    async function finalize_e(f0: Future, f1: Future, f2: Future, addr: address) {
114        f0.await();
115        f1.await();
116        f2.await();
117        let count: u64 = counts.get_or_use(addr, 0u64);
118        counts.set(addr, count + 1u64);
119    }
120  
121    @noupgrade
122    async constructor() {}
123  
124  }
125  
126  
127  // --- Next Program --- //
128  
129  
130  import two_program.alpha;
131  import three_program.alpha;
132  
133  program four_program.alpha {
134  
135    mapping counts: address => u64;
136  
137    async transition a() -> Future {
138      let f0: Future = two_program.alpha/b();
139      let f1: Future = three_program.alpha/e();
140      return finalize_a(f0, f1, self.signer);
141    }
142  
143    async function finalize_a(f0: Future, f1: Future, addr: address) {
144      f0.await();
145      f1.await();
146      let count: u64 = counts.get_or_use(addr, 0u64);
147      counts.set(addr, count + 1u64);
148    }
149  
150    @noupgrade
151    async constructor() {}
152  
153  }