{"id":30047,"date":"2019-10-31T21:33:25","date_gmt":"2019-10-31T18:33:25","guid":{"rendered":"https:\/\/prohoster.info\/blog\/razbiraemsya-v-protokole-konsensusa-stellar\/"},"modified":"2019-10-31T21:33:25","modified_gmt":"2019-10-31T18:33:25","slug":"razbiraemsya-v-protokole-konsensusa-stellar","status":"publish","type":"post","link":"https:\/\/prohoster.info\/en\/blog\/razbiraemsya-v-protokole-konsensusa-stellar","title":{"rendered":"Understanding the Stellar Consensus Protocol","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/09b61160286ae40c21269e1590fc2b92.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThe Stellar Consensus Protocol is first described in <noindex><a rel=\"nofollow\" href=\"https:\/\/www.stellar.org\/papers\/stellar-consensus-protocol.pdf\">a scientific paper<\/a><\/noindex> by David Mazieres in 2015. It is a 'federated Byzantine agreement' system that allows decentralized computing networks without leaders to efficiently reach consensus on any decision. The Stellar payment network utilizes the Stellar Consensus Protocol (SCP) to maintain a consistent transaction history visible to all participants.<\/p>\n<p>Consensus protocols are considered to be difficult to understand. SCP is simpler than most of them, yet still shares this reputation\u2014partly due to the misconception that the 'federated voting' discussed in the first half of the scientific paper is SCP. But that is not the case! It is merely an important building block used in the second half of the paper to construct <i>the actual<\/i> Stellar Consensus Protocol.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nIn this article, we will briefly explain what an 'agreement system' is, what can make it 'Byzantine', and why a Byzantine system should be 'federated'. We will then explain the federated voting procedure described in the SCP paper and finally explain the SCP itself.<\/p>\n<h1>Agreement Systems<\/h1>\n<p>\nAn agreement system allows a group of participants to reach consensus on a topic, such as what to order for lunch.<\/p>\n<p>At Interstellar, we have implemented our own lunch agreement system: we order what our operations manager John says. It is a simple and effective agreement system. We all trust John and believe he will find something interesting and nutritious every day.<\/p>\n<p>But what if John abuses our trust? He could unilaterally decide that we should all become vegetarians. Within a week or two, we might likely overthrow him and hand the power to Elizabeth. But what if she loves avocado with anchovies and thinks everyone should be that way? Power corrupts. So it\u2019s better to find a more democratic method: a way to ensure that different preferences are considered while also providing a timely and clear result, so that it doesn\u2019t end up with no one ordering lunch or five people placing different orders, or the discussion dragging on until evening.<\/p>\n<p>It may seem like a simple solution: hold a vote! But this is a misleading impression. Who will collect the ballots and announce the results? And why should the others trust what he says? Perhaps we can <i>first<\/i> vote for a leader we trust to conduct the voting \u2014 but who will lead this <i>the first<\/i> voting? What if we can't agree on a leader? Or if we do agree, and this leader gets stuck in a meeting or falls ill?<\/p>\n<p>Similar problems occur in distributed computer networks. All participants or nodes need to agree on some decision, such as whose turn it is to update a shared file or take a task from the processing queue. In a cryptocurrency network, nodes often have to choose what the complete history looks like from several possible versions, which sometimes conflict. This network agreement guarantees the recipient that the coin is (a) valid (not counterfeit) and (b) not yet spent elsewhere. It also ensures that they will be able to spend the coins in the future, as the new recipient will have the same guarantees for the same reasons.<\/p>\n<p>Any consensus system in a distributed computing network must be fault-tolerant: it should provide consistent results despite errors, such as slow communication lines, unresponsive nodes, and incorrect message ordering. <i>Byzantine<\/i> consensus systems are additionally resilient to 'Byzantine' faults: nodes that provide false information, whether due to error or a deliberate attempt to undermine the system or gain some advantage. 'Byzantine' fault tolerance \u2014 the ability to trust a group decision even when some members of the group may lie or otherwise break the decision-making rules \u2014 is named after <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%B2%D0%B8%D0%B7%D0%B0%D0%BD%D1%82%D0%B8%D0%B9%D1%81%D0%BA%D0%B8%D1%85_%D0%B3%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D0%BB%D0%BE%D0%B2\">the fable of the Byzantine generals<\/a><\/noindex>, who tried to coordinate an attack. <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/coinmonks\/a-note-from-anthony-if-you-havent-already-please-read-the-article-gaining-clarity-on-key-787989107969\">A good description<\/a><\/noindex> is by Anthony Stevens.<\/p>\n<p>Let's consider the cryptocurrency owner Alice, who has to choose between buying delicious ice cream from Bob and paying off her debt to Carol. Perhaps Alice wants to pay both at once, fraudulently spending the same coin. To do this, she must convince Bob's computer that the coin was never paid to Carol and convince Carol's computer that the coin was never paid to Bob. The Byzantine agreement system makes this virtually impossible using a majority rule form called <i>a quorum<\/i>. A node in such a network refrains from transitioning to a certain version of history until it sees that a sufficient number of peer nodes\u2014a quorum\u2014agree to that transition. Once this happens, they will form a large enough electoral block to compel the remaining nodes in the network to accept their decision. Alice can force some nodes to lie on her behalf, but if the network is large enough, her attempt will be suppressed by the votes of honest nodes.<\/p>\n<p>How many nodes are required for a quorum? At least a majority, or more precisely, a qualified majority to combat errors and fraud. But to count a majority, the total number of participants must be known. In an Interstellar office or local elections, these numbers are easy to ascertain. But if your group is a loosely defined network in which nodes can join and leave at will without consent from a center, then a <i>federated<\/i> Byzantine agreement system is required, one capable of determining quorums not from a pre-defined list of nodes, but dynamically, from a constantly changing and inevitably incomplete snapshot of nodes at any given moment in time.<\/p>\n<p>It may seem impossible to create a quorum from the perspective of a single node in an expansive network, but it is indeed possible. Such a quorum can even guarantee the results of decentralized voting. The technical document SCP shows how to achieve this using a procedure called <i>federated voting.<\/i>.<\/p>\n<h1>For the impatient<\/h1>\n<p>\nThe rest of the article goes into more detail about federated voting and the Stellar consensus protocol. If you're not interested in the specifics, here\u2019s a general overview of the process.<\/p>\n<ol>\n<li>Nodes conduct rounds of federal voting on 'nominees.' A round of federal voting means:\n<ul>\n<li>A node votes on a particular statement, for example, 'I propose value V';\n<\/li>\n<li>A node listens to the votes of peers until it finds one that can 'accept';\n<\/li>\n<li>A node seeks a 'quorum' for this statement. The quorum 'confirms' the nominee.<\/li>\n<\/ul>\n<\/li>\n<li>Once a node can confirm one or more nominees, it attempts to 'prepare' the 'ballot' over several rounds of federal voting.\n<\/li>\n<li>Once a node is able to verify the readiness of the ballot, it tries to commit it through even more rounds of federal voting.\n<\/li>\n<li>Once a node can confirm the commit of the ballot, it can 'externalize' the value of this ballot, using it as the consensus result.<\/li>\n<\/ol>\n<p>\nThese steps include several rounds of federal voting that together form one SCP round. Let's take a closer look at what happens at each step.<\/p>\n<h1>Federal voting<\/h1>\n<p>\nFederal voting is the procedure for determining whether the network can agree on a proposal. In the voting round, each node must choose one of potentially many possible values. It cannot do this until it is certain that other nodes in the network will not choose a different outcome. To be sure of this, nodes exchange a flurry of messages back and forth so that each <i>confirmed<\/i>, that <i>quorum<\/i> of nodes <i>accepts<\/i> the same <i>the decision<\/i>. The rest of this section explains the terms in this statement and how the entire procedure takes place.<\/p>\n<h1>Quorums and quorum slices<\/h1>\n<p>\nLet's start with the definition of a quorum. As we discussed above, in a decentralized network with dynamic membership, it is impossible to know in advance how many nodes there are and therefore how many are needed for a majority. Federal voting solves this problem by introducing a new concept of <i>quorum slice<\/i> (quorum slice): a small set of peer nodes that a node trusts to communicate the state of the voting to the rest of the network. Each node defines its own quorum slice (of which it becomes a member in fact).<\/p>\n<p>The formation of a quorum begins with a quorum slice. Nodes are added for each slice. Then, members of the slices are added. <i>of these nodes.<\/i> and so on. As it continues, more nodes will be encountered that cannot be added because they are already included in the slice. When there are no new nodes left to add, the process stops: we have formed a quorum through the 'transitive closure' of the initial node's quorum slice.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/6991e3f9a22d920e4a5e9c161f32dee1.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>To find a quorum from a given node\u2026<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/52b3d435a8f4a67b56deb43c83fee828.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>\u2026 we add members of its slice\u2026<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/0820e9ca560caf9ebfa92db8e7a1da85.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>\u2026 then we add members of the slices of these nodes.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/539933eb3c279fa7da68fc9049516fc8.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>We continue until there are no more nodes to add.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/48058639262412514641063a10503a01.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/d068fb06f35337ae68c35b4606f329ae.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>No more nodes to add. This is the quorum.<\/i><\/p>\n<p>In fact, each node can belong to more than one slice. To form a quorum, select only one of the slices and add its members; then, for each of those members, select any slice and add its members. <i>this one<\/i> and so on. This means that each node is a member of a multitude of possible quorums.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/3427406c132cfd1cd174b856a1239908.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Select only one quorum slice at each step.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/79a8728890ecb36b2e127b1b76c44fc8.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/22fe0422c73cdf5fb5416e389934c5c3.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/60379efdde3b88fb9c86de6c5b4a0b62.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>One possible quorum. Or an alternative option\u2026<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/341f1e897be1474ee2d67324da2134b1.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>\u2026 selecting different slices\u2026<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/8a6d605050b075bf935e6151bd1cbe2c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/865567aa370605b7cf10da3457c3d158.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>\u2026(when possible)\u2026<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/6343f774104454d62e7c8681bf25dbcb.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>\u2026 creates another quorum.<\/i><\/p>\n<p>How does a node know which slices other nodes are part of? Similarly to how it learns other information about nodes: through broadcasts each node sends over the network when its voting state changes. Each broadcast includes information about the slices of the sending node. The SCP technical document does not specify the communication mechanism. Implementations usually use <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Gossip_protocol\">the gossip protocol<\/a><\/noindex> for guaranteed message broadcast across the network.<\/p>\n<p>Recall that in a non-federated Byzantine agreement system, a quorum is defined as a majority of all nodes. The Byzantine agreement system is developed with the question in mind: how many dishonest nodes can the system endure? In a system of N nodes designed to survive f failures (or deceptions), a node must be able to make progress by receiving responses from N\u2212f peers, since f of them may not be functioning. By receiving a response from N\u2212f peers, one can assume that all f peers (from whom the node did not receive a response) are actually honest. Thus, the malicious nodes are f out of the N\u2212f peers (from whom a response was received). For nodes to reach a single consensus, the majority of the remaining nodes must be honest, which means we need N\u2212f to be greater than 2f or N &gt; 3f. Therefore, a system designed to survive f faults will typically have a total of N=3f+1 nodes and a quorum size of 2f+1. Once a proposal crosses the quorum threshold, the other members of the network are convinced that any competing proposals will fail. Thus, the network converges to a result.<\/p>\n<p>But in a federated Byzantine agreement system, there cannot only be a majority (because no one knows the overall size of the network), and the concept of a majority is entirely useless! If membership in the system is open, someone can gain a majority simply by executing what is called a Sybil attack: repeatedly joining the network through multiple nodes. So why can the transitive closure of a slice be called <i>a quorum<\/i>, and how can it suppress competing proposals?<\/p>\n<p>Technically, it can't! Imagine a network of six nodes, where two triplets are isolated within each other's quorum slices. The first subgroup may come to a decision that the second will never hear about, and vice versa. For this network, there is no way to reach a consensus (except by chance).<\/p>\n<p>Therefore, SCP requires that for federated voting (and for the application of important theorems of the article), the network must possess a property called <i>the intersection of quorums<\/i>In a network with this property, any two quorums that can be formed always overlap at least at one node. For determining the prevailing sentiments of the network, this is just as good as having a majority. Intuitively, this means that if any quorum agrees with statement X, no other quorum can ever agree with something else, as it will necessarily include some node from the first quorum that has already voted for X.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/5b0aeec99e285b4bbeb92ec5b8dfe69d.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>If there is an intersection of quorums in the network\u2026<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/bdb3866cb02fb5991446f0cb0fa5a4fd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>\u2026 then any two quorums that you can form\u2026<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/29ee8d1ce9fba6c5c24386ce1c1c639b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>\u2026 will always overlap.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/6f1ef2b9896669c10fd19f1acd52db70.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/6849569e849ac3b5487d31e0bf22a596.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n(Of course, overlapping nodes may turn out to be Byzantine faulty or bad in other respects. In this case, the intersection of quorums does not help the network reach consensus at all. For this reason, many results in the technical document SCP are based on explicitly stated assumptions, such as the existence of a quorum intersection in the network\u2026 <i>even after the removal of bad nodes.<\/i>For simplicity, let\u2019s keep these assumptions\u2026 <i>implicit\u2026<\/i> in the rest of the article).<\/p>\n<p>It may seem unreasonable to expect reliable quorum intersection in a network of independent nodes. However, there are two reasons why this is the case.<\/p>\n<p>The first reason is the existence of the Internet itself. The Internet is a perfect example of a network of independent nodes with quorum intersections. Most nodes on the Internet connect only to a few other local nodes, but these small sets overlap sufficiently so that each node is accessible from every other node through one route or another.<\/p>\n<p>The second reason is specific to the Stellar payment network (the most common use of SCP). Each asset in the Stellar network has an issuer, and Stellar\u2019s guidelines require that each issuer appoint one or more nodes in the network to handle redemption requests. It is in your interest to include these nodes directly or indirectly in the quorum slices for each asset you are interested in. Then, the quorums for all nodes concerned with a given asset will overlap at least in these redemption nodes. Nodes interested in multiple assets will include in their quorum slices all redemption nodes of the respective issuers, and they will strive to combine all assets together. Additionally, any assets that are not directly connected to others in the network and <i>should not be linked<\/i> \u2014 it is designed so that there is no overlap of quorums in this network (for instance, banks in the dollar zone sometimes want to trade with banks in the euro zone and banks in the peso zone, so they are in the same network, but none of them cares about a separate network of kids trading baseball cards).<\/p>\n<p>Of course, <i>expectation<\/i> of quorum overlap is not <i>a guarantee<\/i>. Other Byzantine agreement systems owe much of their complexity to the guarantee of quorums. An important innovation of SCP is that it removes the responsibility of creating quorums from the consensus algorithm itself and elevates it to the application level. Thus, while federated voting is sufficiently general for voting on any issues, its reliability critically depends on the broader context of these meanings. Some hypothetical use cases may not be as conducive to creating well-connected networks as others.<\/p>\n<h1>Voting, acceptance, and confirmation<\/h1>\n<p>\nIn a round of federated voting, a node optionally begins voting for some value V. This means broadcasting a message to the network: 'I am node N, my quorum slices are Q, and I am voting for V.' When a node votes in this way, it promises that it has never voted against V and never will.<\/p>\n<p>In broadcasts from peer nodes, each node can see how others are voting. Once a node gathers enough of these messages, it can track quorum slices and attempt to find quorums. If it sees a quorum of peers also voting for V, it can move to <i>acceptance<\/i> of V and broadcast this new message to the network: \"I am node N, my quorum slices are Q, and I accept V.\" Acceptance provides a stronger guarantee than simple voting. When a node votes for V, it can never vote for other options. But if a node accepts V, no node in the Network will ever accept another option (Theorem 8 in the SCP technical document proves this).<\/p>\n<p>Of course, there is a high likelihood that a quorum of nodes agreeing on V won't be found immediately. Other nodes may vote for different values. However, there is another way for a node to move from simple voting to acceptance. N can accept another value W, even if it didn't vote for it, and even if it doesn't see a quorum for it. To resolve this, it only needs to see <i>a blocking set<\/i> of nodes that have accepted W. A blocking set consists of one node from each of N's quorum slices. As the name suggests, it is capable of <i>blocking<\/i> any other value. If all nodes in such a set accept W, then (by Theorem 8) it will never be possible to form a quorum accepting any other value, and therefore it is also safe for N to accept W.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/6dd4ec5595ab863daf684fec670d83a6.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Node N with three quorum slices.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/b65e32160570af2883eef9990a74e3bd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>B-D-F is a blocking set for N: it includes one node from each of N's slices.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/7e17b4a9ee83aac7fa2b68b2f9fae066.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>B-E is also a blocking set for N, because E appears in two of N's slices.<\/i><\/p>\n<p>But a blocking set is not a quorum. It would be too easy to trick node N into accepting a desired value if only one node in each of N's slices were compromised. Therefore, accepting a value doesn't mean the end of voting. Instead, N must confirm the value, meaning it needs to see a quorum of nodes accepting it. If it gets that far, then as the SCP technical document (Theorem 11) proves, the rest of the network will also eventually confirm the same value, allowing N to finalize the federated voting with a specific value as the result.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/bd68dc5172460c17fa2de54fcc0d9017.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Federated voting.<\/i><\/p>\n<p>The voting, adoption, and confirmation process constitutes one complete round of federated voting. The Stellar consensus protocol combines many such rounds to create a complete consensus system.<\/p>\n<h1>Stellar Consensus Protocol<\/h1>\n<p>\nThe two most important properties of a consensus system are <i>security<\/i> and <i>liveness<\/i>. A consensus algorithm is considered 'safe' if it can never produce different results for different participants (Bob's copy of history will never contradict Carol's). 'Liveness' means that the algorithm will always produce a result, meaning it won't get stuck.<\/p>\n<p>The described federated voting procedure <i>is safe<\/i> in the sense that if a node confirms a value V, no other node will confirm a different value. However, 'will not confirm a different value' does not mean it will necessarily confirm something at all. Participants can vote on so many different values that none may reach the acceptance threshold. This means that in federated voting, there is a lack of <i>liveness<\/i>.<\/p>\n<p>The Stellar Consensus Protocol uses federated voting in such a way as to ensure both safety and liveness. (The safety and liveness guarantees of SCP have a theoretical limit. The design opts for a very strong safety guarantee, sacrificing a slight weakening of liveness, but given enough time, consensus will likely be reached). In short, the idea is to conduct several federated votes on multiple values until one passes completely through all the voting phases of SCP detailed below.<\/p>\n<p>The values for which SCP seeks consensus can be a transaction history, an order for lunch, or anything else, but it is important to note that these are not the values that are adopted or confirmed. Instead, the federated vote occurs on <i>statements about these values<\/i>.<\/p>\n<p>The first rounds of federated voting occur during the <i>nomination phase<\/i> (nomination phase), on a set of statements like 'I nominate V', possibly for many different values V. The goal of the nomination is to find one or several statements that will pass through acceptance and confirmation.<\/p>\n<p>After identifying the verifiable candidates, the SCP moves to the voting stage, where the goal is to find a certain <i>ballot<\/i> (that is, a container for the proposed value) and a quorum that can declare <i>the commit<\/i> for it (commit). If the quorum commits the ballot, its value is accepted as consensus. However, before a node can vote for the commit of the ballot, it must first confirm the <i>cancellation<\/i> of all ballots with a lower counter value. These steps\u2014cancelling ballots to find the one for which a commit can be confirmed\u2014include several rounds of federated voting on multiple ballot statements.<\/p>\n<p>The following sections describe the nomination and voting processes in more detail.<\/p>\n<h1>Nomination<\/h1>\n<p>\nAt the beginning of the nomination stage, each node can spontaneously choose a value V and vote for the assertion \"I nominate V.\" The goal at this stage is to confirm the nomination of a certain value through federated voting.<\/p>\n<p>It is possible that a sufficient number of nodes vote for sufficiently different assertions, and no nomination can reach the acceptance threshold. Therefore, in addition to broadcasting their own nomination votes, nodes \"echo\" nominations from their peers. Echoing means that if a node votes for the nomination of V but sees a message from a neighbor voting for the nomination of W, it will now vote for both nominations V and W. (Not all peer votes are echoed during the nomination phase, as this may lead to an explosion of different nominees. The SCP includes a mechanism to regulate these votes. In short, there is a formula for determining the \"priority\" of a peer from the perspective of a node, and only the votes from high-priority nodes are echoed. The longer the nomination goes on, the lower the threshold, so the node expands the set of peers whose votes it will echo. The priority formula, as one of the inputs, includes the slot number, so a high-priority peer node for one slot may be low-priority for another, and vice versa).<\/p>\n<p>Conceptually, the nomination process for both V and W involves separate federated votes, each capable of achieving acceptance or confirmation on its own. In practice, SCP protocol messages bundle these individual votes together.<\/p>\n<p>While voting for the nomination of V implies a promise never to vote against it, at the application level\u2014specifically in SCP\u2014it defines what 'against' means. SCP does not recognize a statement that contradicts the vote 'I nominate X', meaning there is no message 'I oppose the nomination of X'; therefore, a node can vote for the nomination of any values. Many of these nominations may lead to nothing, but ultimately, a node will be able to accept or confirm one or more values. Once a nominee is confirmed, it becomes <i>a candidate<\/i>.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/794f55d076ec3e1773c49d32e29c084d.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>The SCP nomination using federated voting can result in multiple values of 'B' nominated by peer nodes and 'reflected' by a node.<\/i> <\/p>\n<p>Candidate nominations may lead to the emergence of several confirmable candidates. Therefore, SCP requires the application layer to provide some method of merging candidates into one <i>composite<\/i> (composite). The merging method can be anything. The key is that if this method is deterministic, then each node will merge the same candidates. In a lunch voting system, 'merging' might simply mean dropping one of two candidates. (But deterministically: each node must choose the same value for the drop. For example, an earlier choice in alphabetical order). In the Stellar payment network, where voting on transaction histories occurs, merging two proposed nominees implies combining the transactions they contain and the latest of their two timestamps.<\/p>\n<p>The technical description of SCP proves (Theorem 12) that by the end of the nomination phase, the network ultimately converges to a single composite. But there is a problem: federated voting is an asynchronous protocol (just like SCP). In other words, nodes are not coordinated by time, only by the messages they send. From the perspective of a node, it is unclear when <i>it has completed<\/i> the proposal phase. Although all nodes ultimately arrive at the same composite, they may choose different paths along the way, creating different composite candidates and can never determine which one is final.<\/p>\n<p>But that's fine. The proposal is just preparation. The main goal is to limit the number of candidates to reach a consensus, which occurs during the <i>balloting<\/i> (balloting).<\/p>\n<h1>Balloting<\/h1>\n<p>\nA ballot is a pair , where counter is an integer starting at 1, and value is a candidate from the proposal phase. This can be either the node's own candidate or a candidate from a neighboring node that this node has accepted. Essentially, in balloting, multiple attempts are made to get the network to reach consensus on some candidate in a particular ballot by potentially conducting many federated votes on ballot statements. The counters in the ballots track the attempts made, and ballots with higher counters take precedence over those with lower counters. If ballot  gets stuck, new voting begins, this time on ballot .<\/p>\n<p>It's important to distinguish <i>values<\/i> (for example, what the lunch order should be: pizza or salad), <i>ballots<\/i> (the counter-value pair) and <i>statements<\/i> about ballots. An SCP round includes several rounds of federated voting, particularly on statements like:<\/p>\n<ul>\n<li>\"I am ready to commit ballot B\" and\n<\/li>\n<li>\"I declare the commit of ballot B\"<\/li>\n<\/ul>\n<p>\nFrom this node's perspective, consensus is reached when it finds ballot B for which it can confirm (i.e., find a quorum accepting) the statement \"I declare the commit of ballot B.\" From this point, it can safely act on the value specified in B \u2014 for example, place this lunch order. This is called <i>externalization<\/i> of the value. Once the acceptance of the ballot is confirmed, the node can be assured that any other node has either externalized the same value or will certainly do so in the future.<\/p>\n<p>Although conceptually many federated votes are conducted on statements about many different ballots, they exchange not such a large number of messages because each message encapsulates a number of ballots. One message thus promotes the state of many federated votes at once, for example: 'I accept the commit of ballots in the range from  to '.<\/p>\n<p>What do the terms 'prepared' and 'commit' mean?<\/p>\n<p>A node votes for the commit of a ballot when it is convinced that other nodes will not make a commit of ballots with other values. The belief in this is the goal of preparing a statement. Voting that says: 'I am ready to commit ballot B' is a promise to never commit a ballot smaller than B, i.e., with a lower counter (SCP requires that values in ballots have a specific order. Thus, ballot  is less than  if N1&lt;N2, and also if N1=N2 and V1&lt;V2). These smaller ballots are &#039;aborted&#039; during the preparation voting, while B is considered &#039;prepared&#039;.<\/p>\n<p>Why does 'I am ready to commit ballot B' mean 'I promise never to allow a commit of ballots less than B'? Because SCP defines abort as the opposite of commit. Voting to prepare a ballot also implies voting to abort some other ballots, and as we discussed earlier, voting for one thing is a promise to never vote against it.<\/p>\n<p>Before broadcasting a commit, a node must first find a ballot that it can confirm as prepared. In other words, it conducts a federated vote on the topic 'I am ready to commit ballot B', possibly for many different ballots, until it finds one that accepts the quorum.<\/p>\n<p>Where do the ballots for the voting preparation come from? Initially, the node broadcasts the preparation for voting for , where C is the composite candidate produced during the nomination stage. However, even after voting preparation begins, nominations can lead to new candidates emerging, which will become new ballots. Meanwhile, peers may have different candidates, and they can form a blocking set that accepts 'I am ready to commit ballot B2', convincing the node to accept it as well. Finally, there's a timeout mechanism that generates new rounds of federated voting on new ballots with higher counters if current ballots are stuck.<\/p>\n<p>Once the node finds ballot B, which can be confirmed as prepared, it broadcasts a new message 'Commit ballot B'. This vote tells the peers that the node will never abandon B. In fact, if B represents the ballot , then 'Commit ballot ' means unconditional agreement to vote for the readiness of each ballot from  to . This additional value helps other nodes catch up with the peer with the commit if they are still on earlier stages of the protocol.<\/p>\n<p>At this stage, it is worth emphasizing that these are asynchronous protocols. Just because one node sends votes for the commit does not mean that its peers are doing the same. Some of them may still be voting on statements for voting preparation, while others may have already externalized the value. SCP explains how a node should handle each type of peer-to-peer message regardless of its phase.<\/p>\n<p>If the message \"I announce commit \" cannot be accepted or confirmed, there is a chance of accepting or confirming the message  or  \u2014 or, in any case, any bulletin with the value C, and not any other, since the node has already promised never to cancel . By the time the node broadcasts votes for the commit, it will be C or nothing, depending on how far the consensus goes. However, this is still not enough for the node to externalize C. Some Byzantine pirates (making up less than a quorum, based on our security assumptions) may lie to the node. Accepting, and then confirming some bulletin (or range of bulletins) is what gives the node the confidence to finally externalize C.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding the Stellar Consensus Protocol\" src=\"\/wp-content\/uploads\/2019\/03\/c59f036bb8aa189bb3d4540f54121391.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Voting SCP through federated voting. Not shown: at any moment, a timer can trigger, increasing the count in the bulletin (and potentially producing a new composite from additional nominated candidates).<\/i> <\/p>\n<p>And that's it! Once the network reaches consensus, it's ready to do it again and again. In the Stellar payment network, this happens approximately every 5 seconds: a feat that requires both security and resilience, guaranteed by SCP.<\/p>\n<p>SCP can achieve this by relying on several rounds of federated voting. Federated voting became possible due to the concept of quorum slices: sets of peer nodes that each node has chosen to trust as part of its (subjective) quorum. This configuration means that consensus can be reached even in a network with open membership and Byzantine fraud.<\/p>\n<h1>Further reading<\/h1>\n<p><\/p>\n<ul>\n<li>The original technical document on SCP can be found <noindex><a rel=\"nofollow\" href=\"https:\/\/www.stellar.org\/papers\/stellar-consensus-protocol.pdf\">here<\/a><\/noindex>, and <noindex><a rel=\"nofollow\" href=\"https:\/\/datatracker.ietf.org\/doc\/draft-mazieres-dinrg-scp\/\">here<\/a><\/noindex> specification draft for its implementation.\n<\/li>\n<li>The original author of the SCP protocol, David Mazieres, explains it simplistically (but still technically) <noindex><a rel=\"nofollow\" href=\"http:\/\/www.scs.stanford.edu\/~dm\/blog\/simplified-scp.html\">here<\/a><\/noindex>.\n<\/li>\n<li>You may have been surprised not to find the terms \"mining\" or \"proof of work\" in this article. SCP does not use these methods, but some other consensus algorithms do. Zane Weiserpoon wrote an accessible <noindex><a rel=\"nofollow\" href=\"https:\/\/hackernoon.com\/a-hitchhikers-guide-to-consensus-algorithms-d81aae3eb0e3\">overview of consensus algorithms<\/a><\/noindex>.\n<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/bobg\/scp\/blob\/master\/Lunch.md\">Step-by-step description of<\/a><\/noindex> a simple network reaching consensus in one complete round of SCP.\n<\/li>\n<li>For readers interested in SCP implementations: see <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/stellar\/stellar-core\/tree\/master\/src\/scp\">C++ code<\/a><\/noindex>, used by the Stellar payment network, or <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/bobg\/scp\">Go code<\/a><\/noindex>, which I wrote for a better understanding of SCP.<\/li>\n<\/ul>\n<p>Source: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/444710\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043a\u043e\u043d\u0441\u0435\u043d\u0441\u0443\u0441\u0430 Stellar \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u043e\u043f\u0438\u0441\u0430\u043d \u0432 \u043d\u0430\u0443\u0447\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0414\u044d\u0432\u0438\u0434\u0430 \u041c\u0430\u0437\u044c\u0435\u0440\u0430 \u0432 2015 \u0433\u043e\u0434\u0443. \u042d\u0442\u043e \u00ab\u0444\u0435\u0434\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0432\u0438\u0437\u0430\u043d\u0442\u0438\u0439\u0441\u043a\u043e\u0433\u043e \u0441\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u044f\u00bb, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0441\u0435\u0442\u044f\u043c \u0431\u0435\u0437 \u043b\u0438\u0434\u0435\u0440\u043e\u0432 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u0435\u043d\u0441\u0443\u0441\u0430 \u043f\u043e \u043a\u0430\u043a\u043e\u043c\u0443-\u043b\u0438\u0431\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044e. \u041f\u043b\u0430\u0442\u0451\u0436\u043d\u0430\u044f \u0441\u0435\u0442\u044c Stellar \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 Stellar Consensus Protocol (SCP) \u0434\u043b\u044f \u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u0438\u0434\u044f\u0442 \u0432\u0441\u0435 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438. \u0421\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u044b \u043a\u043e\u043d\u0441\u0435\u043d\u0441\u0443\u0441\u0430 \u0442\u0440\u0443\u0434\u043d\u044b \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f. [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-30047","post","type-post","status-publish","format-standard","hentry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043a\u043e\u043d\u0441\u0435\u043d\u0441\u0443\u0441\u0430 Stellar \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u043e\u043f\u0438\u0441\u0430\u043d \u0432.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/en\/blog\/razbiraemsya-v-protokole-konsensusa-stellar\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0432 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0435 \u043a\u043e\u043d\u0441\u0435\u043d\u0441\u0443\u0441\u0430 Stellar | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043a\u043e\u043d\u0441\u0435\u043d\u0441\u0443\u0441\u0430 Stellar \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u043e\u043f\u0438\u0441\u0430\u043d \u0432.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/en\/blog\/razbiraemsya-v-protokole-konsensusa-stellar\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:33:25+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:33:25+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Understanding the Stellar consensus protocol | ProHoster","description":"The Stellar consensus protocol is first described in.","canonical_url":"https:\/\/prohoster.info\/en\/blog\/razbiraemsya-v-protokole-konsensusa-stellar","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0432 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0435 \u043a\u043e\u043d\u0441\u0435\u043d\u0441\u0443\u0441\u0430 Stellar | ProHoster","og:description":"\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043a\u043e\u043d\u0441\u0435\u043d\u0441\u0443\u0441\u0430 Stellar \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u043e\u043f\u0438\u0441\u0430\u043d \u0432.","og:url":"https:\/\/prohoster.info\/en\/blog\/razbiraemsya-v-protokole-konsensusa-stellar","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:33:25+00:00","article:modified_time":"2019-10-31T18:33:25+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"30047","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-20 23:34:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:43:15","updated":"2026-01-20 23:34:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/30047","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/comments?post=30047"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/30047\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media?parent=30047"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/categories?post=30047"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/tags?post=30047"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}