{"id":18417426,"url":"https://github.com/stellar/scp-proofs","last_synced_at":"2025-04-07T12:32:33.901Z","repository":{"id":42982410,"uuid":"205069506","full_name":"stellar/scp-proofs","owner":"stellar","description":"SCP proofs and models","archived":false,"fork":false,"pushed_at":"2024-11-18T19:27:49.000Z","size":644,"stargazers_count":10,"open_issues_count":2,"forks_count":5,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-22T18:41:27.787Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stellar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-29T03:05:46.000Z","updated_at":"2024-12-16T07:17:03.000Z","dependencies_parsed_at":"2022-09-19T18:50:21.748Z","dependency_job_id":null,"html_url":"https://github.com/stellar/scp-proofs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stellar%2Fscp-proofs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stellar%2Fscp-proofs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stellar%2Fscp-proofs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stellar%2Fscp-proofs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stellar","download_url":"https://codeload.github.com/stellar/scp-proofs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247653249,"owners_count":20973790,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T04:09:24.633Z","updated_at":"2025-04-07T12:32:28.892Z","avatar_url":"https://github.com/stellar.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"This is a repository containing formal proofs about the Stellar Consensus\nProtocol as described in the paper \"Fast and secure global payments with\nStellar\" (SOSP 2019).\n\nUsing Isabelle/HOL, we formalize the theory of Federated Byzantine Agreement\nSystems (FBAS) and we prove two main results: the cascade theorem and that the\nunion of two intact sets is intact.\n\nUsing Ivy, we formalize SCP in a high-level, non-executable specification, and\nwe prove that members of intertwined sets never disagree (SCP's main safety\nproperty) and some liveness properties.\n\nNOTE: For the old proofs, checkout [commit 803b345](https://github.com/stellar/scp-proofs/tree/803b345e3156f70eb1e24f522c50517161731cd0) . The repository at this\ncommit contains a full liveness proof. However, being written in Ivy 1.6, it\nhas a lot of hacks. The current, newer version of this repository contains\nproofs written in Ivy 1.7.\n\n# Isabelle/HOL proofs\n\nFBA.thy contains a formalization of the notion of intact set. Roughly speaking,\na set *I* is intact when (a) *I* is a quorum, and (b) even if all nodes outside\n*I* are faulty, any two quorums of members of *I* intersect.\n\nWe prove that:\n1. The cascade theorem holds: if `I` is an intact set, `Q` is a quorum of\n   a member of `I`, and `Q⊆S`, then either `I⊆S` or there is a member of `I−S`\n   that is blocked by `S∩I`.\n2. The union of two intersecting intact sets is intact. This implies that\n   maximal intact sets are disjoint.\n\nNote that there two major differences compared to the treatment in the Stellar\nWhitepaper:\n1. We do not assume that the FBAS enjoys quorum intersection. Thus there may be\n   disjoint intact sets that diverge but nevertheless remain internally safe\n   and live. Point 2 above implies that maximal intact sets are disjoint, and\n   that an FBA system is a collection of disjoint maximal intact sets.\n2. We use a new, more abstract definition of quorum for the analysis. A quorum\n   is a set `Q` such that all well-behaved members of `Q` have a slice in `Q`.\n\nNote that the new definition of quorum only relies on the slices of\nwell-behaved nodes, which seems natural since faulty nodes can arbitrarily\nchange their slices, whereas the original definition of quorum used the slices\nof faulty nodes too.\n\nWe use this new definition of quorum only for the analysis of the system. In\nreality, nodes do not know who is faulty and thus cannot use this new\ndefinition of quorum, and instead just check for sets whose members all have\na slice inside the set. The abstraction we make here is safe because any set\nthat is deemed a quorum by a node in reality is also a quorum in the abstract\ndefinition that we use for our analysis. Moreover, the two definitions coincide\nexactly when we consider only well-behaved nodes.\n\nTo browse and check FBA.thy with Isabelle, use [Isabelle\n2019](https://isabelle.in.tum.de/). The file `output/document.pdf` is a PDF\nversion of FBA.thy.\n\nThere is also a maintained version of the theory of FBAS and more in the\nArchive of Formal Proofs:\n\u003chttps://devel.isa-afp.org/entries/Stellar_Quorums.html\u003e.\n\n## Comments on the Isabelle/HOL proofs\n\nThe proofs do not follow the presentation of the Stellar Whitepaper. They are\nsimpler due to the reformulation of the notion of quorum.\n\nTo prove the cascade theorem, we assume by contradiction that `I` is not\na subset of `S` but no member of `S−I` is blocked by `S∩I`. In this situation,\nwe note that `I−S` is a quorum of a member of `I` in the projection of the\nsystem on `I`. Moreover, `Q` is also a quorum of a member of `I` in the\nprojection of the system on `I`. Thus, by the quorum intersection property of\n`I`, `Q` and `I−S` must intersect. This is clearly impossible since `Q` is\na subset of `S`, and we have reached a contradiction.\n\nTo prove that the union of two intersecting intact set is intact, we reason as\nfollows. Take two intersecting intact sets `I₁` and `I₂`. First, note that\n`I₁∪I₂` is trivially a quorum, and thus we have quorum availability.\n\nIt remains to show that `I₁∪I₂` enjoys quorum intersection. Take a set `Q₁`\nthat is a quorum of a member of `I₁` in the system projected on `I₁∪I₂` and\na quorum `Q₂` that is a quorum of a member of `I₂` in the system projected on\n`I₁∪I₂`. We must show that `Q₁` and `Q₂` intersect in `I₁∪I₂`. First note that\n`I₂` is a quorum in the system projected on `I₁` and, by assumption,\n`I₁∩I₂≠{}`. Moreover, `Q₁` is a quorum in the system projected on `I₁` and `I₁`\nis intact. Thus, by the quorum intersection property of intact sets, (a) `I₂`\nand `Q₁` intersect. Moreover, (b) both `Q₁` and `Q₂` are quorums in the system\nprojected on `I₂`. Because `I₂` is intact, by the quorum intersection property,\nwe get from (a) and (b) that `Q₁` and `Q₂` intersect in `I₂`, and we are done.\n\n# Ivy proofs\n\nThis repository contains a proof of SCP's safety property in Ivy (isolate\nprotocol.intertwined_safety in SCP.ivy) and of some of SCP's liveness properties.\n\n## Running the proofs\n\nTo run the proof (that is, to have Ivy check them), run the following commands\n(on Linux) from the root of this repository:\n```\ndocker-compose build ivy-check\ndocker-compose run ivy-check\n```\n\n## Background material to understand the model and proofs\n\n* To understand the model and safety proofs:\n  * Padon, Oded, et al. *Paxos made EPR: decidable reasoning about distributed protocols.* Proceedings of the ACM on Programming Languages 1.OOPSLA (2017): 108. (available [on arXiv](https://arxiv.org/abs/1710.07191)).\n\n* To understand the liveness proofs:\n  * Padon, Oded, et al. *Temporal prophecy for proving temporal properties of infinite-state systems.* 2018 Formal Methods in Computer Aided Design (FMCAD). IEEE, 2018.\n  * Padon, O., Hoenicke, J., Losa, G., Podelski, A., Sagiv, M., \u0026 Shoham, S. (2017). *Reducing liveness to safety in first-order logic*. Proceedings of the ACM on Programming Languages, 2(POPL), 26.\n\n## What is proved with Ivy?\n\n### The model\n\nFirst, the proofs make statements about a model of SCP written in the Ivy\nlanguage, and not about SCP's implementation or SCP's description in the\nStellar Whitepaper. This model may not reflect what the reader think SCP is,\nand what SCP is may be open to interpretation since there is not agreed-upon\nformal specification. The model in `SCP.ivy` could in principle be taken as the\nformal specification of SCP.\n\n**Caveat 1**: Discrepancies between the SCP model and any other notion of what\nSCP is would imply that the statements proved with Ivy may not apply to that\nother notion of what SCP is.\n\nThe model consists of an initial state and a collection of actions, which are\natomic steps that update the global state of the system. Actions model what\nnodes do upon receiving messages or upon timers firing. Each action consists of\npreconditions (expressed using `require` statements) and state updates. An\nexecution of the model is a sequence of global states, starting with the\ninitial state, and such that each successive state is obtained from the\npreceding state by applying an action whose preconditions are satisfied. This\nis an instance of Lamport's Standard Model, used e.g. in TLA+, which Lamport\ndiscusses in his Turing Award lecture.\n\nPreconditions and state updates are specified using First-Order Logic formulas.\nNote that, by convention, all free upper-case variables are taken to be\nuniversally quantified. For more details about specifying protocols in Ivy (and\nproving their safety), see the [Ivy tutorial](https://microsoft.github.io/ivy/).\n\n**Caveat 2:** It is easy to write a model that does nothing, e.g. because the\npreconditions of the actions are too strong or even contradictory, and, in this\ncase, any proof is meaningless. One way to ensure that the model does do\nsomething is to prove liveness properties. For example, we might want to prove\nthat, in every eventually synchronous execution, every intact node eventually\nconfirms a value as committed. We discuss the liveness of SCP below.\n\n#### Abstractions\n\nThe SCP model abstracts over several aspects of SCP.\n\n#### Quorum slices\n\nThere is no notion of quorum slice in the model. Instead, we consider a\nset of nodes which each have a set of quorums and a notion of blocking set. We\nthen define intertwined and intact sets using the following axioms:\n1. The intersection of two quorums of intertwined nodes contains a well-behaved\n   node.\n2. The intersection of two quorums of intact nodes contains an intact node.\n3. The set of intact nodes is a quorum.\n4. If `Q` is a quorum of an intact node and if all members of `Q` have accepted\n   `(b,v)` as prepared, then either all intact nodes have accepted `(b,v)` as\n   prepared, or there is an intact node `n` such that `n` has not accepted\n   `(b,v)` as prepared and `n` is blocked by a set of intact nodes that have\n   all accepted `(b,v)` as prepared. This is an instance of the cascade\n   theorem.\n5. If an intact node is blocked by a set of nodes `S`, then `S` contains an\n   intact node. Properties 4 and 5 are proved in the Isabelle/HOL theory\n   `FBA.thy`.\n\n**Caveat 3**: If those axioms are inconsistent (i.e. lead to a contradiction\nwhen taken together), the proofs are meaningless. We verified 4 and 5 in\nIsabelle/HOL, but there is no mechanically-checked link between the Ivy axioms\nand the Isabelle/HOL theory. Thus there is still the possibility that of\na typo.\n\n**TODO**: It should be possible to use Ivy to check that the axioms have\na model, which would rule out any inconsistency.\n\nAbstracting slices away may see like a bold step. However, the model still\npreserves the most challenging algorithmic aspect of implementing consensus in\na federated Byzantine agreement system, i.e. the fact that the notion of quorum\nis different for each participant. What is not captured by the model includes\nthe fact that quorums are discovered dynamically (nodes know all their quorums\nupfront in the model) and that quorums might change during execution as nodes\nadjust their slices (quorums are fixed upfront in the model).\n\n#### Execution model\n\nThere is no notion of real-time in the model. Instead, messages are delivered\nat non-deterministically and an armed timer can fire non-deterministically at\nany point. Thus we cannot make any statements about the amount of time that it\ntakes to make certain things happen.\n\nHowever, in practice, liveness depends on having synchronized clocks and a\nnetwork delay commensurate with timer values. For the liveness proofs, since we\ncannot talk about real time, we instead make assumptions using Linear-Time Temporal\nLogic (LTL). For example, we assume that every message sent from an intact node\nto an intact node is eventually delivered. Moreover, for a full liveness proof,\nwe would need to assume that there exists a ballot `b` after which the system\nbecomes synchronous (i.e.every message sent by an intact node to an intact node\nis received in the same ballot) and no non-intact nodes take any steps.\n\n#### Nomination\n\nFinally, the model does not specify the nomination protocol. Instead, we assume\nthat nomination can produce arbitrary values, which is a sound\nover-approximation.\n\n### Safety\n\nWe prove that intertwined nodes never disagree by providing a collection of\ninvariants which, together with the safety property to prove, form an\ninductive invariant (i.e. they hold in the initial state and are preserved by\nevery action).\n\nThe key invariants are:\n1. A well-behaved node does not accept `(b,v)` as committed unless it confirmed\n   `(b,v)` as prepared.\n2. A well-behaved node does not accept contradictory statements (where `commit\n   (b,v)` and `prepare (b',v')` are contradictory when `b \u003c b'` and `v ≠ v'`.\n3. If an intertwined node confirms a statement, then there is a quorum of an\n   intertwined node whose well-behaved members accepted that statement.\n4. A well-behaved node does not accept different values as prepared in the same\n   ballot.\n\nGiven those invariants, suppose that `v` and `v'` are confirmed committed in\nballots `n` and `n'`, with `n \u003c n'`. By Invariant 1 and Invariant 3, there is\na quorum `Q` of an intertwined node whose well-behaved members all accepted\n`(n',v')` as prepared. Thus, by Invariant 2, no well-behaved member of `Q` ever\naccepts `(n,v)` as committed. Thus, by Invariant 3 and Quorum Intersection, no\nintertwined node confirmed `(n,v)` as committed, which is a contradiction.\n\nUsing the auxiliary conjectures present in the `safety` isolate in\n`SCP-safety.ivy`, Ivy reaches the same conclusion automatically and\nsuccessfully validates that the safety property holds.\n\n### Liveness\n\nWe would like to prove that SCP guarantees that, under eventual synchrony,\nevery intact node eventually confirms a value as committed. Unfortunately, this\ndoes not hold, and SCP guarantees the following, weaker liveness property: if\nthe system is eventually synchronous and non-intact nodes eventually stop\ntaking steps, then every intact node eventually confirms a value as committed.\n\nMore precisely, let us now sketch a proof that, after two consecutive\nsynchronous ballots that are long enough, every intact node confirms a value as\ncommitted.\n\nThis liveness property follows from the following two sub-properties:\n* L1: by the end of a long-enough synchronous ballot in which non-intact nodes\n  do not take steps, every intact node agrees on the highest confirmed-prepared\n  value.\n* L2: if a quorum unanimously votes to prepare a value `v` during a long-enough\n  synchronous ballot, then every intact node confirms `v` as committed by the\n  end of the ballot.\n\nNow why do L1 and L2 imply the liveness property? Note that, if intact nodes\nagree that the highest confirmed-prepared value is `v`, then they all vote for\n`v`. Thus, once ballots become synchronous and Byzantine nodes stop taking\nstep, properties L1 and L2 together imply that all intact nodes decide.\n\nLet us know informally argue why properties L1 and L2 hold. In each cases, the\nmain obstacle to liveness is the fact that nodes do not accept contradictory\nvalues, and this could block progress. In both cases, we rule out progress\nbeing blocked in this way using additional invariants proved in the isolate\n`protocol.additional_safety`.\n\nTo see why property L1 holds, assume that an intact node has confirmed `(b,v)`\nprepared during a long-enough synchronous ballot. Then, as we prove in `inv2`\nin isolate `protocol.additional_safety`, no contradictory statement is ever\naccepted by intact nodes. Thus, other intact nodes are never prevented from\naccepting `(b,v)` as prepared, and the Cascade Theorem ensures that, given\nenough communication, every intact node confirms `(b,v)` as prepared. Thus, if\nballot `b` is long enough, evey intact node confirms `(b,v)` as prepared by the\nend of the ballot.\n\nTo see  why property L2 holds, assume that every intact node votes to prepare\nthe same value `v` during a long-enough synchronous ballot `b`. Then, as we\nprove in `inv1` in isolate `protocol.additional_safety`, no contradictory\nstatement is ever accepted by intact nodes. Thus, given enough communication,\nnothing prevents value `v` from being accepted prepared, then confirmed\nprepared, then accepted committed, and finally confirmed committed by all\nintact nodes. Thus, if ballot `b` is long enough, every intact node confirms\n`(b,v)` as committed by the end of the ballot.\n\n#### What liveness properties are proved in Ivy?\n\nAn old version of this repository (commit `803b345`) contains a full liveness\nproof. However, this old proof is written in Ivy 1.6 and contains many hacks.\nThe current repository uses Ivy 1.7 and contains cleaner liveness proofs.\nHowever, we have so far only ported the proof of the following statement: if an\nintact node confirms `(b,v)` as prepared, then eventually all intact nodes\nconfirm `(b,v)` as prepared. This implies property L1.\n\n#### Liveness in practice\n\nUnfortunately, Byzantine nodes can always interfere right before the end of\na ballot and cause disagreement on what is confirmed prepared among intact\nnodes and make L1 fail. More precisely, a Byzantine node can always withhold an\n\"accept prepare\" message right until the end of a ballot (either because it is\nfaulty or because it has bad timing) and complete a quorum just before the\nballot ends, and thereby cause some intact nodes to confirm the corresponding\nvalue as prepared while others do not.\n\nIn practice, to ensure that all intact nodes vote to prepare the same value in\nthe next ballot, intact nodes must adjust their slices to make sure that no\nfaulty or otherwise untimely node remain in any of their quorums.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstellar%2Fscp-proofs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstellar%2Fscp-proofs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstellar%2Fscp-proofs/lists"}