github.com/aakash4dev/cometbft@v0.38.2/spec/ivy-proofs/tendermint_test.ivy (about)

     1  #lang ivy1.7
     2  
     3  include tendermint
     4  include abstract_tendermint
     5  
     6  isolate ghost_ = {
     7      instantiate abstract_tendermint
     8  }
     9  
    10  isolate protocol = {
    11      instantiate tendermint(ghost_) # here we instantiate the parameter of the tendermint module with `ghost_`; however note that we don't extract any code for `ghost_` (it's not in the list of object in the extract, and it's thus sliced away).
    12      implementation {
    13          definition init_val(n:node) = <<< `n`%2 >>>
    14      }
    15      # attribute test = impl
    16  } with ghost_, shim, value, round, proposers
    17  
    18  # Here we run a simple scenario that exhibits an execution in which nodes make
    19  # a decision. We do this to rule out trivial modeling errors.
    20  
    21  # One option to check that this scenario is valid is to run it in Ivy's REPL.
    22  # For this, first compile the scenario:
    23  #```ivyc target=repl isolate=code trace=true tendermint_test.ivy
    24  # Then, run the produced binary (e.g. for 4 nodes):
    25  #``` ./tendermint_test 4
    26  # Finally, call the action:
    27  #``` scenarios.scenario_1
    28  # Note that Ivy will check at runtime that all action preconditions are
    29  # satisfied. For example, runing the scenario twice will cause a violation of
    30  # the precondition of the `start` action, because a node cannot start twice
    31  # (see `require ~_has_started` in action `start`).
    32  
    33  # Another possibility would be to run `ivy_check` on the scenario, but that
    34  # does not seem to work at the moment.
    35  
    36  isolate scenarios = {
    37      individual all:nset # will be used as parameter to actions requiring a quorum
    38  
    39      after init {
    40          var iter := node.iter.create(0);
    41          while ~iter.is_end
    42          {
    43              all := all.insert(iter.val);
    44              iter := iter.next;
    45          };
    46          assert nset.is_quorum(all); # we can also use asserts to make sure we are getting what we expect
    47      }
    48  
    49      export action scenario_1 = {
    50          # all nodes start:
    51          var iter := node.iter.create(0);
    52          while ~iter.is_end
    53          {
    54              call protocol.server.start(iter.val);
    55              iter := iter.next;
    56          };
    57          # all nodes receive the leader's proposal:
    58          var m:msg;
    59          m.m_kind := msg_kind.proposal;
    60          m.m_src := 0;
    61          m.m_round := 0;
    62          m.m_value := 0;
    63          m.m_vround := round.minus_one;
    64          iter := node.iter.create(0);
    65          while ~iter.is_end
    66          {
    67              call net.recv(iter.val,m);
    68              iter := iter.next;
    69          };
    70          # all nodes prevote:
    71          iter := node.iter.create(0);
    72          while ~iter.is_end
    73          {
    74              call protocol.server.l_22(iter.val,0);
    75              iter := iter.next;
    76          };
    77          # all nodes receive each other's prevote messages;
    78          m.m_kind := msg_kind.prevote;
    79          m.m_vround := 0;
    80          iter := node.iter.create(0);
    81          while ~iter.is_end
    82          {
    83              var iter2 := node.iter.create(0); # the sender
    84              while ~iter2.is_end
    85              {
    86                  m.m_src := iter2.val;
    87                  call net.recv(iter.val,m);
    88                  iter2 := iter2.next;
    89              };
    90              iter := iter.next;
    91          };
    92          # all nodes precommit:
    93          iter := node.iter.create(0);
    94          while ~iter.is_end
    95          {
    96              call protocol.server.l_36(iter.val,0,0,all);
    97              iter := iter.next;
    98          };
    99          # all nodes receive each other's pre-commits
   100          m.m_kind := msg_kind.precommit;
   101          iter := node.iter.create(0);
   102          while ~iter.is_end
   103          {
   104              var iter2 := node.iter.create(0); # the sender
   105              while ~iter2.is_end
   106              {
   107                  m.m_src := iter2.val;
   108                  call net.recv(iter.val,m);
   109                  iter2 := iter2.next;
   110              };
   111              iter := iter.next;
   112          };
   113          # now all nodes can decide:
   114          iter := node.iter.create(0);
   115          while ~iter.is_end
   116          {
   117              call protocol.server.l_49_decide(iter.val,0,0,all);
   118              iter := iter.next;
   119          };
   120      }
   121  
   122      # TODO: add more scenarios
   123  
   124  } with round, node, proposers, value, nset, protocol, shim, net
   125  
   126  # extract code = protocol, shim, round, node
   127  extract code = round, node, proposers, value, nset, protocol, shim, net, scenarios