github.com/vipernet-xyz/tm@v0.34.24/spec/light-client/attacks/Isolation_001_draft.tla (about)

     1  ----------------------- MODULE Isolation_001_draft ----------------------------
     2  (**
     3   * The specification of the attackers isolation at full node,
     4   * when it has received an evidence from the light client.
     5   * We check that the isolation spec produces a set of validators
     6   * that have more than 1/3 of the voting power.
     7   *
     8   * It follows the English specification:
     9   *
    10   * https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/attacks/isolate-attackers_001_draft.md
    11   *
    12   * The assumptions made in this specification:
    13   *
    14   *  - the voting power of every validator is 1
    15   *     (add more validators, if you need more validators)
    16   *
    17   *  - Tendermint security model is violated
    18   *    (there are Byzantine validators who signed a conflicting block)
    19   *
    20   * Igor Konnov, Zarko Milosevic, Josef Widder, Informal Systems, 2020
    21   *)
    22  
    23  
    24  EXTENDS Integers, FiniteSets, Apalache
    25  
    26  \* algorithm parameters
    27  CONSTANTS
    28    AllNodes,
    29      (* a set of all nodes that can act as validators (correct and faulty) *)
    30    COMMON_HEIGHT,
    31      (* an index of the block header that two peers agree upon *)
    32    CONFLICT_HEIGHT,
    33      (* an index of the block header that two peers disagree upon *)
    34    TRUSTING_PERIOD,
    35      (* the period within which the validators are trusted *)
    36    FAULTY_RATIO
    37      (* a pair <<a, b>> that limits that ratio of faulty validator in the blockchain
    38         from above (exclusive). Tendermint security model prescribes 1 / 3. *)
    39  
    40  VARIABLES  
    41    blockchain,           (* the chain at the full node *)
    42    refClock,             (* the reference clock at the full node *)
    43    Faulty,               (* the set of faulty validators *)
    44    conflictingBlock,     (* an evidence that two peers reported conflicting blocks *)
    45    state,                (* the state of the attack isolation machine at the full node *)
    46    attackers             (* the set of the identified attackers *)
    47  
    48  vars == <<blockchain, refClock, Faulty, conflictingBlock, state>>  
    49   
    50  \* instantiate the chain at the full node
    51  ULTIMATE_HEIGHT == CONFLICT_HEIGHT + 1 
    52  BC == INSTANCE Blockchain_003_draft
    53  
    54  \* use the light client API
    55  TRUSTING_HEIGHT == COMMON_HEIGHT
    56  TARGET_HEIGHT == CONFLICT_HEIGHT
    57  
    58  LC == INSTANCE LCVerificationApi_003_draft
    59      WITH localClock <- refClock, REAL_CLOCK_DRIFT <- 0, CLOCK_DRIFT <- 0
    60  
    61  \* old-style type annotations in apalache
    62  a <: b == a
    63  
    64  \* [LCAI-NONVALID-OUTPUT.1::TLA.1]
    65  ViolatesValidity(header1, header2) ==
    66      \/ header1.VS /= header2.VS
    67      \/ header1.NextVS /= header2.NextVS
    68      \/ header1.height /= header2.height
    69      \/ header1.time /= header2.time
    70      (* The English specification also checks the fields that we do not have
    71         at this level of abstraction:
    72         - header1.ConsensusHash != header2.ConsensusHash or
    73         - header1.AppHash != header2.AppHash or
    74         - header1.LastResultsHash header2 != ev.LastResultsHash
    75      *)
    76  
    77  Init ==
    78      /\ state := "init"
    79      \* Pick an arbitrary blockchain from 1 to COMMON_HEIGHT + 1.
    80      /\ BC!InitToHeight(FAULTY_RATIO) \* initializes blockchain, Faulty, and refClock
    81      /\ attackers := {} <: {STRING}      \* attackers are unknown
    82      \* Receive an arbitrary evidence.
    83      \* Instantiate the light block fields one by one,
    84      \* to avoid combinatorial explosion of records.
    85      /\ \E time \in Int:
    86          \E VS, NextVS, lastCommit, Commits \in SUBSET AllNodes:
    87            LET conflicting ==
    88               [ Commits |-> Commits,
    89                 header |->
    90                   [height |-> CONFLICT_HEIGHT,
    91                    time |-> time,
    92                    VS |-> VS,
    93                    NextVS |-> NextVS,
    94                    lastCommit |-> lastCommit] ]
    95            IN  
    96            LET refBlock == [ header |-> blockchain[COMMON_HEIGHT],
    97                             Commits |-> blockchain[COMMON_HEIGHT + 1].lastCommit ]
    98            IN
    99            /\ "SUCCESS" = LC!ValidAndVerifiedUntimed(refBlock, conflicting)
   100            \* More than third of next validators in the common reference block
   101            \* is faulty. That is a precondition for a fork.
   102            /\ 3 * Cardinality(Faulty \intersect refBlock.header.NextVS)
   103                  > Cardinality(refBlock.header.NextVS)
   104            \* correct validators cannot sign an invalid block
   105            /\ ViolatesValidity(conflicting.header, refBlock.header)
   106                => conflicting.Commits \subseteq Faulty
   107            /\ conflictingBlock := conflicting
   108  
   109      
   110  \* This is a specification of isolateMisbehavingProcesses.
   111  \*
   112  \* [LCAI-FUNC-MAIN.1::TLA.1]
   113  Next ==
   114      /\ state = "init"
   115      \* Extract the rounds from the reference block and the conflicting block.
   116      \* In this specification, we just pick rounds non-deterministically.
   117      \* The English specification calls RoundOf on the blocks.
   118      /\ \E referenceRound, evidenceRound \in Int:
   119        /\ referenceRound >= 0 /\ evidenceRound >= 0
   120        /\ LET reference == blockchain[CONFLICT_HEIGHT]
   121              referenceCommit == blockchain[CONFLICT_HEIGHT + 1].lastCommit
   122              evidenceHeader == conflictingBlock.header
   123              evidenceCommit == conflictingBlock.Commits
   124          IN
   125          IF ViolatesValidity(reference, evidenceHeader)
   126          THEN /\ attackers' := blockchain[COMMON_HEIGHT].NextVS \intersect evidenceCommit
   127               /\ state' := "Lunatic"
   128          ELSE IF referenceRound = evidenceRound
   129          THEN /\ attackers' := referenceCommit \intersect evidenceCommit
   130               /\ state' := "Equivocation"
   131          ELSE
   132            \* This property is shown in property
   133            \* Accountability of TendermintAcc3.tla
   134            /\ state' := "Amnesia"
   135            /\ \E Attackers \in SUBSET (Faulty \intersect reference.VS):
   136               /\ 3 * Cardinality(Attackers) > Cardinality(reference.VS)
   137               /\ attackers' := Attackers
   138      /\ blockchain' := blockchain
   139      /\ refClock' := refClock
   140      /\ Faulty' := Faulty
   141      /\ conflictingBlock' := conflictingBlock
   142  
   143  (********************************** INVARIANTS *******************************)
   144  
   145  \* This invariant ensure that the attackers have
   146  \* more than 1/3 of the voting power
   147  \*
   148  \* [LCAI-INV-Output.1::TLA-DETECTION-COMPLETENESS.1]
   149  DetectionCompleteness ==
   150    state /= "init" =>
   151      3 * Cardinality(attackers) > Cardinality(blockchain[CONFLICT_HEIGHT].VS)
   152  
   153  \* This invariant ensures that only the faulty validators are detected
   154  \*
   155  \* [LCAI-INV-Output.1::TLA-DETECTION-ACCURACY.1]
   156  DetectionAccuracy ==
   157    attackers \subseteq Faulty
   158  
   159  ==============================================================================