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.

159 lines
6.3 KiB

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