github.com/Team-Kujira/tendermint@v0.34.24-indexer/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 ==============================================================================