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

     1  #lang ivy1.7
     2  
     3  include tendermint
     4  include abstract_tendermint
     5  
     6  # Here we prove the second accountability property: no well-behaved node is
     7  # ever observed to violate the accountability properties.
     8  
     9  # The proof is done in two steps: first we prove the the abstract specification
    10  # satisfies the property, and then we show by refinement that this property
    11  # also holds in the concrete specification.
    12  
    13  # To see what is checked in the refinement proof, use `ivy_show isolate=accountable_safety_2 accountable_safety_2.ivy`
    14  # To see what is checked in the abstract correctness proof, use `ivy_show isolate=abstract_accountable_safety_2 accountable_safety_2.ivy`
    15  # To check the whole proof, use `ivy_check complete=fo accountable_safety_2.ivy`.
    16  
    17  # Proof that the property holds in the abstract specification
    18  # ============================================================
    19  
    20  isolate abstract_accountable_safety_2 = {
    21  
    22      instantiate abstract_tendermint
    23  
    24  # the main property:
    25      invariant [wb_never_punished] well_behaved(N) -> ~(observed_equivocation(N) | observed_unlawful_prevote(N))
    26  
    27  # the main invariant for proving wb_not_punished:
    28      invariant well_behaved(N) & precommitted(N,R,V) & ~locked(N,R,V) & V ~= value.nil -> exists R2,V2 . V2 ~= value.nil & R < R2 & precommitted(N,R2,V2) & locked(N,R2,V2)
    29  
    30      invariant (exists N . well_behaved(N) & precommitted(N,R,V) & V ~= value.nil) -> exists Q . nset.is_quorum(Q) & forall N . nset.member(N,Q) -> observed_prevoted(N,R,V)
    31  
    32      invariant well_behaved(N) -> (observed_prevoted(N,R,V) <-> prevoted(N,R,V))
    33      invariant well_behaved(N) -> (observed_precommitted(N,R,V) <-> precommitted(N,R,V))
    34  
    35  # nodes stop prevoting or precommitting in lower rounds when doing so in a higher round:
    36      invariant well_behaved(N) & prevoted(N,R2,V2) & R1 < R2 -> left_round(N,R1)
    37      invariant well_behaved(N) & locked(N,R2,V2) & R1 < R2 -> left_round(N,R1)
    38  
    39      invariant [precommit_unique_per_round] well_behaved(N) & precommitted(N,R,V1) & precommitted(N,R,V2) -> V1 = V2
    40  
    41  } with nset, round, abstract_accountable_safety_2.defs.observed_equivocation_def, abstract_accountable_safety_2.defs.observed_unlawful_prevote_def
    42  
    43  # Proof that the property holds in the concrete specification
    44  # ===========================================================
    45  
    46  isolate accountable_safety_2 = {
    47  
    48      instantiate tendermint(abstract_accountable_safety_2)
    49  
    50      invariant well_behaved(N) -> ~(abstract_accountable_safety_2.observed_equivocation(N) | abstract_accountable_safety_2.observed_unlawful_prevote(N))
    51  
    52  } with round, value, shim, abstract_accountable_safety_2, abstract_accountable_safety_2.defs.observed_equivocation_def, abstract_accountable_safety_2.defs.observed_unlawful_prevote_def