You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
4.1 KiB

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